#634 work on reactor PLC backplane
This commit is contained in:
parent
5acc6470e3
commit
cddd9f7437
@ -49,6 +49,8 @@ function backplane.init(config, __shared_memory)
|
||||
|
||||
log.info("BKPLN: WIRED PHY_" .. util.trinary(modem, "UP ", "DOWN ") .. _bp.lan_iface)
|
||||
|
||||
plc_state.wd_modem = _bp.wd_nic.is_connected()
|
||||
|
||||
-- set this as active for now
|
||||
_bp.wl_act = false
|
||||
_bp.act_nic = _bp.wd_nic
|
||||
@ -61,6 +63,8 @@ function backplane.init(config, __shared_memory)
|
||||
|
||||
log.info("BKPLN: WIRELESS PHY_" .. util.trinary(modem, "UP ", "DOWN ") .. iface)
|
||||
|
||||
plc_state.wl_modem = _bp.wl_nic.is_connected()
|
||||
|
||||
-- set this as active if connected or if both modems are disconnected and this is preferred
|
||||
if (modem and _bp.wlan_pref) or not (_bp.act_nic and _bp.act_nic.is_connected()) then
|
||||
_bp.wl_act = true
|
||||
@ -68,12 +72,8 @@ function backplane.init(config, __shared_memory)
|
||||
end
|
||||
end
|
||||
|
||||
plc_state.no_modem = not _bp.act_nic.is_connected()
|
||||
|
||||
databus.tx_hw_modem(not plc_state.no_modem)
|
||||
|
||||
-- comms modem is required if networked
|
||||
if plc_state.no_modem then
|
||||
if not (plc_state.wd_modem or plc_state.wl_modem) then
|
||||
println("startup> comms modem not found")
|
||||
log.warning("BKPLN: no comms modem on startup")
|
||||
|
||||
@ -121,61 +121,106 @@ function backplane.active_nic() return _bp.act_nic end
|
||||
---@param device table
|
||||
---@param print_no_fp function
|
||||
function backplane.attach(iface, type, device, print_no_fp)
|
||||
local MQ__RPS_CMD = _bp.smem.q_cmds.MQ__RPS_CMD
|
||||
|
||||
local networked = _bp.smem.networked
|
||||
local state = _bp.smem.plc_state
|
||||
local dev = _bp.smem.plc_dev
|
||||
local sys = _bp.smem.plc_sys
|
||||
|
||||
if state.no_reactor and (type == "fissionReactorLogicAdapter") then
|
||||
-- reconnected reactor
|
||||
dev.reactor = device
|
||||
state.no_reactor = false
|
||||
if type ~= nil and device ~= nil then
|
||||
if state.no_reactor and (type == "fissionReactorLogicAdapter") then
|
||||
-- reconnected reactor
|
||||
dev.reactor = device
|
||||
state.no_reactor = false
|
||||
|
||||
print_no_fp("reactor reconnected")
|
||||
log.info("BKPLN: reactor reconnected")
|
||||
print_no_fp("reactor reconnected")
|
||||
log.info("BKPLN: reactor reconnected")
|
||||
|
||||
-- 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
|
||||
state.reactor_formed = true
|
||||
|
||||
-- determine if we are still in a degraded state
|
||||
if (not networked or not state.no_modem) and state.reactor_formed then
|
||||
state.degraded = false
|
||||
end
|
||||
|
||||
_bp.smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM)
|
||||
|
||||
sys.rps.reconnect_reactor(dev.reactor)
|
||||
if networked then
|
||||
sys.plc_comms.reconnect_reactor(dev.reactor)
|
||||
end
|
||||
|
||||
-- partial reset of RPS, specific to becoming formed/reconnected
|
||||
-- without this, auto control can't resume on chunk load
|
||||
sys.rps.reset_formed()
|
||||
elseif networked and type == "modem" then
|
||||
---@cast device Modem
|
||||
local is_comms_modem = util.trinary(dev.modem_wired, dev.modem_iface == iface, device.isWireless())
|
||||
|
||||
-- note, check init_ok first since nic will be nil if it is false
|
||||
if is_comms_modem and not (state.init_ok and nic.is_connected()) then
|
||||
-- reconnected modem
|
||||
dev.modem = device
|
||||
state.no_modem = false
|
||||
|
||||
if state.init_ok then nic.connect(device) end
|
||||
|
||||
print_no_fp("comms modem reconnected")
|
||||
log.info("comms modem reconnected")
|
||||
-- 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
|
||||
state.reactor_formed = true
|
||||
|
||||
-- determine if we are still in a degraded state
|
||||
if not state.no_reactor then
|
||||
if ((not networked) or (state.wd_modem or state.wl_modem)) and state.reactor_formed then
|
||||
state.degraded = false
|
||||
end
|
||||
|
||||
_bp.smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM)
|
||||
|
||||
sys.rps.reconnect_reactor(dev.reactor)
|
||||
if networked then
|
||||
sys.plc_comms.reconnect_reactor(dev.reactor)
|
||||
end
|
||||
|
||||
-- partial reset of RPS, specific to becoming formed/reconnected
|
||||
-- without this, auto control can't resume on chunk load
|
||||
sys.rps.reset_reattach()
|
||||
elseif networked and type == "modem" then
|
||||
---@cast device Modem
|
||||
|
||||
local m_is_wl = device.isWireless()
|
||||
|
||||
log.info(util.c("BKPLN: ", util.trinary(m_is_wl, "WIRELESS", "WIRED"), " PHY_ATTACH ", iface))
|
||||
|
||||
local is_wd = _bp.wd_nic and (_bp.lan_iface == iface)
|
||||
local is_wl = _bp.wl_nic and (not _bp.wl_nic.is_connected()) and m_is_wl
|
||||
|
||||
if is_wd then
|
||||
-- connect this as the wired NIC
|
||||
_bp.wd_nic.connect(device)
|
||||
|
||||
log.info("BKPLN: WIRED PHY_UP " .. iface)
|
||||
print_no_fp("wired comms modem reconnected")
|
||||
|
||||
state.wd_modem = true
|
||||
|
||||
if _bp.act_nic == _bp.wd_nic then
|
||||
-- set as active
|
||||
_bp.wl_act = false
|
||||
_bp.act_nic = _bp.wd_nic
|
||||
elseif _bp.wl_act and not _bp.wlan_pref then
|
||||
-- switch back to preferred wired
|
||||
_bp.wl_act = false
|
||||
_bp.act_nic = _bp.wd_nic
|
||||
|
||||
sys.plc_comms.switch_nic(_bp.act_nic)
|
||||
log.info("BKPLN: switched comms to wired modem (preferred)")
|
||||
end
|
||||
elseif is_wl then
|
||||
-- connect this as the wireless NIC
|
||||
_bp.wl_nic.connect(device)
|
||||
|
||||
log.info("BKPLN: WIRELESS PHY_UP " .. iface)
|
||||
print_no_fp("wireless comms modem reconnected")
|
||||
|
||||
state.wl_modem = true
|
||||
|
||||
if _bp.act_nic == _bp.wl_nic then
|
||||
-- set as active
|
||||
_bp.wl_act = true
|
||||
_bp.act_nic = _bp.wl_nic
|
||||
elseif (not _bp.wl_act) and _bp.wlan_pref then
|
||||
-- switch back to preferred wireless
|
||||
_bp.wl_act = true
|
||||
_bp.act_nic = _bp.wl_nic
|
||||
|
||||
sys.plc_comms.switch_nic(_bp.act_nic)
|
||||
log.info("BKPLN: switched comms to wireless modem (preferred)")
|
||||
end
|
||||
elseif _bp.wl_nic and m_is_wl then
|
||||
-- the wireless NIC already has a modem
|
||||
print_no_fp("standby wireless modem connected")
|
||||
log.info("BKPLN: standby wireless modem connected")
|
||||
else
|
||||
print_no_fp("unassigned modem connected")
|
||||
log.warning("BKPLN: unassigned modem connected")
|
||||
end
|
||||
|
||||
-- determine if we are still in a degraded state
|
||||
if (state.wd_modem or state.wl_modem) and state.reactor_formed and not state.no_reactor then
|
||||
state.degraded = false
|
||||
end
|
||||
elseif device.isWireless() then
|
||||
log.info("unused wireless modem connected")
|
||||
else
|
||||
log.info("non-comms wired modem connected")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -830,6 +830,22 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog)
|
||||
---@class plc_comms
|
||||
local public = {}
|
||||
|
||||
-- switch the current active NIC
|
||||
---@param _nic nic
|
||||
function public.switch_nic(_nic)
|
||||
nic.closeAll()
|
||||
|
||||
if _nic.isWireless() then
|
||||
comms.set_trusted_range(config.TrustedRange)
|
||||
end
|
||||
|
||||
-- configure receive channels
|
||||
_nic.closeAll()
|
||||
_nic.open(config.PLC_Channel)
|
||||
|
||||
nic = _nic
|
||||
end
|
||||
|
||||
-- reconnect a newly connected reactor
|
||||
---@param new_reactor table
|
||||
function public.reconnect_reactor(new_reactor)
|
||||
|
||||
@ -18,15 +18,14 @@ local ui = {
|
||||
}
|
||||
|
||||
-- try to start the UI
|
||||
---@param theme FP_THEME front panel theme
|
||||
---@param color_mode COLOR_MODE color mode
|
||||
---@param config plc_config configuration
|
||||
---@return boolean success, any error_msg
|
||||
function renderer.try_start_ui(theme, color_mode)
|
||||
function renderer.try_start_ui(config)
|
||||
local status, msg = true, nil
|
||||
|
||||
if ui.display == nil then
|
||||
-- set theme
|
||||
style.set_theme(theme, color_mode)
|
||||
style.set_theme(config.FrontPanelTheme, config.ColorMode)
|
||||
|
||||
-- reset terminal
|
||||
term.setTextColor(colors.white)
|
||||
@ -40,7 +39,7 @@ function renderer.try_start_ui(theme, color_mode)
|
||||
end
|
||||
|
||||
-- apply color mode
|
||||
local c_mode_overrides = style.theme.color_modes[color_mode]
|
||||
local c_mode_overrides = style.theme.color_modes[config.ColorMode]
|
||||
for i = 1, #c_mode_overrides do
|
||||
term.setPaletteColor(c_mode_overrides[i].c, c_mode_overrides[i].hex)
|
||||
end
|
||||
@ -48,7 +47,7 @@ function renderer.try_start_ui(theme, color_mode)
|
||||
-- init front panel view
|
||||
status, msg = pcall(function ()
|
||||
ui.display = DisplayBox{window=term.current(),fg_bg=style.fp.root}
|
||||
panel_view(ui.display)
|
||||
panel_view(ui.display, config)
|
||||
end)
|
||||
|
||||
if status then
|
||||
|
||||
@ -91,9 +91,10 @@ local function main()
|
||||
fp_ok = false,
|
||||
shutdown = false,
|
||||
degraded = true,
|
||||
reactor_formed = true,
|
||||
no_reactor = true,
|
||||
no_modem = true
|
||||
reactor_formed = true,
|
||||
wd_modem = false,
|
||||
wl_modem = false
|
||||
},
|
||||
|
||||
-- control setpoints
|
||||
@ -123,6 +124,18 @@ local function main()
|
||||
mq_rps = mqueue.new(),
|
||||
mq_comms_tx = mqueue.new(),
|
||||
mq_comms_rx = mqueue.new()
|
||||
},
|
||||
|
||||
-- message queue commands
|
||||
q_cmds = {
|
||||
MQ__RPS_CMD = {
|
||||
SCRAM = 1,
|
||||
DEGRADED_SCRAM = 2,
|
||||
TRIP_TIMEOUT = 3
|
||||
},
|
||||
MQ__COMM_CMD = {
|
||||
SEND_STATUS = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,7 +155,7 @@ local function main()
|
||||
|
||||
-- setup front panel
|
||||
local message
|
||||
plc_state.fp_ok, message = renderer.try_start_ui(config.FrontPanelTheme, config.ColorMode)
|
||||
plc_state.fp_ok, message = renderer.try_start_ui(config)
|
||||
|
||||
-- ...or not
|
||||
if not plc_state.fp_ok then
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
local log = require("scada-common.log")
|
||||
local mqueue = require("scada-common.mqueue")
|
||||
local ppm = require("scada-common.ppm")
|
||||
local tcd = require("scada-common.tcd")
|
||||
local util = require("scada-common.util")
|
||||
local log = require("scada-common.log")
|
||||
local mqueue = require("scada-common.mqueue")
|
||||
local ppm = require("scada-common.ppm")
|
||||
local tcd = require("scada-common.tcd")
|
||||
local util = require("scada-common.util")
|
||||
|
||||
local databus = require("reactor-plc.databus")
|
||||
local renderer = require("reactor-plc.renderer")
|
||||
local backplane = require("reactor-plc.backplane")
|
||||
local databus = require("reactor-plc.databus")
|
||||
local renderer = require("reactor-plc.renderer")
|
||||
|
||||
local core = require("graphics.core")
|
||||
local core = require("graphics.core")
|
||||
|
||||
local threads = {}
|
||||
|
||||
@ -18,16 +19,6 @@ local SP_CTRL_SLEEP = 250 -- 250ms, 5 ticks
|
||||
|
||||
local BURN_RATE_RAMP_mB_s = 5.0
|
||||
|
||||
local MQ__RPS_CMD = {
|
||||
SCRAM = 1,
|
||||
DEGRADED_SCRAM = 2,
|
||||
TRIP_TIMEOUT = 3
|
||||
}
|
||||
|
||||
local MQ__COMM_CMD = {
|
||||
SEND_STATUS = 1
|
||||
}
|
||||
|
||||
-- main thread
|
||||
---@nodiscard
|
||||
---@param smem plc_shared_memory
|
||||
@ -50,9 +41,12 @@ function threads.thread__main(smem)
|
||||
local loop_clock = util.new_clock(MAIN_CLOCK)
|
||||
|
||||
-- load in from shared memory
|
||||
local networked = smem.networked
|
||||
local plc_state = smem.plc_state
|
||||
local plc_dev = smem.plc_dev
|
||||
local networked = smem.networked
|
||||
local plc_state = smem.plc_state
|
||||
local plc_dev = smem.plc_dev
|
||||
|
||||
local MQ__RPS_CMD = smem.q_cmds.MQ__RPS_CMD
|
||||
local MQ__COMM_CMD = smem.q_cmds.MQ__COMM_CMD
|
||||
|
||||
-- start clock
|
||||
loop_clock.start()
|
||||
@ -175,60 +169,8 @@ function threads.thread__main(smem)
|
||||
elseif event == "peripheral" then
|
||||
-- peripheral connect
|
||||
local type, device = ppm.mount(param1)
|
||||
|
||||
if type ~= nil and device ~= nil then
|
||||
if plc_state.no_reactor and (type == "fissionReactorLogicAdapter") then
|
||||
-- reconnected reactor
|
||||
plc_dev.reactor = device
|
||||
plc_state.no_reactor = false
|
||||
|
||||
println_ts("reactor reconnected")
|
||||
log.info("reactor reconnected")
|
||||
|
||||
-- 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
|
||||
|
||||
-- determine if we are still in a degraded state
|
||||
if (not networked or not plc_state.no_modem) and plc_state.reactor_formed then
|
||||
plc_state.degraded = false
|
||||
end
|
||||
|
||||
smem.q.mq_rps.push_command(MQ__RPS_CMD.SCRAM)
|
||||
|
||||
rps.reconnect_reactor(plc_dev.reactor)
|
||||
if networked then
|
||||
plc_comms.reconnect_reactor(plc_dev.reactor)
|
||||
end
|
||||
|
||||
-- partial reset of RPS, specific to becoming formed/reconnected
|
||||
-- without this, auto control can't resume on chunk load
|
||||
rps.reset_reattach()
|
||||
elseif networked and type == "modem" then
|
||||
---@cast device Modem
|
||||
local is_comms_modem = util.trinary(plc_dev.modem_wired, plc_dev.modem_iface == param1, device.isWireless())
|
||||
|
||||
-- note, check init_ok first since nic will be nil if it is false
|
||||
if is_comms_modem and not nic.is_connected() then
|
||||
-- reconnected modem
|
||||
plc_dev.modem = device
|
||||
plc_state.no_modem = false
|
||||
|
||||
nic.connect(device)
|
||||
|
||||
println_ts("comms modem reconnected")
|
||||
log.info("comms modem reconnected")
|
||||
|
||||
-- determine if we are still in a degraded state
|
||||
if plc_state.reactor_formed and not plc_state.no_reactor then
|
||||
plc_state.degraded = false
|
||||
end
|
||||
elseif device.isWireless() then
|
||||
log.info("unused wireless modem connected")
|
||||
else
|
||||
log.info("non-comms wired modem connected")
|
||||
end
|
||||
end
|
||||
backplane.attach(param1, type, device, println_ts)
|
||||
end
|
||||
|
||||
-- update indicators
|
||||
@ -295,6 +237,8 @@ function threads.thread__rps(smem)
|
||||
|
||||
local rps_queue = smem.q.mq_rps
|
||||
|
||||
local MQ__RPS_CMD = smem.q_cmds.MQ__RPS_CMD
|
||||
|
||||
local was_linked = false
|
||||
local last_update = util.time()
|
||||
|
||||
@ -425,8 +369,10 @@ function threads.thread__comms_tx(smem)
|
||||
log.debug("OS: comms tx thread start")
|
||||
|
||||
-- load in from shared memory
|
||||
local plc_state = smem.plc_state
|
||||
local comms_queue = smem.q.mq_comms_tx
|
||||
local plc_state = smem.plc_state
|
||||
local comms_queue = smem.q.mq_comms_tx
|
||||
|
||||
local MQ__COMM_CMD = smem.q_cmds.MQ__COMM_CMD
|
||||
|
||||
local last_update = util.time()
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user