Guest User

SensorServer(early systems testing)

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