#181 independent emergency coolant valve control

This commit is contained in:
Mikayla Fischler 2023-04-07 08:05:14 -04:00
parent c2132ea7eb
commit ccc0aa18ff
4 changed files with 66 additions and 4 deletions

View File

@ -5,6 +5,10 @@ config.NETWORKED = true
-- unique reactor ID
config.REACTOR_ID = 1
-- for offline mode, this redstone interface will turn off (open a valve)
-- when emergency coolant is needed due to low coolant
config.EMERGENCY_COOL = { side = "right", color = nil }
-- port to send packets TO server
config.SERVER_PORT = 16000
-- port to listen to incoming packets FROM server

View File

@ -2,6 +2,7 @@ local comms = require("scada-common.comms")
local const = require("scada-common.constants")
local log = require("scada-common.log")
local ppm = require("scada-common.ppm")
local rsio = require("scada-common.rsio")
local types = require("scada-common.types")
local util = require("scada-common.util")
@ -34,7 +35,8 @@ local PCALL_START_MSG = "pcall: Reactor is already active."
---@nodiscard
---@param reactor table
---@param is_formed boolean
function plc.rps_init(reactor, is_formed)
---@param emer_cool nil|table emergency coolant configuration
function plc.rps_init(reactor, is_formed, emer_cool)
local state_keys = {
high_dmg = 1,
high_temp = 2,
@ -54,6 +56,7 @@ function plc.rps_init(reactor, is_formed)
state = { false, false, false, false, false, false, false, false, false, false, false, false },
reactor_enabled = false,
enabled_at = 0,
emer_cool_active = nil, ---@type boolean
formed = is_formed,
force_disabled = false,
tripped = false,
@ -74,6 +77,41 @@ function plc.rps_init(reactor, is_formed)
self.state[state_keys.fault] = false
end
-- set emergency coolant control (if configured)
---@param state boolean true to enable emergency coolant, false to disable
local function _set_emer_cool(state)
-- check if this was configured: if it's a table, fields have already been validated.
if type(emer_cool) == "table" then
local level = rsio.digital_write_active(rsio.IO.U_EMER_COOL, state)
if level ~= false then
if rsio.is_color(emer_cool.color) then
local output = rs.getBundledOutput(emer_cool.side)
if rsio.digital_write(level) then
output = colors.combine(output, emer_cool.color)
else
output = colors.subtract(output, emer_cool.color)
end
rs.setBundledOutput(emer_cool.side, output)
else
rs.setOutput(emer_cool.side, rsio.digital_write(level))
end
if state ~= self.emer_cool_active then
if state then
log.info("RPS: emergency coolant valve OPENED")
else
log.info("RPS: emergency coolant valve CLOSED")
end
self.emer_cool_active = state
end
end
end
end
-- check if the reactor is formed
local function _is_formed()
local formed = reactor.isFormed()
@ -348,6 +386,9 @@ function plc.rps_init(reactor, is_formed)
end
end
-- update emergency coolant control if configured
_set_emer_cool(self.state[state_keys.low_coolant])
return self.tripped, status, first_trip
end
@ -358,6 +399,8 @@ function plc.rps_init(reactor, is_formed)
function public.is_tripped() return self.tripped end
---@nodiscard
function public.get_trip_cause() return self.trip_cause end
---@nodiscard
function public.is_low_coolant() return self.states[state_keys.low_coolant] end
---@nodiscard
function public.is_active() return self.reactor_enabled end

View File

@ -8,13 +8,14 @@ local crash = require("scada-common.crash")
local log = require("scada-common.log")
local mqueue = require("scada-common.mqueue")
local ppm = require("scada-common.ppm")
local rsio = require("scada-common.rsio")
local util = require("scada-common.util")
local config = require("reactor-plc.config")
local plc = require("reactor-plc.plc")
local threads = require("reactor-plc.threads")
local R_PLC_VERSION = "v1.0.0"
local R_PLC_VERSION = "v1.0.1"
local print = util.print
local println = util.println
@ -39,6 +40,15 @@ cfv.assert_type_int(config.LOG_MODE)
assert(cfv.valid(), "bad config file: missing/invalid fields")
-- check emergency coolant configuration
if type(config.EMERGENCY_COOL) == "table" then
if not rsio.is_valid_side(config.EMERGENCY_COOL.side) then
assert(false, "bad config file: emergency coolant side unrecognized")
elseif config.EMERGENCY_COOL.color ~= nil and not rsio.is_color(config.EMERGENCY_COOL.color) then
assert(false, "bad config file: emergency coolant invalid redstone channel color provided")
end
end
----------------------------------------
-- log init
----------------------------------------
@ -155,7 +165,7 @@ local function main()
end
-- init reactor protection system
smem_sys.rps = plc.rps_init(smem_dev.reactor, plc_state.reactor_formed)
smem_sys.rps = plc.rps_init(smem_dev.reactor, plc_state.reactor_formed, config.EMERGENCY_COOL)
log.debug("init> rps init")
if __shared_memory.networked then
@ -172,6 +182,12 @@ local function main()
log.info("init> running without networking")
end
-- notify user of emergency coolant configuration status
if config.EMERGENCY_COOL ~= nil then
println("init> emergency coolant control ready")
log.info("init> running with emergency coolant control available")
end
util.push_event("clock_start")
println("init> completed")

View File

@ -314,7 +314,6 @@ function threads.thread__rps(smem)
rps.trip_timeout()
end
else
-- would do elseif not networked but there is no reason to do that extra operation
was_linked = true
end