#57 updates per safety pass, fixed plc_sys fields staying nil on degraded start, fixed repeated SCRAM messages when unlinked

This commit is contained in:
Mikayla Fischler 2022-05-22 17:57:24 -04:00
parent 26c6010ce0
commit a93f0a4452
6 changed files with 47 additions and 31 deletions

View File

@ -155,7 +155,7 @@ plc.rps_init = function (reactor)
-- trip for a PLC comms timeout -- trip for a PLC comms timeout
public.trip_timeout = function () public.trip_timeout = function ()
self.state[state_keys.timed_out] = true self.state[state_keys.timeout] = true
end end
-- manually SCRAM the reactor -- manually SCRAM the reactor

View File

@ -13,7 +13,7 @@ local config = require("reactor-plc.config")
local plc = require("reactor-plc.plc") local plc = require("reactor-plc.plc")
local threads = require("reactor-plc.threads") local threads = require("reactor-plc.threads")
local R_PLC_VERSION = "alpha-v0.7.0" local R_PLC_VERSION = "alpha-v0.7.1"
local print = util.print local print = util.print
local println = util.println local println = util.println

View File

@ -47,12 +47,14 @@ threads.thread__main = function (smem, init)
local networked = smem.networked local networked = smem.networked
local plc_state = smem.plc_state local plc_state = smem.plc_state
local plc_dev = smem.plc_dev local plc_dev = smem.plc_dev
local rps = smem.plc_sys.rps
local plc_comms = smem.plc_sys.plc_comms
local conn_watchdog = smem.plc_sys.conn_watchdog
-- event loop -- event loop
while true do while true do
-- get plc_sys fields (may have been set late due to degraded boot)
local rps = smem.plc_sys.rps
local plc_comms = smem.plc_sys.plc_comms
local conn_watchdog = smem.plc_sys.conn_watchdog
---@diagnostic disable-next-line: undefined-field ---@diagnostic disable-next-line: undefined-field
local event, param1, param2, param3, param4, param5 = os.pullEventRaw() local event, param1, param2, param3, param4, param5 = os.pullEventRaw()
@ -77,14 +79,14 @@ threads.thread__main = function (smem, init)
end end
end end
end end
elseif event == "modem_message" and networked and not plc_state.no_modem then elseif event == "modem_message" and networked and plc_state.init_ok and not plc_state.no_modem then
-- got a packet -- got a packet
local packet = plc_comms.parse_packet(param1, param2, param3, param4, param5) local packet = plc_comms.parse_packet(param1, param2, param3, param4, param5)
if packet ~= nil then if packet ~= nil then
-- pass the packet onto the comms message queue -- pass the packet onto the comms message queue
smem.q.mq_comms_rx.push_packet(packet) smem.q.mq_comms_rx.push_packet(packet)
end end
elseif event == "timer" and networked and conn_watchdog.is_timer(param1) then elseif event == "timer" and networked and plc_state.init_ok and conn_watchdog.is_timer(param1) then
-- haven't heard from server recently? shutdown reactor -- haven't heard from server recently? shutdown reactor
plc_comms.unlink() plc_comms.unlink()
smem.q.mq_rps.push_command(MQ__RPS_CMD.TRIP_TIMEOUT) smem.q.mq_rps.push_command(MQ__RPS_CMD.TRIP_TIMEOUT)
@ -128,7 +130,7 @@ threads.thread__main = function (smem, init)
smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM) smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM)
println_ts("reactor reconnected.") println_ts("reactor reconnected.")
log.info("reactor reconnected.") log.info("reactor reconnected")
plc_state.no_reactor = false plc_state.no_reactor = false
if plc_state.init_ok then if plc_state.init_ok then
@ -139,7 +141,7 @@ threads.thread__main = function (smem, init)
end end
-- determine if we are still in a degraded state -- determine if we are still in a degraded state
if not networked or ppm.get_device("modem") ~= nil then if not networked or not plc_state.no_modem then
plc_state.degraded = false plc_state.degraded = false
end end
elseif networked and type == "modem" then elseif networked and type == "modem" then
@ -152,19 +154,20 @@ threads.thread__main = function (smem, init)
end end
println_ts("wireless modem reconnected.") println_ts("wireless modem reconnected.")
log.info("comms modem reconnected.") log.info("comms modem reconnected")
plc_state.no_modem = false plc_state.no_modem = false
-- determine if we are still in a degraded state -- determine if we are still in a degraded state
if ppm.get_device("fissionReactor") ~= nil then if not plc_state.no_reactor then
plc_state.degraded = false plc_state.degraded = false
end end
else else
log.info("wired modem reconnected.") log.info("wired modem reconnected")
end end
end end
end end
-- if not init'd and no longer degraded, proceed to init
if not plc_state.init_ok and not plc_state.degraded then if not plc_state.init_ok and not plc_state.degraded then
plc_state.init_ok = true plc_state.init_ok = true
init() init()
@ -223,8 +226,6 @@ threads.thread__rps = function (smem)
local networked = smem.networked local networked = smem.networked
local plc_state = smem.plc_state local plc_state = smem.plc_state
local plc_dev = smem.plc_dev local plc_dev = smem.plc_dev
local rps = smem.plc_sys.rps
local plc_comms = smem.plc_sys.plc_comms
local rps_queue = smem.q.mq_rps local rps_queue = smem.q.mq_rps
@ -233,13 +234,16 @@ threads.thread__rps = function (smem)
-- thread loop -- thread loop
while true do while true do
local reactor = plc_dev.reactor -- get plc_sys fields (may have been set late due to degraded boot)
local rps = smem.plc_sys.rps
local plc_comms = smem.plc_sys.plc_comms
-- get reactor, may have changed do to disconnect/reconnect
local reactor = plc_dev.reactor
-- RPS checks -- RPS checks
if plc_state.init_ok then if plc_state.init_ok then
-- SCRAM if no open connection -- SCRAM if no open connection
if networked and not plc_comms.is_linked() then if networked and not plc_comms.is_linked() then
rps.scram()
if was_linked then if was_linked then
was_linked = false was_linked = false
rps.trip_timeout() rps.trip_timeout()
@ -264,7 +268,7 @@ threads.thread__rps = function (smem)
if not plc_state.no_reactor then if not plc_state.no_reactor then
local rps_tripped, rps_status_string, rps_first = rps.check() local rps_tripped, rps_status_string, rps_first = rps.check()
if rps_first then if rps_tripped and rps_first then
println_ts("[RPS] SCRAM! safety trip: " .. rps_status_string) println_ts("[RPS] SCRAM! safety trip: " .. rps_status_string)
if networked and not plc_state.no_modem then if networked and not plc_state.no_modem then
plc_comms.send_rps_alarm(rps_status_string) plc_comms.send_rps_alarm(rps_status_string)
@ -330,7 +334,6 @@ threads.thread__rps = function (smem)
-- execute the thread in a protected mode, retrying it on return if not shutting down -- execute the thread in a protected mode, retrying it on return if not shutting down
public.p_exec = function () public.p_exec = function ()
local plc_state = smem.plc_state local plc_state = smem.plc_state
local rps = smem.plc_sys.rps
while not plc_state.shutdown do while not plc_state.shutdown do
local status, result = pcall(public.exec) local status, result = pcall(public.exec)
@ -339,7 +342,7 @@ threads.thread__rps = function (smem)
end end
if not plc_state.shutdown then if not plc_state.shutdown then
if plc_state.init_ok then rps.scram() end if plc_state.init_ok then smem.plc_sys.rps.scram() end
log.info("rps thread restarting in 5 seconds...") log.info("rps thread restarting in 5 seconds...")
util.psleep(5) util.psleep(5)
end end
@ -360,19 +363,20 @@ threads.thread__comms_tx = function (smem)
-- load in from shared memory -- load in from shared memory
local plc_state = smem.plc_state local plc_state = smem.plc_state
local plc_comms = smem.plc_sys.plc_comms
local comms_queue = smem.q.mq_comms_tx local comms_queue = smem.q.mq_comms_tx
local last_update = util.time() local last_update = util.time()
-- thread loop -- thread loop
while true do while true do
-- get plc_sys fields (may have been set late due to degraded boot)
local plc_comms = smem.plc_sys.plc_comms
-- check for messages in the message queue -- check for messages in the message queue
while comms_queue.ready() and not plc_state.shutdown do while comms_queue.ready() and not plc_state.shutdown do
local msg = comms_queue.pop() local msg = comms_queue.pop()
if msg ~= nil then if msg ~= nil and plc_state.init_ok then
if msg.qtype == mqueue.TYPE.COMMAND then if msg.qtype == mqueue.TYPE.COMMAND then
-- received a command -- received a command
if msg.message == MQ__COMM_CMD.SEND_STATUS then if msg.message == MQ__COMM_CMD.SEND_STATUS then
@ -434,7 +438,6 @@ threads.thread__comms_rx = function (smem)
-- load in from shared memory -- load in from shared memory
local plc_state = smem.plc_state local plc_state = smem.plc_state
local setpoints = smem.setpoints local setpoints = smem.setpoints
local plc_comms = smem.plc_sys.plc_comms
local comms_queue = smem.q.mq_comms_rx local comms_queue = smem.q.mq_comms_rx
@ -442,11 +445,14 @@ threads.thread__comms_rx = function (smem)
-- thread loop -- thread loop
while true do while true do
-- get plc_sys fields (may have been set late due to degraded boot)
local plc_comms = smem.plc_sys.plc_comms
-- check for messages in the message queue -- check for messages in the message queue
while comms_queue.ready() and not plc_state.shutdown do while comms_queue.ready() and not plc_state.shutdown do
local msg = comms_queue.pop() local msg = comms_queue.pop()
if msg ~= nil then if msg ~= nil and plc_state.init_ok then
if msg.qtype == mqueue.TYPE.COMMAND then if msg.qtype == mqueue.TYPE.COMMAND then
-- received a command -- received a command
elseif msg.qtype == mqueue.TYPE.DATA then elseif msg.qtype == mqueue.TYPE.DATA then
@ -507,7 +513,6 @@ threads.thread__setpoint_control = function (smem)
local plc_state = smem.plc_state local plc_state = smem.plc_state
local setpoints = smem.setpoints local setpoints = smem.setpoints
local plc_dev = smem.plc_dev local plc_dev = smem.plc_dev
local rps = smem.plc_sys.rps
local last_update = util.time() local last_update = util.time()
local running = false local running = false
@ -520,6 +525,9 @@ threads.thread__setpoint_control = function (smem)
-- thread loop -- thread loop
while true do while true do
-- get plc_sys fields (may have been set late due to degraded boot)
local rps = smem.plc_sys.rps
-- get reactor, may have changed do to disconnect/reconnect
local reactor = plc_dev.reactor local reactor = plc_dev.reactor
if plc_state.init_ok and not plc_state.no_reactor then if plc_state.init_ok and not plc_state.no_reactor then

