--Mekanism Fission Reactor Emergency Shutdown Monitor --v0.91 by SemlerPDX Aug26 2021 --Reactor Control & Monitor Scripts -- Control PC: https://pastebin.com/2VrXwGNH -- and -- Emergency Monitor PC (this script): https://pastebin.com/uxE2jE2B -- and -- Remote Status Monitor PC: https://pastebin.com/59EWW86J -- -- example image of setup: https://imgur.com/a/nrKeBcH --Redstone I/O Sides dmgSide = "top" tempSide = "right" wasteSide = "left" fuelSide = "back" reactorShutdown = "bottom" --Peripheral Side modemSide = "front" --wireless modem side hazardPC = 22 --id of (this) critical shutdown monitor PC remotePC = 21 --id of remote display status monitor PC controlPC = 20 --id of reactor control PC --id of rednet protocols protocol = "PowerSys" --Remote Command Keywords msgConfirmed = "copycopy" faultCleared = "FaultCleared" --Remote Command Receive Timeout (in seconds) timeout = 5 sendCount = 0 --Display Text and Shutdown Reasons shutdownReasons = {"Damage","Heat","Waste","Fuel"} monitorActive = "Monitor is active" emergencyShutdown = "EMERGENCY SHUTDOWN!" standbyShutdown = "Standby Shutdown" faultyStandby = "Fault Standby Mode" --Init modem = peripheral.wrap(modemSide) rednet.open(modemSide) local function fSet() term.clear() y = 1 end local function fWrite(msg) if y >= 19 then fSet() end term.setCursorPos(1,y) term.write(msg) y = y + 1 end --Rednet Recieve Requested Message local function fRcv(msg) id,message = rednet.receive(protocol,timeout) if message ~= nil then if msg == message then return true else return false end end end --Rednet Send with Receipt Confirmation local function fSend(toID,msg,rcv,ccode) rednet.send(toID,msg,protocol) if rcv then returnReceipt = fRcv(ccode) if returnReceipt then return true else return false end end end --MAIN LOOP while true do fSet() fWrite(monitorActive) --Check State and Clear State Functions local function fCheckDamage() while true do sleep(0.05) dmgStable = redstone.getInput(dmgSide) if not dmgStable then redstone.setOutput(reactorShutdown,true) dmgStable = nil return true end end end local function fClearDamage() while true do sleep(5) local dmgStable = redstone.getInput(dmgSide) if dmgStable then dmgStable = nil return true end end end local function fCheckTemperature() while true do sleep(0.05) tempStable = redstone.getInput(tempSide) if not tempStable then redstone.setOutput(reactorShutdown,true) tempStable = nil return true end end end local function fClearTemperature() while true do sleep(5) local tempStable = redstone.getInput(tempSide) if tempStable then tempStable = nil return true end end end local function fCheckWaste() while true do sleep(0.05) wasteStable = redstone.getInput(wasteSide) if not wasteStable then redstone.setOutput(reactorShutdown,true) wasteStable = nil return true end end end local function fClearWaste() while true do sleep(5) local wasteStable = redstone.getInput(wasteSide) if wasteStable then wasteStable = nil return true end end end local function fCheckFuel() while true do sleep(0.05) local fuelLow = redstone.getInput(fuelSide) if fuelLow then redstone.setOutput(reactorShutdown,true) fuelLow = nil return true end end end local function fClearFuel() while true do sleep(5) fuelLow = redstone.getInput(fuelSide) if not fuelLow then fuelLow = nil return true end end end local function fSendFault() sendCount = 0 fSet() fWrite("Sent MSG: '"..shutdownReasons[shutdownReason].."' to PCID: "..controlPC) while true do local messageReceived = fSend(controlPC,shutdownReasons[shutdownReason],true,msgConfirmed) sleep(1) sendCount = sendCount + 1 fWrite("Reason Send Count: "..sendCount) if messageReceived then messageReceived = nil return true end end end local function fClearFault() fWrite("Fault Monitor in Standby...") while true do id,message = rednet.receive(protocol) if message == faultCleared then local checkDmgStable = redstone.getInput(dmgSide) local checkTempStable = redstone.getInput(tempSide) local checkWasteStable = redstone.getInput(wasteSide) local checkFuelLow = redstone.getInput(fuelSide) if checkDmgStable and checkTempStable and checkWasteStable and not checkFuelLow then redstone.setOutput(reactorShutdown,false) sleep(1) rednet.send(id,faultCleared,protocol) return true end end end end local function fCheckReacting() while true do sleep(0.05) reacting = redstone.getInput(reactorShutdown) if not reacting then sleep(5) reacting = nil return true end end end local function fStandby() while true do sleep(5) local reacting = redstone.getInput(reactorShutdown) if reacting then reacting = nil return true end end end shutdownReason = parallel.waitForAny(fCheckDamage,fCheckTemperature,fCheckWaste,fCheckFuel,fCheckReacting) if shutdownReason <= 4 then --send fault shutdown reason to control PC fWrite(emergencyShutdown) faultAcknowledge = parallel.waitForAll(fSendFault,fCheckReacting) --enter fault standby loop fWrite(faultyStandby) faultStandby = parallel.waitForAll(fClearDamage,fClearTemperature,fClearWaste,fClearFuel,fClearFault,fStandby) elseif shutdownReason == 5 then --enter standby loop fWrite(standbyShutdown) monitorStandby = parallel.waitForAll(fClearDamage,fClearTemperature,fClearWaste,fClearFuel,fStandby) end --confirm standby exit and reset for active monitoring fWrite("'Copy' to Control") fSend(controlPC,msgConfirmed) sleep(1) end