SemlerPDX icon

Minecraft ComputerCraft Reactor Shutdown

SemlerPDX | PRO | 10/22/21 08:51:15 PM UTC (Edited) | 0 ⭐ | 2455 👁️ | Never ⏰ | []
Lua |

6.39 KB

|

None

|

0 👍

/

0 👎

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