Nikola013

SensorServer(E.S.T - 0.01)

Nov 23rd, 2013
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.62 KB | None | 0 0
  1. --this is a work in progress program.
  2. --written by Andrew Phifer
  3. --version: E.S.T - 0.01 (Early Systems Testing)
  4.  
  5. os.unloadAPI("sensors");
  6. os.unloadAPI("sensorsUI");
  7. os.loadAPI("rom/apis/sensors");
  8. os.loadAPI("rom/apis/sensorsUI");
  9.  
  10.  
  11. --reactor[x][1] = Reactor hull heat
  12. --reactor[x][2] = ice quantity
  13. --reactor[x][3] = fuel quantity
  14. --reactor[x][4] = reactor cycle
  15. --reactor[x][5] = the time when the reactor began the current cycle
  16. --reactor[x][6] = reactor life (how long till the next fuel rod will burn out)
  17. --reactor[x][7] = the amount of time the reactor has been running
  18. --reactor[x][8] = the heat level of the hottest item in the reactor
  19. --reactor[x][9] = the heat level of the coldest item in the reactor
  20. --reactor[x][10] = the average heat level of the items in the reactor
  21. --reactor[x][11] = the current EU/t output of the reactor
  22. --reactor[x][12] = the total EU output of the reactor for this cycle
  23. --reactor[x][13] = the X location of the reactor
  24. --reactor[x][14] = the Y location of the reactor
  25. --reactor[x][15] = the Z location of the reactor
  26.  
  27.  
  28. --reactorMap[Xpos][Ypos][xItemDetail]
  29. --reactorMap[Xpos][Ypos][1] = Item Name
  30. --reactorMap[Xpos][Ypos][2] = Item Id
  31. --reactorMap[Xpos][Ypos][3] = Item Damage Value
  32. --reactorMap[Xpos][Ypos][4] = Stack Size
  33.  
  34.  
  35.  
  36. function netSendUpdate (react)
  37. --this function sends a rednet message  
  38. --containing a summary of the specified reactor's state
  39.  
  40. end
  41.  
  42. function netSendReactorMap(react)
  43. --sends a map of the specifed reactor's contents
  44. --and all their item's details
  45.   print("sending reactor map!");
  46.   if react == nil then
  47.     return nil;
  48.   end
  49.   local Items = getReactorContent(react);
  50.   local Readout = getReactorInfo(react);
  51.   local reactorSizeX = getStorageX(Readout);
  52.   local reactorSizeY = getStorageY(Readout);
  53.   local item;
  54.   local stack;
  55.   local name;
  56.   local damage;
  57.   local location;
  58.   local object;
  59.   local u = 0;
  60.   local reactorMapString;
  61.   local reactorMap = {};
  62.   --local monitor = peripheral.wrap("bottom");
  63.   --monitor.clear();
  64.   --monitor.setTextScale(1);
  65.   --monitor.setCursorPos(1,4);
  66.   print("variables initialized!");
  67.   print("reactorX: " .. reactorSizeX);
  68.   print("reactorY: " .. reactorSizeY);  
  69.   print("sending data...");
  70.   os.sleep(2);
  71.   for x = 0, tonumber(reactorSizeX) do
  72.     for y = 0, tonumber(reactorSizeY) do
  73.       location, item = getItemX(x, y, Items); --gets the data for the item (if there is one) at the specifed x y location
  74.       if item ~= nil then
  75.         --if the inventory slot does have something in it, then do this stuff
  76.         stack = getStack(item);
  77.         name = getName(item);
  78.         damage = getDamage(item);
  79.     reactorMap[u] = location;
  80.         reactorMap[u + 1] = stack;
  81.     reactorMap[u + 2] = name;
  82.     reactorMap[u + 3] = damage;
  83.     u = u + 4; --just a counter to advance the position on "reactorMap[]"
  84.     --object = location .. " " .. stack .. " " .. name .. " " .. damage;
  85.       else
  86.     --this section ensures the client never sees a message with 'nil' in it
  87.     --object = "nothing" .. " " .. "nothing" .. " " .. "nothing" .. " " .. "nothing";
  88.     reactorMap[u] = "0,0";
  89.         reactorMap[u + 1] = "nothing";
  90.     reactorMap[u + 2] = "nothing";
  91.     reactorMap[u + 3] = "nothing";
  92.     u = u + 4; --just a counter to advance the position on "reactorMap[]"
  93.       end
  94.       --monitor.write(object);
  95.       --monitor.scroll(-1);
  96.     end
  97.   end
  98.   reactorMapString = textutils.serialize(reactorMap);  
  99.   print("Sucessful Sending?: " .. tostring(rednet.broadcast(reactorMapString)));
  100.   print("end of Map!");
  101. end
  102.  
  103. function getStorageY(Readout)
  104. --this is just a place holder function, right now, it's only being used for reactors.
  105. --that means that it should always return "6"
  106. --in the future however, i might expand this function to be used for regular storage devices
  107. --which do have varible Y values
  108. return "6" --because strings are better, and "6" is all i need right now
  109. end
  110.  
  111. function getStorageX(Readout)
  112. --this function returns the number of inventory slots a certain reactor is wide
  113. --this function requires a Reactor Info Array to be passed to it
  114.   local reactorX = getReactorSize(Readout);
  115.   return reactorX + 3; --because the width of a reactor is 3 + It's size according to the "getReactorSize()" function
  116. end
  117.  
  118. function getReactorSize(Readout)
  119. --returns the size of the specified reactor
  120. --this function requires a Reactor Info Array to be passed to it  
  121.   return Readout[10];
  122. end
  123.  
  124. function getHullHeat(Readout)
  125. --returns the heat level of the reactor hull
  126. --this function requires a Reactor Info Array to be passed to it  
  127.   return Readout[2];
  128. end
  129.  
  130. function getMaxComponentHeat(Items)
  131. --returns the heat level of the hottest
  132. --component in the reactor
  133. --this function requires a Reactor Content Map to be passed to it
  134. end
  135.  
  136. function getLowestComponentHeat(Items)
  137. --returns the heat level of the coldest
  138. --componenet in the reactor
  139. --this function requires a Reactor Content Map to be passed to it
  140. end
  141.  
  142. function getAverageComponentHeat(Items)
  143. --returns the average heat level
  144. --of the components in the reactor
  145. --this function requires a Reactor Content Map to be passed to it
  146. end
  147.  
  148. function getIce(Items)
  149. --returns the amount of ice in the reactor
  150. --this function requires an Reactor Content Map to be passed to it  
  151.   local count = 0;
  152.   for x = 1, table.maxn(Items), 2 do --this moves through all of the items in the reactor, searching for instances of ice.    
  153.     if getName(data[x] + 1) == "" then --need to find out what the actual item code for ice is.
  154.       count = count + 1; --every time the loop finds an instance of Ice in the reactor, it will add one to the counter
  155.     end    
  156.   end
  157.   return count;
  158. end
  159.  
  160. function getFuel(Items)
  161. --returns the amount of urnanium in the reactor
  162. --this function requires a Reactor Content Map to be passed to it  
  163.   local count = 0;
  164.   for x = 1, table.maxn(Items), 2 do --this moves through all of the items in the reactor, searching for instances of uranium.    
  165.     if getName(data[x] + 1, Items) == "" then --need to find out what the actual item code for uranium is.
  166.       count = count + 1; --every time the loop finds an instance of Uranium in the reactor, it will add one to the counter
  167.     end    
  168.   end
  169.   return count;
  170. end
  171.  
  172. function getName(name)
  173. --this pulls the item name from the formatted text provided by ccSensors
  174.   if name ~= nil then -- this is just a preventitive messure, if the function is given a 'nil' argument, then it will automaticly return 'nil'
  175.     local stack = string.find(name, "*"); --the "*" denotes the stack indicator, the stack value precedes it
  176.     local damage = string.find(name, "@"); --the "@" denotes the damge value indicator, the damage value follows it
  177.     if stack == nil then -- IDIOT PROOFING: if there is no stack symbol in the argument passed to the function, it will return 'nil'
  178.       return nil;
  179.     end
  180.     if damage == nil then -- IDIOT PROOFING: if there is no damage symbol in the argument passed to the function, it will return 'nil'
  181.       return nil;
  182.     end
  183.     return string.sub(name, stack + 1, damage - 1); --this line takes the string data that is found between the stack and damage value markers
  184.   end
  185.   return nil;
  186. end
  187.  
  188. function getDamage(name)
  189. --this pulls the item damage value from the formatted text provided by ccSensors
  190.   if name ~= nil then -- this is just a preventitive messure, if the function is given a 'nil' argument, then it will automaticly return 'nil'
  191.     local damage = string.find(name, "@"); --the "@" denotes the damge value indicator, the damage value follows it
  192.     local length = string.len(name); --this gives the string's length
  193.     if damage == nil then -- IDIOT PROOFING: if there is no damage symbol in the argument passed to the function, it will return 'nil'
  194.       return nil;
  195.     end    
  196.     return string.sub(name, damage + 1, length); --this line pulls the damage value and returns it
  197.   end
  198.   return nil;
  199. end
  200.  
  201. function getStack(name)
  202. --this pulls the item stack value from the formatted text provided by ccSensors
  203.   if name ~= nil then -- this is just a preventitive messure, if the function is given a 'nil' argument, then it will automaticly return 'nil'
  204.     local stack = string.find(name, "*"); --the "*" denotes the stack indicator, the stack value precedes it
  205.     if stack == nil then -- IDIOT PROOFING: if there is no stack symbol in the argument passed to the function, it will return 'nil'
  206.       return nil;
  207.     end
  208.     return string.sub(name, 1, stack - 1); --this pulls the items stack value and returns it
  209.   end
  210.   return nil;
  211. end
  212.  
  213. function getCycle(react)
  214. --returns the number of cycles the
  215. --reactor has been running since last
  216. --cool down/ shut down
  217. --this function requires a Reactor Content Map to be passed to it
  218. --THIS FUNCTION WILL HAVE TO DRAW ON MEMORY STORED IN AN ARRAY
  219. --THAT DATA WILL HAVE TO RELY ON SOME OTHER FUNCTION TO GENERATE IT
  220. end
  221.  
  222. function getStart(react)
  223. --returns the amount of time that
  224. --has passed since the reactor was
  225. --last shut down
  226. --THIS FUNCTION WILL HAVE TO DRAW ON MEMORY STORED IN AN ARRAY
  227. --THAT DATA WILL HAVE TO RELY ON SOME OTHER FUNCTION TO GENERATE IT
  228. end
  229.  
  230. function getCycleRemain(react)
  231. --returns the amount of time till
  232. --the next fuel rod will burn out
  233. --this function requires a Reactor Content Map to be passed to it  
  234. end
  235.  
  236. function getItemX(iX, iY, Items)
  237. --returns the info for the item in the specified reactor
  238. --at the specified location
  239. --this function requires an Reactor Content Map to be passed to it
  240. --this function returns two arguments
  241. --this function will return nil as the second arguement if there is nothing in the inventory slot specified
  242.   local coords = tostring(iX) .. "," .. tostring(iY);
  243.   for x = 1, table.maxn(Items), 2 do --this moves through all the items in the reactor, searching for an item that has a coordinate set that matches the one generated from the integer values passed to this function
  244.     if coords == Items[x] then
  245.       return Items[x], Items[x + 1]; --the function will automatically exit once it finds the right item and returns the item name associated with it
  246.     end
  247.   end
  248.   return coords, nil;
  249. end
  250.  
  251. function getReactorLocation(react)
  252.   --returns the x, y, and z coordinates of the specified reactor
  253. end
  254.  
  255. function getPowerOutput(Readout)
  256. --returns the current EU/t output of the
  257. --specified reactor
  258. --this function requires a Reactor Info Array to be passed to it  
  259.   return Readout[4];
  260. end
  261.  
  262. function getTargetInfo(react)
  263.   --returns the data for "Target Info"
  264.   local side = sensors.getController();
  265.   local probes = sensors.getSensors(side);
  266.   local readings = sensors.getAvailableReadings(side, probes[1]);
  267.   local targets = sensors.getAvailableTargetsforProbe(side, probes[1], readings[1]); --targets refers to which type of readings you want to pull, like information about the block, or information about what is inside the block
  268.   local data = sensors.getSensorReadingAsTable(side, probes[1], targets[react], readings[1]) --this is the actual data you want.  it is in the form of a table and the damage value appears to be embedded in the item name, and the x,y coordinates are given as a single string
  269.   return data;
  270. end
  271.  
  272. function getReactorInfo(react)
  273.   --returns the data for "Reactor Info"
  274.   local side = sensors.getController();
  275.   local probes = sensors.getSensors(side);
  276.   local readings = sensors.getAvailableReadings(side, probes[1]);
  277.   local targets = sensors.getAvailableTargetsforProbe(side, probes[1], readings[2]); --targets refers to which type of readings you want to pull, like information about the block, or information about what is inside the block
  278.   local data = sensors.getSensorReadingAsTable(side, probes[1], targets[react], readings[2]) --this is the actual data you want.  it is in the form of a table and the damage value appears to be embedded in the item name, and the x,y coordinates are given as a single string
  279.   return data;
  280. end
  281.  
  282. function getReactorContent(react)
  283.   --returns the data for "Reactor Content"
  284.   local side = sensors.getController();
  285.   local probes = sensors.getSensors(side);
  286.   local readings = sensors.getAvailableReadings(side, probes[1]);
  287.   local targets = sensors.getAvailableTargetsforProbe(side, probes[1], readings[5]); --targets refers to which type of readings you want to pull, like information about the block, or information about what is inside the block
  288.   local data = sensors.getSensorReadingAsTable(side, probes[1], targets[react], readings[5]) --this is the actual data you want.  it is in the form of a table and the damage value appears to be embedded in the item name, and the x,y coordinates are given as a single string
  289.   return data;
  290. end
  291.  
  292. function outputTable(data)
  293.   --takes a table and prints every two items on the same line
  294.   local file = fs.open("ReactorData.txt", "w");
  295.   local message = "";
  296.   local damage;
  297.   local stack;
  298.   local name;
  299.   for x = 1, table.maxn(data), 2 do
  300.     if data[x] ~= nil then
  301.       message = message .. " " .. tostring(data[x]);
  302.     end
  303.     if data[x + 1] ~= nil then
  304.       message = message .. " " .. tostring(getStack(data[x + 1]).. " " .. getName(data[x + 1]) .. " " .. getDamage(data[x + 1]));
  305.     end
  306.     file.writeLine(message);
  307.     message = "";
  308.   end
  309.   file.close();
  310. end
  311.  
  312. function record(i0, i1, i2 ,i3, i4)
  313. --prints out all server activity to the screen
  314.   i0 = textutils.serialize(i0);
  315.   i1 = textutils.serialize(i1);
  316.   i2 = textutils.serialize(i2);
  317.   i3 = textutils.serialize(i3);
  318.   i4 = textutils.serialize(i4);
  319.   local message = "";
  320.   if i0 ~= nil then
  321.     message = message .. " " .. i0;
  322.   else
  323.     message = message .. " " .. "nil";
  324.   end
  325.   if i1 ~= nil then
  326.     message = message .. " " .. i1;
  327.   else
  328.     message = message .. " " .. "nil";
  329.   end
  330.   if i2 ~= nil then
  331.     message = message .. " " .. i2;
  332.   else
  333.     message = message .. " " .. "nil";
  334.   end
  335.   if i3 ~= nil then
  336.     message = message .. " " .. i3;
  337.   else
  338.     message = message .. " " .. "nil";
  339.   end
  340.   if i4 ~= nil then
  341.     message = message .. " " .. i4;
  342.   else
  343.     message = message .. " " .. "nil";
  344.   end
  345.   print(message);
  346. end
  347.  
  348. function rednetMessageSplitter(message)
  349. --this function takes a rednet message, in the form of a string, and looks to see if it has
  350. --more than item it by looking for ","
  351. --it returns all the found parameters as an array
  352.   local length;
  353.   local first;
  354.   local newParameters = {};
  355.   local x = 0;
  356.   repeat
  357.     length = string.len(message); --find the length of message
  358.     first = string.find(message, ","); --find the first instance of a ","
  359.     if first ~= nil then --if there is actually an instance of a "," then continue
  360.       x = x + 1;
  361.       newParameters[x] = string.sub(message, 1, first - 1); --this will take everything in front of the "," and place it into "newParameter"
  362.       message = string.sub(message, first + 1, length); --this will create a new version of "message" that includes all of the original, accept for what is now in "newParameter"
  363.     end
  364.   until first == nil --just exit the loop if there is nothing else to do
  365.   newParameters[x + 1] = message;
  366.   return newParameters;
  367. end
  368.  
  369.  
  370. --notes:
  371. --i really REEEEEALLLLY don't like how "rednetMessageSplitter()" is implemented in the main method.
  372. --it is incredibly ugly, and in elegent and makes the that section way more difficult to read and modify!
  373. --it should be rewritten immediately!!!!
  374. --should be replaced with the "textutils.unserialize()" command!!!!
  375.  
  376. --begin program
  377. reactors = 9; --how many reactors are there to monitor
  378.  
  379.  
  380. --main method
  381. repeat
  382.   rednet.open("back");
  383.   local event, param1, param2, param3, param4 = os.pullEvent("rednet_message");
  384.   --rednet.close("back");
  385.   if event == "rednet_message" then
  386.     local param2x = rednetMessageSplitter(param2);
  387.     if param2x[1] == "sendReactorMap" then
  388.       netSendReactorMap(tonumber(param2x[2]));
  389.     elseif param2x[1] == "sendReactorUpdate" then
  390.       netSendUpdate(tonumber(param2x[2]));
  391.     elseif param2x[1] == "systemShutDown" then
  392.       os.shutdown();
  393.     elseif param2x[1] == "systemReboot" then
  394.       os.reboot();
  395.     elseif param2x[1] == "sensorReboot" then
  396.       os.reboot();
  397.     elseif param2x[1] == "sensorShutDown" then
  398.       os.shutdown();
  399.     elseif param2x[1] == "updateMonitorOn" then
  400.       peripheral.call("bottom", "clear");      
  401.       --this is a command that tells the sensor server
  402.       --to place sensor information on the directly attached
  403.       --monitor
  404.     elseif param2x[1] == "updateMonitorOff" then
  405.       peripheral.call("bottom", "clear");
  406.       --this is a command that tells the sensor server
  407.       --to not place sensor information on the directly
  408.       --attached monitor
  409.     end
  410.   end
  411.   record(event, param1, param2, param3, param4);
  412. until 1 == 0
Advertisement
Add Comment
Please, Sign In to add comment