--Mekanism Fission Reactor Control w/Remote Emergency Monitor --v0.92 by SemlerPDX Aug21-26 2021 --Reactor Control & Monitor Scripts -- Control PC (this script): https://pastebin.com/2VrXwGNH -- and -- Emergency Monitor PC: 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 battery = "left" reactor = "right" monitoring = "top" --Peripheral Sides monitorSide = "bottom" modemSide = "back" --Battery Monitor Redstone Min/Max Levels (0-15) minBank = 7 maxBank = 15 --id of rednet protocols protocol = "PowerSys" protocolCMD = "PowerCMD" controlPC = 20 --id of (this) reactor control PC remotePC = 21 --id of remote display status monitor PC hazardPC = 22 --id of critical shutdown monitor PC --Remote Command Keywords msgConfirmed = "copycopy" msgDenied = "samestate" faultClear = "FaultCleared" clearFaults = "ClearFault" commandClear = "enable" commandON = "on" commandOFF = "off" --Remote Command Receive Timeout (in seconds) timeout = 5 --Array of Redstone (0-15) into % of 100 for Text Display batteryLevels = {7,13,20,27,33,40,47,53,60,67,73,80,87,93,100} --Init y = 1 online = false reacting = false shutdownReason = "unknown" redstone.setOutput(reactor,false) redstone.setOutput(monitoring,false) monitor = peripheral.wrap(monitorSide) modem = peripheral.wrap(modemSide) rednet.open(modemSide) --Remote Reactor Status Monitor Send Function local function fStatusUpdate(msg) rednet.send(remotePC,msg,protocol) end --Refresh/Clear Display(s) Function local function fSet(remoteClear) y = 1 term.clear() monitor.clear() term.setCursorPos(1,1) monitor.setCursorPos(1,1) if remoteClear then fStatusUpdate("clear") end end --Direct Monitor Screen Write Function local function fDisplay(txt) monitor.write(txt) monitor.setCursorPos(1,y) end --Combined Term/Monitor/Remote Write Function local function fWrite(msg,display,send) y = y + 1 term.write(msg) term.setCursorPos(1,y) if display then fDisplay(msg) end if send then fStatusUpdate(msg) end end --Change Redstone Input (0-15) into Percentage for Text Display local function fBankStatus(cellLevel) bankCapacity = "Bank Capacity < 7%" if cellLevel == 1 then bankCapacity = "Bank Capacity > "..batteryLevels[cellLevel].."%" elseif cellLevel >= 2 and cellLevel <= 14 then bankCapacity = "Bank Capacity >"..batteryLevels[cellLevel].."%" else bankCapacity = "Bank Capacity 100%" end return bankCapacity end --Acknowledge Emergency Shutdown Fault and Get Reason from Monitoring PC local function fAcknowledge() shutdownReason = "unknown" id,reason = rednet.receive(protocol) rednet.send(id,msgConfirmed,protocol) if reason ~= nil then shutdownReason = reason end end --MAIN LOOP while true do --Emergency Shutdown Monitor Function local function fShutdown() local criticalShutdown = redstone.getInput(monitoring) while true do sleep(0.05) criticalShutdown = redstone.getInput(monitoring) if criticalShutdown then redstone.setOutput(reactor,false) criticalShutdown = nil return true end end end --Master Online State & Battery Monitor Function local function fBatteryMonitor() while true do sleep(5) fSet(true) currBank = redstone.getAnalogInput(battery) reacting = redstone.getOutput(reactor) currStatus = fBankStatus(currBank) fWrite(currStatus,true,true) if currBank == maxBank and reacting then fWrite("Bank at capacity",true,true) fWrite("Shutting down...",true,true) redstone.setOutput(monitoring,false) redstone.setOutput(reactor,false) sleep(10) elseif currBank <= minBank and not reacting and online then fWrite("Bank below min",true,true) fWrite("Enabling reaction",true,true) redstone.setOutput(monitoring,true) sleep(5) redstone.setOutput(reactor,true) elseif currBank >= minBank and not reacting and online then fWrite("Bank at capacity",true,true) fWrite("Reactor in standby",true,true) elseif reacting and not online then fWrite("Command Offline",true,true) fWrite("Shutting down...",true,true) redstone.setOutput(monitoring,false) redstone.setOutput(reactor,false) sleep(10) elseif not reacting and not online then fWrite("Systems Offline",true,true) fWrite("Reactor in standby",true,true) else fWrite("Systems Online",true,true) if reacting then fWrite("Reactor operating",true,true) else fWrite("Reactor in standby",true,true) end end monitor.setCursorPos(1,5) if online then fDisplay(" -Tap to Disable- ") fStatusUpdate(commandON) else fDisplay(" -Tap to Enable- ") fStatusUpdate(commandOFF) end end end --Touchscreen Systems Online Toggle local function fTouch() while true do sleep(3) event,side,xPos,yPos = os.pullEvent("monitor_touch") if not online then online = true elseif online then online = false end end end --Rednet Systems Online Toggle local function fListen() while true do id,message = rednet.receive(protocolCMD) rednet.send(id,msgConfirmed,protocolCMD) id,message = rednet.receive(protocolCMD,timeout) if message ~= nil then if message == commandON and not online then online = true rednet.send(id,msgConfirmed,protocolCMD) elseif message == commandOFF and online then online = false rednet.send(id,msgConfirmed,protocolCMD) else rednet.send(id,msgDenied,protocolCMD) end end end end --Emergency Shutdown Fault Acknowledgment local function fClearFault() while true do sleep(5) local faultsActive = redstone.getInput(monitoring) if not faultsActive then faultsActive = nil return true end end end --Fault Clear Terminal Input Confirmation Function local function fConfirmCleared() while true do fSet(true) currBank = redstone.getAnalogInput(battery) currStatus = fBankStatus(currBank) fWrite(currStatus,true,true) fWrite("Critical "..shutdownReason.."!",true,true) fWrite("EMERGENCY SHUTDOWN",true,true) fWrite("Clear faults, then type 'enable' and press Enter") term.write("> ") local confirmCleared = read() fSet() if confirmCleared == commandClear then fWrite("Confirming Cleared") rednet.send(hazardPC,faultClear,protocol) id,message = rednet.receive(protocol,15) if message == faultCleared then sleep(5) end faultsActive = redstone.getInput(monitoring) fSet() if not faultsActive then fWrite("Clear Confirmed") fWrite("Zero Faults Detected") fWrite("Enabling Operations") return true else fWrite("Clear Disregarded") fWrite("Reactor Faults Detected!") fWrite("Cannot Enable Operations!") end else fWrite("Invalid Command...") fWrite("Reactor Faults Detected!") fWrite("Clear faults and enter 'enable'") end sleep(4) end end --MAIN Reactor Function monitoring battery, cmd input, and shutdown signal reactorFunction = parallel.waitForAny(fShutdown,fBatteryMonitor,fTouch,fListen) --Emergency Shutdown, output to screens/rednet if reactorFunction == 1 then redstone.setOutput(monitoring,false) fAcknowledge() --Force Terminal Input that faults cleared faultAcknowledged = parallel.waitForAll(fClearFault,fConfirmCleared) end end