diff --git a/reactor-plc/config.lua b/reactor-plc/config.lua index 539946e..25f750c 100644 --- a/reactor-plc/config.lua +++ b/reactor-plc/config.lua @@ -1,3 +1,5 @@ +-- set to false to run in standalone mode (safety regulation only) +NETWORKED = true -- unique reactor ID REACTOR_ID = 1 -- port to send packets TO server diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 65dfe39..dcac721 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -22,6 +22,8 @@ ppm.mount_all() local reactor = ppm.get_device("fissionReactor") local modem = ppm.get_device("modem") +local networked = config.NETWORKED + local plc_state = { init_ok = true, scram = true, -- treated as latching e-stop, all conditions must be OK to set false @@ -38,7 +40,7 @@ if reactor == nil then plc_state.degraded = true plc_state.no_reactor = true end -if modem == nil then +if networked and modem == nil then if reactor ~= nil then print_ts("No modem found. Disabling reactor and running in a degraded state...\n") reactor.scram() @@ -52,37 +54,46 @@ if modem == nil then plc_state.no_modem = true end -::init:: -if plc_state.init_ok then - -- just booting up, no fission allowed (neutrons stay put thanks) - reactor.scram() - - -- init internal safety system - local iss = plc.iss_init(reactor) - log._debug("iss init") - - -- start comms - local plc_comms = plc.comms_init(config.REACTOR_ID, modem, config.LISTEN_PORT, config.SERVER_PORT, reactor, iss) - log._debug("comms init") - - -- comms watchdog, 3 second timeout - local conn_watchdog = watchdog.new_watchdog(3) - log._debug("conn watchdog started") - - -- loop clock (10Hz, 2 ticks) - local loop_tick = os.startTimer(0.05) - log._debug("loop clock started") -else - log._warning("booted in a degraded state, awaiting peripheral connections...") -end +local iss = nil +local plc_comms = nil +local conn_watchdog = nil -- send status updates at ~3.33Hz (every 6 server ticks) (every 3 loop ticks) -- send link requests at 0.5Hz (every 40 server ticks) (every 20 loop ticks) local UPDATE_TICKS = 3 local LINK_TICKS = 20 --- start by linking -local ticks_to_update = LINK_TICKS +local loop_tick = nil +local ticks_to_update = LINK_TICKS -- start by linking + +-- initialize PLC +::init:: +if plc_state.init_ok then + -- just booting up, no fission allowed (neutrons stay put thanks) + reactor.scram() + + -- init internal safety system + iss = plc.iss_init(reactor) + log._debug("iss init") + + if networked then + -- start comms + plc_comms = plc.comms_init(config.REACTOR_ID, modem, config.LISTEN_PORT, config.SERVER_PORT, reactor, iss) + log._debug("comms init") + + -- comms watchdog, 3 second timeout + conn_watchdog = watchdog.new_watchdog(3) + log._debug("conn watchdog started") + else + log._debug("running without networking") + end + + -- loop clock (10Hz, 2 ticks) + loop_tick = os.startTimer(0.05) + log._debug("loop clock started") +else + log._warning("booted in a degraded state, awaiting peripheral connections...") +end -- event loop while true do @@ -93,7 +104,7 @@ while true do -- if it disconnected, isPowered will return nil (and error logs will get spammed at 10Hz, so disable reporting) -- in that case, SCRAM won't be called until it reconnects (this is the expected use of this check) ppm.disable_reporting() - if plc_state.scram and reactor.isPowered() then + if plc_state.degraded or (plc_state.scram and reactor.isPowered()) then reactor.scram() end ppm.enable_reporting() @@ -108,7 +119,7 @@ while true do log._error("reactor disconnected!") plc_state.no_reactor = true -- send an alarm: plc_comms.send_alarm(ALARMS.PLC_PERI_DC) ? - elseif device.type == "modem" then + elseif networked and device.type == "modem" then print_ts("modem disconnected!\n") log._error("modem disconnected!") plc_state.no_modem = true @@ -139,14 +150,16 @@ while true do if plc_state.init_ok then iss.reconnect_reactor(device) - plc_comms.reconnect_reactor(device) + if networked then + plc_comms.reconnect_reactor(device) + end end -- determine if we are still in a degraded state - if get_device("modem") not nil then + if not networked or get_device("modem") not nil then plc_state.degraded = false end - elseif device.type == "modem" then + elseif networked and device.type == "modem" then -- reconnected modem if plc_state.init_ok then plc_comms.reconnect_modem(device) @@ -172,31 +185,29 @@ while true do if not plc_state.degraded then local iss_tripped, iss_status, iss_first = iss.check() plc_state.scram = plc_state.scram or iss_tripped - if iss_first then + if networked and iss_first then plc_comms.send_iss_alarm(iss_status) end end -- handle event - if event == "timer" and param1 == loop_tick then - if not plc_state.no_modem then - -- basic event tick, send updated data if it is time (~3.33Hz) - -- iss was already checked (main reason for this tick rate) - ticks_to_update = ticks_to_update - 1 + if event == "timer" and param1 == loop_tick and networked and not plc_state.no_modem then + -- basic event tick, send updated data if it is time (~3.33Hz) + -- iss was already checked (that's the main reason for this tick rate) + ticks_to_update = ticks_to_update - 1 - if plc_comms.is_linked() then - if ticks_to_update <= 0 then - plc_comms.send_status(iss_tripped) - ticks_to_update = UPDATE_TICKS - end - else - if ticks_to_update <= 0 then - plc_comms.send_link_req() - ticks_to_update = LINK_TICKS - end + if plc_comms.is_linked() then + if ticks_to_update <= 0 then + plc_comms.send_status(iss_tripped) + ticks_to_update = UPDATE_TICKS + end + else + if ticks_to_update <= 0 then + plc_comms.send_link_req() + ticks_to_update = LINK_TICKS end end - elseif event == "modem_message" then + elseif event == "modem_message" and networked and not plc_state.no_modem then -- got a packet -- feed the watchdog first so it doesn't uhh...eat our packets conn_watchdog.feed() @@ -204,7 +215,7 @@ while true do local packet = plc_comms.parse_packet(p1, p2, p3, p4, p5) plc_comms.handle_packet(packet) plc_state.scram = plc_state.scram or plc_comms.is_scrammed() - elseif event == "timer" and param1 == conn_watchdog.get_timer() then + elseif event == "timer" and param1 == conn_watchdog.get_timer() and networked then -- haven't heard from server recently? shutdown reactor plc_state.scram = true plc_comms.unlink()