Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- os.loadAPI("ocs/apis/sensor")
- rs.setOutput("top", false)
- rednet.open("right")
- local util = dofile("util")
- local sensor = sensor.wrap("left")
- local targets = sensor.getTargets()
- local reactorTarget = nil
- config = dofile("reactor.config")
- term.clear()
- term.setCursorPos(1,1)
- io.write("Looking for the reactor...")
- for name, target in pairs(targets) do
- target2 = sensor.getTargetDetails(name)
- if target2.Name == "Nuclear Reactor" then
- io.write("FOUND")
- print()
- reactorTarget = name
- break
- end
- end
- local totalEnergyStored = 0
- local totalEnergyCapacity = 0
- local coolingSystemId = nil
- local storageSystemId = nil
- local statsSystemId = nil
- local cobblestoneSystemId = nil
- local coolingStatus = "Unknown"
- local reactorData = nil
- local systemRunning = false
- local totalRuntime = 0
- local lastOutputAmount = 0
- local startTime = 0
- local storageBanks = {}
- local function sendStatus()
- local statusMessage = textutils.serialize{type="reactor", sender="monitor", command="status", status = systemRunning and "ONLINE" or "OFFLINE"}
- if coolingSystemId then rednet.send(coolingSystemId, statusMessage) end
- if cobblestoneSystemId then rednet.send(cobblestoneSystemId, statusMessage) end
- end
- local function startSystem()
- if not systemRunning and (coolingStatus == "ONLINE") and ((totalEnergyCapacity - totalEnergyStored) > config.energyBuffer) then
- rs.setOutput("top", true)
- systemRunning = true
- sendStatus()
- end
- end
- local function stopSystem()
- if systemRunning then
- rs.setOutput("top", false)
- systemRunning = false
- sendStatus()
- end
- end
- local function calculateEnergyTotals()
- local energyStored = 0
- local energyCapacity = 0
- for bankId,energyTotals in pairs(storageBanks) do
- energyStored = energyStored + energyTotals.stored
- energyCapacity = energyCapacity + energyTotals.capacity
- end
- totalEnergyStored = energyStored
- totalEnergyCapacity = energyCapacity
- if (totalEnergyCapacity - totalEnergyStored) < config.energyBuffer then
- stopSystem()
- else
- startSystem()
- end
- end
- local function handleCobblestoneSystem(senderId, message)
- if message.command == "announce" then
- cobblestoneSystemId = senderId
- rednet.send(storageSystemId, textutils.serialize{type="reactor", sender="monitor", command="ack"})
- sendStatus()
- elseif message.command == "ack" then
- cobblestoneSystemId = senderId
- sendStatus()
- end
- end
- local function handleCoolingSystem(senderId, message)
- if message.command == "announce" then
- coolingSystemId = senderId
- rednet.send(coolingSystemId, textutils.serialize{type="reactor", sender="monitor", command="ack"})
- sendStatus()
- elseif message.command == "start" then
- startSystem()
- elseif message.command == "stop" then
- stopSystem()
- elseif message.command == "status" then
- coolingStatus = message.status
- elseif message.command == "ack" then
- coolingSystemId = senderId
- sendStatus()
- end
- end
- local function handleStorageSystem(senderId, message)
- if message.command == "announce" then
- storageSystemId = senderId
- rednet.send(storageSystemId, textutils.serialize{type="reactor", sender="monitor", command="ack", id = message.id})
- elseif message.command == "ack" then
- storageSystemId = senderId
- elseif message.command == "capacity" then
- storageBanks[message.id] = { stored = message.stored, capacity = message.capacity }
- calculateEnergyTotals()
- end
- end
- local function handleStatsSystem(senderId, message)
- if message.command == "announce" then
- statsSystemId = senderId
- rednet.send(storageSystemId, textutils.serialize{type="reactor", sender="monitor", command="ack"})
- elseif message.command == "ack" then
- statsSystemId = senderId
- end
- end
- local function doNetwork()
- print("Starting network...")
- rednet.broadcast(textutils.serialize{type="reactor", sender="monitor", command="announce"})
- while true do
- local event, senderId, data, distance = os.pullEvent("rednet_message")
- local message = textutils.unserialize(data)
- if message and message.type == "reactor" then
- if message.sender == "cooling" then
- handleCoolingSystem(senderId, message)
- elseif message.sender == "storage" then
- handleStorageSystem(senderId, message)
- elseif message.sender == "cobblestone" then
- handleCobblestoneSystem(senderId, message)
- elseif message.sender == "stats" then
- handleStatsSystem(senderId, message)
- elseif message.sender == "controller" then
- -- handleControlSystem(senderId, message)
- end
- end
- end
- print("network coro exiting")
- end
- local function doKeyboard()
- print("Starting keyboard handler...")
- while true do
- local event, key = os.pullEvent("char")
- if string.lower(key) == "q" then
- break
- end
- end
- print("keyboard coro exiting")
- end
- local function doMenu()
- print("Displaying menu...")
- while true do
- sleep(1)
- if reactorData then
- term.clear()
- term.setCursorPos(1,1)
- local runTime = 0
- if startTime > 0 then
- runTime = totalRuntime + (os.clock() - startTime)
- else
- runTime = totalRuntime
- end
- local totalOutput = 0
- if reactorData.Output > 0 then lastOutputAmount = reactorData.Output end
- if runTime > 0 then totalOutput = util.round((lastOutputAmount * runTime * 20) / 1000000, 2) end
- print(string.format("System Status: %s", reactorData.Active and "ONLINE" or "OFFLINE"))
- print(string.format("System Runtime: %ss", util.commavalue(runTime)))
- print(string.format("Current Output: %s", util.commavalue(reactorData.Output)))
- print(string.format("Total Output: %sM", util.commavalue(totalOutput)))
- print(string.format("Heat: %s", util.commavalue(reactorData.Heat)))
- print(string.format("Max Heat: %s", util.commavalue(reactorData.MaxHeat)))
- print(string.format("Cooling System: %s", coolingStatus))
- print(string.format("Energy Stored:\n %s/%s", util.commavalue(totalEnergyStored), util.commavalue(totalEnergyCapacity)))
- if statsSystemId then
- stats = { status = reactorData.Active, runTime = runTime, output = reactorData.Output, totalOutput = (lastOutputAmount * runTime * 20), heat = reactorData.Heat, maxHeat = reactorData.MaxHeat }
- rednet.send(statsSystemId, textutils.serialize{type="reactor", sender="monitor", command="stats", stats = stats})
- end
- print("Press Q to exit")
- end
- end
- print("menu coro exiting")
- end
- local function fastSleep()
- sleep(.5)
- end
- local function monitorReactor()
- print("Starting Reactor Monitor...")
- while true do
- reactorData = sensor.getTargetDetails(reactorTarget)
- if not reactorData or reactorData.Heat > 0 then
- rs.setOutput("top", false)
- print("We have heat or reactorData is nil! Aborting to prevent meltdown.")
- break
- end
- if reactorData.Output > 0 and startTime == 0 then
- startTime = os.clock()
- elseif reactorData.Output == 0 and startTime > 0 then
- totalRuntime = totalRuntime + (os.clock() - startTime)
- startTime = 0;
- end
- fastSleep()
- end
- print("monitor coro exiting")
- end
- local function startup()
- if reactorTarget then
- parallel.waitForAny(monitorReactor, doNetwork, doKeyboard, doMenu)
- else
- error("no reactor found")
- end
- end
- local rtn, error = pcall(startup)
- if not rtn then
- print("Reactor failed: " .. error)
- end
- print("Forcing reactor OFFLINE.")
- print("Exiting.")
- stopSystem()
Advertisement
Add Comment
Please, Sign In to add comment