#51 PLC changes for new networking

This commit is contained in:
Mikayla Fischler 2023-06-23 13:52:24 -04:00
parent da3c92b3bf
commit ffac6996ed
3 changed files with 39 additions and 49 deletions

View File

@ -445,14 +445,14 @@ end
---@nodiscard
---@param id integer reactor ID
---@param version string PLC version
---@param modem table modem device
---@param nic nic network interface device
---@param plc_channel integer PLC comms channel
---@param svr_channel integer supervisor server channel
---@param range integer trusted device connection range
---@param reactor table reactor device
---@param rps rps RPS reference
---@param conn_watchdog watchdog watchdog reference
function plc.comms(id, version, modem, plc_channel, svr_channel, range, reactor, rps, conn_watchdog)
function plc.comms(id, version, nic, plc_channel, svr_channel, range, reactor, rps, conn_watchdog)
local self = {
sv_addr = comms.BROADCAST,
seq_num = 0,
@ -470,13 +470,9 @@ function plc.comms(id, version, modem, plc_channel, svr_channel, range, reactor,
-- PRIVATE FUNCTIONS --
-- configure modem channels
local function _conf_channels()
modem.closeAll()
modem.open(plc_channel)
end
_conf_channels()
-- configure network channels
nic.closeAll()
nic.open(plc_channel)
-- send an RPLC packet
---@param msg_type RPLC_TYPE
@ -488,7 +484,7 @@ function plc.comms(id, version, modem, plc_channel, svr_channel, range, reactor,
r_pkt.make(id, msg_type, msg)
s_pkt.make(self.sv_addr, self.seq_num, PROTOCOL.RPLC, r_pkt.raw_sendable())
modem.transmit(svr_channel, plc_channel, s_pkt.raw_sendable())
nic.transmit(svr_channel, plc_channel, s_pkt)
self.seq_num = self.seq_num + 1
end
@ -502,7 +498,7 @@ function plc.comms(id, version, modem, plc_channel, svr_channel, range, reactor,
m_pkt.make(msg_type, msg)
s_pkt.make(self.sv_addr, self.seq_num, PROTOCOL.SCADA_MGMT, m_pkt.raw_sendable())
modem.transmit(svr_channel, plc_channel, s_pkt.raw_sendable())
nic.transmit(svr_channel, plc_channel, s_pkt)
self.seq_num = self.seq_num + 1
end
@ -650,13 +646,6 @@ function plc.comms(id, version, modem, plc_channel, svr_channel, range, reactor,
---@class plc_comms
local public = {}
-- reconnect a newly connected modem
---@param new_modem table
function public.reconnect_modem(new_modem)
modem = new_modem
_conf_channels()
end
-- reconnect a newly connected reactor
---@param new_reactor table
function public.reconnect_reactor(new_reactor)
@ -744,12 +733,9 @@ function plc.comms(id, version, modem, plc_channel, svr_channel, range, reactor,
---@return rplc_frame|mgmt_frame|nil packet
function public.parse_packet(side, sender, reply_to, message, distance)
local pkt = nil
local s_pkt = comms.scada_packet()
local s_pkt = nic.receive(side, sender, reply_to, message, distance)
-- parse packet as generic SCADA packet
s_pkt.receive(side, sender, reply_to, message, distance)
if s_pkt.is_valid() then
if s_pkt and s_pkt.is_valid() then
-- get as RPLC packet
if s_pkt.protocol() == PROTOCOL.RPLC then
local rplc_pkt = comms.rplc_packet()

View File

@ -8,6 +8,7 @@ local comms = require("scada-common.comms")
local crash = require("scada-common.crash")
local log = require("scada-common.log")
local mqueue = require("scada-common.mqueue")
local network = require("scada-common.network")
local ppm = require("scada-common.ppm")
local rsio = require("scada-common.rsio")
local util = require("scada-common.util")
@ -18,7 +19,7 @@ local plc = require("reactor-plc.plc")
local renderer = require("reactor-plc.renderer")
local threads = require("reactor-plc.threads")
local R_PLC_VERSION = "v1.4.7"
local R_PLC_VERSION = "v1.5.0"
local println = util.println
local println_ts = util.println_ts
@ -88,13 +89,13 @@ local function main()
-- PLC system state flags
---@class plc_state
plc_state = {
init_ok = true,
fp_ok = false,
shutdown = false,
degraded = false,
init_ok = true,
fp_ok = false,
shutdown = false,
degraded = true,
reactor_formed = true,
no_reactor = false,
no_modem = false
no_reactor = true,
no_modem = true
},
-- control setpoints
@ -113,6 +114,7 @@ local function main()
-- system objects
plc_sys = {
rps = nil, ---@type rps
nic = nil, ---@type nic
plc_comms = nil, ---@type plc_comms
conn_watchdog = nil ---@type watchdog
},
@ -130,14 +132,17 @@ local function main()
local plc_state = __shared_memory.plc_state
-- initial state evaluation
plc_state.no_reactor = smem_dev.reactor == nil
plc_state.no_modem = smem_dev.modem == nil
-- we need a reactor, can at least do some things even if it isn't formed though
if smem_dev.reactor == nil then
if plc_state.no_reactor then
println("init> fission reactor not found");
log.warning("init> no reactor on startup")
plc_state.init_ok = false
plc_state.degraded = true
plc_state.no_reactor = true
elseif not smem_dev.reactor.isFormed() then
println("init> fission reactor not formed");
log.warning("init> reactor logic adapter present, but reactor is not formed")
@ -147,7 +152,7 @@ local function main()
end
-- modem is required if networked
if __shared_memory.networked and smem_dev.modem == nil then
if __shared_memory.networked and plc_state.no_modem then
println("init> wireless modem not found")
log.warning("init> no wireless modem on startup")
@ -158,7 +163,6 @@ local function main()
plc_state.init_ok = false
plc_state.degraded = true
plc_state.no_modem = true
end
-- print a log message to the terminal as long as the UI isn't running
@ -196,8 +200,9 @@ local function main()
smem_sys.conn_watchdog = util.new_watchdog(config.COMMS_TIMEOUT)
log.debug("init> conn watchdog started")
-- start comms
smem_sys.plc_comms = plc.comms(config.REACTOR_ID, R_PLC_VERSION, smem_dev.modem, config.PLC_CHANNEL, config.SVR_CHANNEL,
-- init network interface then start comms
smem_sys.nic = network.nic(smem_dev.modem)
smem_sys.plc_comms = plc.comms(config.REACTOR_ID, R_PLC_VERSION, smem_sys.nic, config.PLC_CHANNEL, config.SVR_CHANNEL,
config.TRUSTED_RANGE, smem_dev.reactor, smem_sys.rps, smem_sys.conn_watchdog)
log.debug("init> comms init")
else

View File

@ -59,6 +59,7 @@ function threads.thread__main(smem, init)
while true do
-- get plc_sys fields (may have been set late due to degraded boot)
local rps = smem.plc_sys.rps
local nic = smem.plc_sys.nic
local plc_comms = smem.plc_sys.plc_comms
local conn_watchdog = smem.plc_sys.conn_watchdog
@ -66,6 +67,7 @@ function threads.thread__main(smem, init)
-- handle event
if event == "timer" and loop_clock.is_clock(param1) then
-- note: loop clock is only running if init_ok = true
-- blink heartbeat indicator
databus.heartbeat()
@ -75,7 +77,7 @@ function threads.thread__main(smem, init)
loop_clock.start()
-- send updated data
if not plc_state.no_modem then
if not nic.connected() then
if plc_comms.is_linked() then
smem.q.mq_comms_tx.push_command(MQ__COMM_CMD.SEND_STATUS)
else
@ -114,7 +116,7 @@ function threads.thread__main(smem, init)
smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM)
-- determine if we are still in a degraded state
if not networked or not plc_state.no_modem then
if (not networked) or nic.connected() then
plc_state.degraded = false
end
@ -144,7 +146,7 @@ function threads.thread__main(smem, init)
-- update indicators
databus.tx_hw_status(plc_state)
elseif event == "modem_message" and networked and plc_state.init_ok and not plc_state.no_modem then
elseif event == "modem_message" and networked and plc_state.init_ok and nic.connected() then
-- got a packet
local packet = plc_comms.parse_packet(param1, param2, param3, param4, param5)
if packet ~= nil then
@ -171,7 +173,9 @@ function threads.thread__main(smem, init)
plc_state.degraded = true
elseif networked and type == "modem" then
-- we only care if this is our wireless modem
if device == plc_dev.modem then
if nic.is_modem(device) then
nic.disconnect()
println_ts("comms modem disconnected!")
log.error("comms modem disconnected")
@ -199,12 +203,11 @@ function threads.thread__main(smem, init)
if type == "fissionReactorLogicAdapter" then
-- reconnected reactor
plc_dev.reactor = device
plc_state.no_reactor = false
println_ts("reactor reconnected.")
log.info("reactor reconnected")
plc_state.no_reactor = false
-- we need to assume formed here as we cannot check in this main loop
-- RPS will identify if it isn't and this will get set false later
plc_state.reactor_formed = true
@ -230,14 +233,12 @@ function threads.thread__main(smem, init)
if device.isWireless() then
-- reconnected modem
plc_dev.modem = device
plc_state.no_modem = false
if plc_state.init_ok then
plc_comms.reconnect_modem(plc_dev.modem)
end
if plc_state.init_ok then nic.connect(device) 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 not plc_state.no_reactor then
@ -709,9 +710,7 @@ function threads.thread__setpoint_control(smem)
end
-- if ramping completed or was aborted, reset last burn setpoint so that if it is requested again it will be re-attempted
if not setpoints.burn_rate_en then
last_burn_sp = 0
end
if not setpoints.burn_rate_en then last_burn_sp = 0 end
end
-- check for termination request