From e3a4ed53631d78603bbcab7d108d8ddcbb648e60 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Tue, 10 May 2022 17:08:38 -0400 Subject: [PATCH] catch nil cases, supervisor use loop clock --- reactor-plc/threads.lua | 110 +++++++++++++++++++++------------------- rtu/threads.lua | 102 +++++++++++++++++++------------------ supervisor/startup.lua | 47 +++++++++-------- 3 files changed, 136 insertions(+), 123 deletions(-) diff --git a/reactor-plc/threads.lua b/reactor-plc/threads.lua index bf05f22..7231f2a 100644 --- a/reactor-plc/threads.lua +++ b/reactor-plc/threads.lua @@ -88,74 +88,78 @@ threads.thread__main = function (smem, init) smem.q.mq_rps.push_command(MQ__RPS_CMD.TRIP_TIMEOUT) elseif event == "peripheral_detach" then -- peripheral disconnect - local device = ppm.handle_unmount(param1) - - if device.type == "fissionReactor" then - println_ts("reactor disconnected!") - log.error("reactor disconnected!") - plc_state.no_reactor = true - plc_state.degraded = true - elseif networked and device.type == "modem" then - -- we only care if this is our wireless modem - if device.dev == plc_dev.modem then - println_ts("wireless modem disconnected!") - log.error("comms modem disconnected!") - plc_state.no_modem = true - - if plc_state.init_ok then - -- try to scram reactor if it is still connected - smem.q.mq_rps.push_command(MQ__RPS_CMD.DEGRADED_SCRAM) - end + local type, device = ppm.handle_unmount(param1) + if type ~= nil and device ~= nil then + if type == "fissionReactor" then + println_ts("reactor disconnected!") + log.error("reactor disconnected!") + plc_state.no_reactor = true plc_state.degraded = true - else - log.warning("non-comms modem disconnected") + elseif networked and type == "modem" then + -- we only care if this is our wireless modem + if device == plc_dev.modem then + println_ts("wireless modem disconnected!") + log.error("comms modem disconnected!") + plc_state.no_modem = true + + if plc_state.init_ok then + -- try to scram reactor if it is still connected + smem.q.mq_rps.push_command(MQ__RPS_CMD.DEGRADED_SCRAM) + end + + plc_state.degraded = true + else + log.warning("non-comms modem disconnected") + end end end elseif event == "peripheral" then -- peripheral connect local type, device = ppm.mount(param1) - if type == "fissionReactor" then - -- reconnected reactor - plc_dev.reactor = device + if type ~= nil and device ~= nil then + if type == "fissionReactor" then + -- reconnected reactor + plc_dev.reactor = device - smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM) + smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM) - println_ts("reactor reconnected.") - log.info("reactor reconnected.") - plc_state.no_reactor = false - - if plc_state.init_ok then - rps.reconnect_reactor(plc_dev.reactor) - if networked then - plc_comms.reconnect_reactor(plc_dev.reactor) - end - end - - -- determine if we are still in a degraded state - if not networked or ppm.get_device("modem") ~= nil then - plc_state.degraded = false - end - elseif networked and type == "modem" then - if device.isWireless() then - -- reconnected modem - plc_dev.modem = device + println_ts("reactor reconnected.") + log.info("reactor reconnected.") + plc_state.no_reactor = false if plc_state.init_ok then - plc_comms.reconnect_modem(plc_dev.modem) + rps.reconnect_reactor(plc_dev.reactor) + if networked then + plc_comms.reconnect_reactor(plc_dev.reactor) + end end - println_ts("wireless 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 networked or ppm.get_device("modem") ~= nil then plc_state.degraded = false end - else - log.info("wired modem reconnected.") + elseif networked and type == "modem" then + if device.isWireless() then + -- reconnected modem + plc_dev.modem = device + + if plc_state.init_ok then + plc_comms.reconnect_modem(plc_dev.modem) + end + + println_ts("wireless 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 + plc_state.degraded = false + end + else + log.info("wired modem reconnected.") + end end end @@ -203,7 +207,7 @@ threads.thread__rps = function (smem) -- thread loop while true do local reactor = plc_dev.reactor - + -- RPS checks if plc_state.init_ok then -- SCRAM if no open connection @@ -240,7 +244,7 @@ threads.thread__rps = function (smem) end end end - + -- check for messages in the message queue while rps_queue.ready() and not plc_state.shutdown do local msg = rps_queue.pop() diff --git a/rtu/threads.lua b/rtu/threads.lua index ef30b45..5799efb 100644 --- a/rtu/threads.lua +++ b/rtu/threads.lua @@ -74,24 +74,26 @@ threads.thread__main = function (smem) rtu_comms.unlink(rtu_state) elseif event == "peripheral_detach" then -- handle loss of a device - local device = ppm.handle_unmount(param1) + local type, device = ppm.handle_unmount(param1) - if device.type == "modem" then - -- we only care if this is our wireless modem - if device.dev == rtu_dev.modem then - println_ts("wireless modem disconnected!") - log.warning("comms modem disconnected!") + if type ~= nil and device ~= nil then + if type == "modem" then + -- we only care if this is our wireless modem + if device == rtu_dev.modem then + println_ts("wireless modem disconnected!") + log.warning("comms modem disconnected!") + else + log.warning("non-comms modem disconnected") + end else - log.warning("non-comms modem disconnected") - end - else - for i = 1, #units do - -- find disconnected device - if units[i].device == device.dev then - -- we are going to let the PPM prevent crashes - -- return fault flags/codes to MODBUS queries - local unit = units[i] - println_ts("lost the " .. unit.type .. " on interface " .. unit.name) + for i = 1, #units do + -- find disconnected device + if units[i].device == device then + -- we are going to let the PPM prevent crashes + -- return fault flags/codes to MODBUS queries + local unit = units[i] + println_ts("lost the " .. unit.type .. " on interface " .. unit.name) + end end end end @@ -99,44 +101,46 @@ threads.thread__main = function (smem) -- peripheral connect local type, device = ppm.mount(param1) - if type == "modem" then - if device.isWireless() then - -- reconnected modem - rtu_dev.modem = device - rtu_comms.reconnect_modem(rtu_dev.modem) + if type ~= nil and device ~= nil then + if type == "modem" then + if device.isWireless() then + -- reconnected modem + rtu_dev.modem = device + rtu_comms.reconnect_modem(rtu_dev.modem) - println_ts("wireless modem reconnected.") - log.info("comms modem reconnected.") + println_ts("wireless modem reconnected.") + log.info("comms modem reconnected.") + else + log.info("wired modem reconnected.") + end else - log.info("wired modem reconnected.") - end - else - -- relink lost peripheral to correct unit entry - for i = 1, #units do - local unit = units[i] + -- relink lost peripheral to correct unit entry + for i = 1, #units do + local unit = units[i] - -- find disconnected device to reconnect - if unit.name == param1 then - -- found, re-link - unit.device = device + -- find disconnected device to reconnect + if unit.name == param1 then + -- found, re-link + unit.device = device - if unit.type == rtu_t.boiler then - unit.rtu = boiler_rtu.new(device) - elseif unit.type == rtu_t.boiler_valve then - unit.rtu = boilerv_rtu.new(device) - elseif unit.type == rtu_t.turbine then - unit.rtu = turbine_rtu.new(device) - elseif unit.type == rtu_t.turbine_valve then - unit.rtu = turbinev_rtu.new(device) - elseif unit.type == rtu_t.energy_machine then - unit.rtu = energymachine_rtu.new(device) - elseif unit.type == rtu_t.induction_matrix then - unit.rtu = imatrix_rtu.new(device) + if unit.type == rtu_t.boiler then + unit.rtu = boiler_rtu.new(device) + elseif unit.type == rtu_t.boiler_valve then + unit.rtu = boilerv_rtu.new(device) + elseif unit.type == rtu_t.turbine then + unit.rtu = turbine_rtu.new(device) + elseif unit.type == rtu_t.turbine_valve then + unit.rtu = turbinev_rtu.new(device) + elseif unit.type == rtu_t.energy_machine then + unit.rtu = energymachine_rtu.new(device) + elseif unit.type == rtu_t.induction_matrix then + unit.rtu = imatrix_rtu.new(device) + end + + unit.modbus_io = modbus.new(unit.rtu) + + println_ts("reconnected the " .. unit.type .. " on interface " .. unit.name) end - - unit.modbus_io = modbus.new(unit.rtu) - - println_ts("reconnected the " .. unit.type .. " on interface " .. unit.name) end end end diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 825e30c..bf0eabc 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -43,41 +43,46 @@ local superv_comms = supervisor.comms(config.NUM_REACTORS, modem, config.SCADA_D -- base loop clock (6.67Hz, 3 ticks) local MAIN_CLOCK = 0.15 -local loop_clock = os.startTimer(MAIN_CLOCK) +local loop_clock = util.new_clock(MAIN_CLOCK) -- event loop while true do +---@diagnostic disable-next-line: undefined-field local event, param1, param2, param3, param4, param5 = os.pullEventRaw() -- handle event if event == "peripheral_detach" then - local device = ppm.handle_unmount(param1) + local type, device = ppm.handle_unmount(param1) - if device.type == "modem" then - -- we only care if this is our wireless modem - if device.dev == modem then - println_ts("wireless modem disconnected!") - log.error("comms modem disconnected!") - else - log.warning("non-comms modem disconnected") + if type ~= nil and device ~= nil then + if type == "modem" then + -- we only care if this is our wireless modem + if device == modem then + println_ts("wireless modem disconnected!") + log.error("comms modem disconnected!") + else + log.warning("non-comms modem disconnected") + end end end elseif event == "peripheral" then local type, device = ppm.mount(param1) - if type == "modem" then - if device.isWireless() then - -- reconnected modem - modem = device - superv_comms.reconnect_modem(modem) + if type ~= nil and device ~= nil then + if type == "modem" then + if device.isWireless() then + -- reconnected modem + modem = device + superv_comms.reconnect_modem(modem) - println_ts("wireless modem reconnected.") - log.info("comms modem reconnected.") - else - log.info("wired modem reconnected.") + println_ts("wireless modem reconnected.") + log.info("comms modem reconnected.") + else + log.info("wired modem reconnected.") + end end end - elseif event == "timer" and param1 == loop_clock then + elseif event == "timer" and loop_clock.is_clock(param1) then -- main loop tick -- iterate sessions @@ -86,9 +91,9 @@ while true do -- free any closed sessions svsessions.free_all_closed() - loop_clock = os.startTimer(MAIN_CLOCK) + loop_clock.start() elseif event == "timer" then - -- another timer event, check watchdogs + -- a non-clock timer event, check watchdogs svsessions.check_all_watchdogs(param1) elseif event == "modem_message" then -- got a packet