Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement