Meeschter

rmon

May 8th, 2013
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. os.loadAPI("ocs/apis/sensor")
  2. rs.setOutput("top", false)
  3. rednet.open("right")
  4. local util = dofile("util")
  5. local sensor = sensor.wrap("left")
  6. local targets = sensor.getTargets()
  7. local reactorTarget = nil
  8. config = dofile("reactor.config")
  9. term.clear()
  10. term.setCursorPos(1,1)
  11. io.write("Looking for the reactor...")
  12. for name, target in pairs(targets) do
  13.  target2 = sensor.getTargetDetails(name)   
  14. if target2.Name == "Nuclear Reactor" then
  15.         io.write("FOUND")
  16.         print()
  17.         reactorTarget = name
  18.         break
  19.     end
  20. end
  21.  
  22. local totalEnergyStored = 0
  23. local totalEnergyCapacity = 0
  24. local coolingSystemId = nil
  25. local storageSystemId = nil
  26. local statsSystemId = nil
  27. local cobblestoneSystemId = nil
  28. local coolingStatus = "Unknown"
  29. local reactorData = nil
  30. local systemRunning = false
  31. local totalRuntime = 0
  32. local lastOutputAmount = 0
  33. local startTime = 0
  34.  
  35. local storageBanks = {}
  36.  
  37. local function sendStatus()
  38.     local statusMessage = textutils.serialize{type="reactor", sender="monitor", command="status", status = systemRunning and "ONLINE" or "OFFLINE"}
  39.     if coolingSystemId then rednet.send(coolingSystemId, statusMessage) end
  40.     if cobblestoneSystemId then rednet.send(cobblestoneSystemId, statusMessage) end
  41. end
  42.  
  43. local function startSystem()
  44.     if not systemRunning and (coolingStatus == "ONLINE") and ((totalEnergyCapacity - totalEnergyStored) > config.energyBuffer) then
  45.         rs.setOutput("top", true)
  46.         systemRunning = true
  47.         sendStatus()
  48.     end
  49. end
  50.  
  51. local function stopSystem()
  52.     if systemRunning then
  53.         rs.setOutput("top", false)
  54.         systemRunning = false
  55.         sendStatus()
  56.     end
  57. end
  58.  
  59. local function calculateEnergyTotals()
  60.     local energyStored = 0
  61.     local energyCapacity = 0
  62.     for bankId,energyTotals in pairs(storageBanks) do
  63.         energyStored = energyStored + energyTotals.stored
  64.         energyCapacity = energyCapacity + energyTotals.capacity
  65.     end
  66.     totalEnergyStored = energyStored
  67.     totalEnergyCapacity = energyCapacity
  68.     if (totalEnergyCapacity - totalEnergyStored) < config.energyBuffer then
  69.         stopSystem()
  70.     else
  71.         startSystem()
  72.     end
  73.  
  74. end
  75.  
  76. local function handleCobblestoneSystem(senderId, message)
  77.     if message.command == "announce" then
  78.         cobblestoneSystemId = senderId
  79.         rednet.send(storageSystemId, textutils.serialize{type="reactor", sender="monitor", command="ack"})
  80.         sendStatus()
  81.     elseif message.command == "ack" then
  82.         cobblestoneSystemId = senderId
  83.         sendStatus()
  84.     end
  85. end
  86.  
  87. local function handleCoolingSystem(senderId, message)
  88.     if message.command == "announce" then
  89.         coolingSystemId = senderId
  90.         rednet.send(coolingSystemId, textutils.serialize{type="reactor", sender="monitor", command="ack"})
  91.         sendStatus()
  92.     elseif message.command == "start" then
  93.         startSystem()      
  94.     elseif message.command == "stop" then
  95.         stopSystem()
  96.     elseif message.command == "status" then    
  97.         coolingStatus = message.status
  98.     elseif message.command == "ack" then
  99.         coolingSystemId = senderId
  100.         sendStatus()
  101.     end
  102. end
  103.  
  104. local function handleStorageSystem(senderId, message)
  105.     if message.command == "announce" then
  106.         storageSystemId = senderId
  107.         rednet.send(storageSystemId, textutils.serialize{type="reactor", sender="monitor", command="ack", id = message.id})
  108.     elseif message.command == "ack" then
  109.         storageSystemId = senderId
  110.     elseif message.command == "capacity" then      
  111.         storageBanks[message.id] = { stored = message.stored, capacity = message.capacity }
  112.         calculateEnergyTotals()
  113.     end
  114. end
  115.  
  116. local function handleStatsSystem(senderId, message)
  117.     if message.command == "announce" then
  118.         statsSystemId = senderId
  119.         rednet.send(storageSystemId, textutils.serialize{type="reactor", sender="monitor", command="ack"})
  120.     elseif message.command == "ack" then
  121.         statsSystemId = senderId
  122.     end
  123. end
  124.  
  125. local function doNetwork()
  126.     print("Starting network...")
  127.     rednet.broadcast(textutils.serialize{type="reactor", sender="monitor", command="announce"})
  128.     while true do
  129.         local event, senderId, data, distance = os.pullEvent("rednet_message")
  130.         local message = textutils.unserialize(data)    
  131.         if  message and message.type == "reactor" then
  132.             if message.sender == "cooling" then
  133.                 handleCoolingSystem(senderId, message)
  134.             elseif message.sender == "storage" then
  135.                 handleStorageSystem(senderId, message)
  136.             elseif message.sender == "cobblestone" then
  137.                 handleCobblestoneSystem(senderId, message)
  138.             elseif message.sender == "stats" then
  139.                 handleStatsSystem(senderId, message)
  140.             elseif message.sender == "controller" then
  141.                 -- handleControlSystem(senderId, message)
  142.             end
  143.         end    
  144.     end
  145.     print("network coro exiting")
  146. end
  147.  
  148. local function doKeyboard()
  149.     print("Starting keyboard handler...")
  150.     while true do
  151.         local event, key = os.pullEvent("char")
  152.         if string.lower(key) == "q" then
  153.             break
  154.         end
  155.     end
  156.     print("keyboard coro exiting")
  157. end
  158.  
  159. local function doMenu()
  160.     print("Displaying menu...")
  161.     while true do
  162.         sleep(1)
  163.         if reactorData then
  164.             term.clear()
  165.             term.setCursorPos(1,1)
  166.             local runTime = 0
  167.             if startTime >  0 then
  168.                 runTime = totalRuntime + (os.clock() - startTime)
  169.             else
  170.                 runTime = totalRuntime
  171.             end
  172.             local totalOutput = 0
  173.             if reactorData.Output > 0 then lastOutputAmount = reactorData.Output end
  174.             if runTime > 0 then totalOutput = util.round((lastOutputAmount * runTime * 20) / 1000000, 2) end
  175.             print(string.format("System Status:     %s", reactorData.Active and "ONLINE" or "OFFLINE"))
  176.             print(string.format("System Runtime:    %ss", util.commavalue(runTime)))
  177.             print(string.format("Current Output:    %s", util.commavalue(reactorData.Output)))
  178.             print(string.format("Total Output:      %sM", util.commavalue(totalOutput)))
  179.             print(string.format("Heat:              %s", util.commavalue(reactorData.Heat)))
  180.             print(string.format("Max Heat:          %s", util.commavalue(reactorData.MaxHeat)))
  181.             print(string.format("Cooling System:    %s", coolingStatus))
  182.             print(string.format("Energy Stored:\n     %s/%s", util.commavalue(totalEnergyStored), util.commavalue(totalEnergyCapacity)))
  183.             if statsSystemId then
  184.                 stats = { status = reactorData.Active, runTime = runTime, output = reactorData.Output, totalOutput = (lastOutputAmount * runTime * 20), heat = reactorData.Heat, maxHeat  = reactorData.MaxHeat }
  185.                 rednet.send(statsSystemId, textutils.serialize{type="reactor", sender="monitor", command="stats", stats = stats})
  186.             end
  187.             print("Press Q to exit")
  188.         end
  189.     end
  190.     print("menu coro exiting")
  191. end
  192.  
  193. local function fastSleep()
  194.     sleep(.5)
  195. end
  196.  
  197. local function monitorReactor()
  198.     print("Starting Reactor Monitor...")   
  199.     while true do
  200.         reactorData = sensor.getTargetDetails(reactorTarget)
  201.         if not reactorData or reactorData.Heat > 0 then
  202.             rs.setOutput("top", false)
  203.             print("We have heat or reactorData is nil! Aborting to prevent meltdown.")
  204.             break
  205.         end
  206.         if reactorData.Output > 0 and startTime == 0 then
  207.             startTime = os.clock()
  208.         elseif reactorData.Output == 0 and startTime > 0 then
  209.             totalRuntime = totalRuntime + (os.clock() - startTime)
  210.             startTime = 0;
  211.         end
  212.         fastSleep()
  213.     end
  214.     print("monitor coro exiting")
  215. end
  216.  
  217. local function startup()
  218.     if reactorTarget then
  219.         parallel.waitForAny(monitorReactor, doNetwork, doKeyboard, doMenu)
  220.     else
  221.         error("no reactor found")
  222.     end
  223. end
  224.  
  225. local rtn, error = pcall(startup)
  226. if not rtn then
  227.     print("Reactor failed: " .. error)
  228. end
  229. print("Forcing reactor OFFLINE.")
  230. print("Exiting.")
  231. stopSystem()
Advertisement
Add Comment
Please, Sign In to add comment