View File

@ -137,6 +137,7 @@ end
---@param msg string message ---@param msg string message
---@param show_term? boolean whether or not to show on terminal output ---@param show_term? boolean whether or not to show on terminal output
log.dmesg = function (msg, show_term) log.dmesg = function (msg, show_term)
if msg == nil then return end
local message = string.format("[%10.3f] ", os.clock()) .. msg local message = string.format("[%10.3f] ", os.clock()) .. msg
if show_term then _write(message) end if show_term then _write(message) end
_log(message) _log(message)
@ -146,6 +147,7 @@ end
---@param msg string message ---@param msg string message
---@param trace? boolean include file trace ---@param trace? boolean include file trace
log.debug = function (msg, trace) log.debug = function (msg, trace)
if msg == nil then return end
if LOG_DEBUG then if LOG_DEBUG then
local dbg_info = "" local dbg_info = ""
@ -167,12 +169,14 @@ end
-- log info messages -- log info messages
---@param msg string message ---@param msg string message
log.info = function (msg) log.info = function (msg)
if msg == nil then return end
_log("[INF] " .. msg) _log("[INF] " .. msg)
end end
-- log warning messages -- log warning messages
---@param msg string message ---@param msg string message
log.warning = function (msg) log.warning = function (msg)
if msg == nil then return end
_log("[WRN] " .. msg) _log("[WRN] " .. msg)
end end
@ -180,6 +184,7 @@ end
---@param msg string message ---@param msg string message
---@param trace? boolean include file trace ---@param trace? boolean include file trace
log.error = function (msg, trace) log.error = function (msg, trace)
if msg == nil then return end
local dbg_info = "" local dbg_info = ""
if trace then if trace then
@ -199,6 +204,7 @@ end
-- log fatal errors -- log fatal errors
---@param msg string message ---@param msg string message
log.fatal = function (msg) log.fatal = function (msg)
if msg == nil then return end
_log("[FTL] " .. msg) _log("[FTL] " .. msg)
end end

