--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
Comments