From a93f0a4452cf796be3172cabd46480dc1d65b131 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 22 May 2022 17:57:24 -0400 Subject: [PATCH] #57 updates per safety pass, fixed plc_sys fields staying nil on degraded start, fixed repeated SCRAM messages when unlinked --- reactor-plc/plc.lua | 2 +- reactor-plc/startup.lua | 2 +- reactor-plc/threads.lua | 54 +++++++++++++++++++++++------------------ scada-common/log.lua | 6 +++++ scada-common/ppm.lua | 8 +++--- scada-common/util.lua | 6 +++-- 6 files changed, 47 insertions(+), 31 deletions(-) diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index db04467..b5d36b5 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -155,7 +155,7 @@ plc.rps_init = function (reactor) -- trip for a PLC comms timeout public.trip_timeout = function () - self.state[state_keys.timed_out] = true + self.state[state_keys.timeout] = true end -- manually SCRAM the reactor diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index c401961..8a2d296 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -13,7 +13,7 @@ local config = require("reactor-plc.config") local plc = require("reactor-plc.plc") 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 println = util.println diff --git a/reactor-plc/threads.lua b/reactor-plc/threads.lua index 561f72c..f28c775 100644 --- a/reactor-plc/threads.lua +++ b/reactor-plc/threads.lua @@ -47,12 +47,14 @@ threads.thread__main = function (smem, init) local networked = smem.networked local plc_state = smem.plc_state 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 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 local event, param1, param2, param3, param4, param5 = os.pullEventRaw() @@ -77,14 +79,14 @@ threads.thread__main = function (smem, init) 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 local packet = plc_comms.parse_packet(param1, param2, param3, param4, param5) if packet ~= nil then -- pass the packet onto the comms message queue smem.q.mq_comms_rx.push_packet(packet) 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 plc_comms.unlink() 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) println_ts("reactor reconnected.") - log.info("reactor reconnected.") + log.info("reactor reconnected") plc_state.no_reactor = false if plc_state.init_ok then @@ -139,7 +141,7 @@ threads.thread__main = function (smem, init) end -- 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 end elseif networked and type == "modem" then @@ -152,19 +154,20 @@ threads.thread__main = function (smem, init) end println_ts("wireless modem reconnected.") - log.info("comms modem reconnected.") + log.info("comms modem reconnected") plc_state.no_modem = false -- 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 end else - log.info("wired modem reconnected.") + log.info("wired modem reconnected") 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 plc_state.init_ok = true init() @@ -223,8 +226,6 @@ threads.thread__rps = function (smem) local networked = smem.networked local plc_state = smem.plc_state 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 @@ -233,13 +234,16 @@ threads.thread__rps = function (smem) -- thread loop 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 if plc_state.init_ok then -- SCRAM if no open connection if networked and not plc_comms.is_linked() then - rps.scram() if was_linked then was_linked = false rps.trip_timeout() @@ -264,7 +268,7 @@ threads.thread__rps = function (smem) if not plc_state.no_reactor then 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) if networked and not plc_state.no_modem then 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 public.p_exec = function () local plc_state = smem.plc_state - local rps = smem.plc_sys.rps while not plc_state.shutdown do local status, result = pcall(public.exec) @@ -339,7 +342,7 @@ threads.thread__rps = function (smem) end 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...") util.psleep(5) end @@ -360,19 +363,20 @@ threads.thread__comms_tx = function (smem) -- load in from shared memory local plc_state = smem.plc_state - local plc_comms = smem.plc_sys.plc_comms - local comms_queue = smem.q.mq_comms_tx local last_update = util.time() -- thread loop 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 while comms_queue.ready() and not plc_state.shutdown do 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 -- received a command if msg.message == MQ__COMM_CMD.SEND_STATUS then @@ -434,7 +438,6 @@ threads.thread__comms_rx = function (smem) -- load in from shared memory local plc_state = smem.plc_state local setpoints = smem.setpoints - local plc_comms = smem.plc_sys.plc_comms local comms_queue = smem.q.mq_comms_rx @@ -442,11 +445,14 @@ threads.thread__comms_rx = function (smem) -- thread loop 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 while comms_queue.ready() and not plc_state.shutdown do 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 -- received a command elseif msg.qtype == mqueue.TYPE.DATA then @@ -507,7 +513,6 @@ threads.thread__setpoint_control = function (smem) local plc_state = smem.plc_state local setpoints = smem.setpoints local plc_dev = smem.plc_dev - local rps = smem.plc_sys.rps local last_update = util.time() local running = false @@ -520,6 +525,9 @@ threads.thread__setpoint_control = function (smem) -- thread loop 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 if plc_state.init_ok and not plc_state.no_reactor then diff --git a/scada-common/log.lua b/scada-common/log.lua index 3ea4262..d8d245b 100644 --- a/scada-common/log.lua +++ b/scada-common/log.lua @@ -137,6 +137,7 @@ end ---@param msg string message ---@param show_term? boolean whether or not to show on terminal output log.dmesg = function (msg, show_term) + if msg == nil then return end local message = string.format("[%10.3f] ", os.clock()) .. msg if show_term then _write(message) end _log(message) @@ -146,6 +147,7 @@ end ---@param msg string message ---@param trace? boolean include file trace log.debug = function (msg, trace) + if msg == nil then return end if LOG_DEBUG then local dbg_info = "" @@ -167,12 +169,14 @@ end -- log info messages ---@param msg string message log.info = function (msg) + if msg == nil then return end _log("[INF] " .. msg) end -- log warning messages ---@param msg string message log.warning = function (msg) + if msg == nil then return end _log("[WRN] " .. msg) end @@ -180,6 +184,7 @@ end ---@param msg string message ---@param trace? boolean include file trace log.error = function (msg, trace) + if msg == nil then return end local dbg_info = "" if trace then @@ -199,6 +204,7 @@ end -- log fatal errors ---@param msg string message log.fatal = function (msg) + if msg == nil then return end _log("[FTL] " .. msg) end diff --git a/scada-common/ppm.lua b/scada-common/ppm.lua index fd84503..d07e703 100644 --- a/scada-common/ppm.lua +++ b/scada-common/ppm.lua @@ -189,12 +189,12 @@ ppm.mount = function (iface) for i = 1, #ifaces do if iface == ifaces[i] then - log.info("PPM: mount(" .. iface .. ") -> found a " .. peripheral.getType(iface)) - _ppm_sys.mounts[iface] = peri_init(iface) pm_type = _ppm_sys.mounts[iface].type pm_dev = _ppm_sys.mounts[iface].dev + + log.info("PPM: mount(" .. iface .. ") -> found a " .. pm_type) break end end @@ -262,7 +262,7 @@ end ppm.get_all_devices = function (name) local devices = {} - for side, data in pairs(_ppm_sys.mounts) do + for _, data in pairs(_ppm_sys.mounts) do if data.type == name then table.insert(devices, data.dev) end @@ -300,7 +300,7 @@ end ppm.get_wireless_modem = function () 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 w_modem = device.dev break diff --git a/scada-common/util.lua b/scada-common/util.lua index 9e7a4a7..34c10ee 100644 --- a/scada-common/util.lua +++ b/scada-common/util.lua @@ -19,11 +19,13 @@ end -- timestamped print util.print_ts = function (message) + if message == nil then return end term.write(os.date("[%H:%M:%S] ") .. message) end -- timestamped print line util.println_ts = function (message) + if message == nil then return end print(os.date("[%H:%M:%S] ") .. message) end @@ -37,10 +39,10 @@ util.time_ms = function () end -- current time ----@return integer seconds +---@return number seconds util.time_s = function () ---@diagnostic disable-next-line: undefined-field - return os.epoch('local') / 1000 + return os.epoch('local') / 1000.0 end -- current time