View File

@ -189,12 +189,12 @@ ppm.mount = function (iface)
for i = 1, #ifaces do for i = 1, #ifaces do
if iface == ifaces[i] then if iface == ifaces[i] then
log.info("PPM: mount(" .. iface .. ") -> found a " .. peripheral.getType(iface))
_ppm_sys.mounts[iface] = peri_init(iface) _ppm_sys.mounts[iface] = peri_init(iface)
pm_type = _ppm_sys.mounts[iface].type pm_type = _ppm_sys.mounts[iface].type
pm_dev = _ppm_sys.mounts[iface].dev pm_dev = _ppm_sys.mounts[iface].dev
log.info("PPM: mount(" .. iface .. ") -> found a " .. pm_type)
break break
end end
end end
@ -262,7 +262,7 @@ end
ppm.get_all_devices = function (name) ppm.get_all_devices = function (name)
local devices = {} local devices = {}
for side, data in pairs(_ppm_sys.mounts) do for _, data in pairs(_ppm_sys.mounts) do
if data.type == name then if data.type == name then
table.insert(devices, data.dev) table.insert(devices, data.dev)
end end
@ -300,7 +300,7 @@ end
ppm.get_wireless_modem = function () ppm.get_wireless_modem = function ()
local w_modem = nil local w_modem = nil
for side, device in pairs(_ppm_sys.mounts) do for _, device in pairs(_ppm_sys.mounts) do
if device.type == "modem" and device.dev.isWireless() then if device.type == "modem" and device.dev.isWireless() then
w_modem = device.dev w_modem = device.dev
break break

View File

@ -19,11 +19,13 @@ end
-- timestamped print -- timestamped print
util.print_ts = function (message) util.print_ts = function (message)
if message == nil then return end
term.write(os.date("[%H:%M:%S] ") .. message) term.write(os.date("[%H:%M:%S] ") .. message)
end end
-- timestamped print line -- timestamped print line
util.println_ts = function (message) util.println_ts = function (message)
if message == nil then return end
print(os.date("[%H:%M:%S] ") .. message) print(os.date("[%H:%M:%S] ") .. message)
end end
@ -37,10 +39,10 @@ util.time_ms = function ()
end end
-- current time -- current time
---@return integer seconds ---@return number seconds
util.time_s = function () util.time_s = function ()
---@diagnostic disable-next-line: undefined-field ---@diagnostic disable-next-line: undefined-field
return os.epoch('local') / 1000 return os.epoch('local') / 1000.0
end end
-- current time -- current time