#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)
|
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
|
-- set this as active for now
|
||||||
_bp.wl_act = false
|
_bp.wl_act = false
|
||||||
_bp.act_nic = _bp.wd_nic
|
_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)
|
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
|
-- 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
|
if (modem and _bp.wlan_pref) or not (_bp.act_nic and _bp.act_nic.is_connected()) then
|
||||||
_bp.wl_act = true
|
_bp.wl_act = true
|
||||||
@ -68,12 +72,8 @@ function backplane.init(config, __shared_memory)
|
|||||||
end
|
end
|
||||||
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
|
-- 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")
|
println("startup> comms modem not found")
|
||||||
log.warning("BKPLN: no comms modem on startup")
|
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 device table
|
||||||
---@param print_no_fp function
|
---@param print_no_fp function
|
||||||
function backplane.attach(iface, type, device, print_no_fp)
|
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 networked = _bp.smem.networked
|
||||||
local state = _bp.smem.plc_state
|
local state = _bp.smem.plc_state
|
||||||
local dev = _bp.smem.plc_dev
|
local dev = _bp.smem.plc_dev
|
||||||
local sys = _bp.smem.plc_sys
|
local sys = _bp.smem.plc_sys
|
||||||
|
|
||||||
if state.no_reactor and (type == "fissionReactorLogicAdapter") then
|
if type ~= nil and device ~= nil then
|
||||||
-- reconnected reactor
|
if state.no_reactor and (type == "fissionReactorLogicAdapter") then
|
||||||
dev.reactor = device
|
-- reconnected reactor
|
||||||
state.no_reactor = false
|
dev.reactor = device
|
||||||
|
state.no_reactor = false
|
||||||
|
|
||||||
print_no_fp("reactor reconnected")
|
print_no_fp("reactor reconnected")
|
||||||
log.info("BKPLN: reactor reconnected")
|
log.info("BKPLN: reactor reconnected")
|
||||||
|
|
||||||
-- we need to assume formed here as we cannot check in this main loop
|
-- 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
|
-- RPS will identify if it isn't and this will get set false later
|
||||||
state.reactor_formed = true
|
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")
|
|
||||||
|
|
||||||
-- determine if we are still in a degraded state
|
-- 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
|
state.degraded = false
|
||||||
end
|
end
|
||||||
elseif device.isWireless() then
|
|
||||||
log.info("unused wireless modem connected")
|
|
||||||
else
|
|
||||||
log.info("non-comms wired modem connected")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -830,6 +830,22 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog)
|
|||||||
---@class plc_comms
|
---@class plc_comms
|
||||||
local public = {}
|
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
|
-- reconnect a newly connected reactor
|
||||||
---@param new_reactor table
|
---@param new_reactor table
|
||||||
function public.reconnect_reactor(new_reactor)
|
function public.reconnect_reactor(new_reactor)
|
||||||
|
|||||||
@ -18,15 +18,14 @@ local ui = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
-- try to start the UI
|
-- try to start the UI
|
||||||
---@param theme FP_THEME front panel theme
|
---@param config plc_config configuration
|
||||||
---@param color_mode COLOR_MODE color mode
|
|
||||||
---@return boolean success, any error_msg
|
---@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
|
local status, msg = true, nil
|
||||||
|
|
||||||
if ui.display == nil then
|
if ui.display == nil then
|
||||||
-- set theme
|
-- set theme
|
||||||
style.set_theme(theme, color_mode)
|
style.set_theme(config.FrontPanelTheme, config.ColorMode)
|
||||||
|
|
||||||
-- reset terminal
|
-- reset terminal
|
||||||
term.setTextColor(colors.white)
|
term.setTextColor(colors.white)
|
||||||
@ -40,7 +39,7 @@ function renderer.try_start_ui(theme, color_mode)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- apply color mode
|
-- 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
|
for i = 1, #c_mode_overrides do
|
||||||
term.setPaletteColor(c_mode_overrides[i].c, c_mode_overrides[i].hex)
|
term.setPaletteColor(c_mode_overrides[i].c, c_mode_overrides[i].hex)
|
||||||
end
|
end
|
||||||
@ -48,7 +47,7 @@ function renderer.try_start_ui(theme, color_mode)
|
|||||||
-- init front panel view
|
-- init front panel view
|
||||||
status, msg = pcall(function ()
|
status, msg = pcall(function ()
|
||||||
ui.display = DisplayBox{window=term.current(),fg_bg=style.fp.root}
|
ui.display = DisplayBox{window=term.current(),fg_bg=style.fp.root}
|
||||||
panel_view(ui.display)
|
panel_view(ui.display, config)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if status then
|
if status then
|
||||||
|
|||||||
@ -91,9 +91,10 @@ local function main()
|
|||||||
fp_ok = false,
|
fp_ok = false,
|
||||||
shutdown = false,
|
shutdown = false,
|
||||||
degraded = true,
|
degraded = true,
|
||||||
reactor_formed = true,
|
|
||||||
no_reactor = true,
|
no_reactor = true,
|
||||||
no_modem = true
|
reactor_formed = true,
|
||||||
|
wd_modem = false,
|
||||||
|
wl_modem = false
|
||||||
},
|
},
|
||||||
|
|
||||||
-- control setpoints
|
-- control setpoints
|
||||||
@ -123,6 +124,18 @@ local function main()
|
|||||||
mq_rps = mqueue.new(),
|
mq_rps = mqueue.new(),
|
||||||
mq_comms_tx = mqueue.new(),
|
mq_comms_tx = mqueue.new(),
|
||||||
mq_comms_rx = 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
|
-- setup front panel
|
||||||
local message
|
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
|
-- ...or not
|
||||||
if not plc_state.fp_ok then
|
if not plc_state.fp_ok then
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
local log = require("scada-common.log")
|
local log = require("scada-common.log")
|
||||||
local mqueue = require("scada-common.mqueue")
|
local mqueue = require("scada-common.mqueue")
|
||||||
local ppm = require("scada-common.ppm")
|
local ppm = require("scada-common.ppm")
|
||||||
local tcd = require("scada-common.tcd")
|
local tcd = require("scada-common.tcd")
|
||||||
local util = require("scada-common.util")
|
local util = require("scada-common.util")
|
||||||
|
|
||||||
local databus = require("reactor-plc.databus")
|
local backplane = require("reactor-plc.backplane")
|
||||||
local renderer = require("reactor-plc.renderer")
|
local databus = require("reactor-plc.databus")
|
||||||
|
local renderer = require("reactor-plc.renderer")
|
||||||
|
|
||||||
local core = require("graphics.core")
|
local core = require("graphics.core")
|
||||||
|
|
||||||
local threads = {}
|
local threads = {}
|
||||||
|
|
||||||
@ -18,16 +19,6 @@ local SP_CTRL_SLEEP = 250 -- 250ms, 5 ticks
|
|||||||
|
|
||||||
local BURN_RATE_RAMP_mB_s = 5.0
|
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
|
-- main thread
|
||||||
---@nodiscard
|
---@nodiscard
|
||||||
---@param smem plc_shared_memory
|
---@param smem plc_shared_memory
|
||||||
@ -50,9 +41,12 @@ function threads.thread__main(smem)
|
|||||||
local loop_clock = util.new_clock(MAIN_CLOCK)
|
local loop_clock = util.new_clock(MAIN_CLOCK)
|
||||||
|
|
||||||
-- load in from shared memory
|
-- load in from shared memory
|
||||||
local networked = smem.networked
|
local networked = smem.networked
|
||||||
local plc_state = smem.plc_state
|
local plc_state = smem.plc_state
|
||||||
local plc_dev = smem.plc_dev
|
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
|
-- start clock
|
||||||
loop_clock.start()
|
loop_clock.start()
|
||||||
@ -175,60 +169,8 @@ function threads.thread__main(smem)
|
|||||||
elseif event == "peripheral" then
|
elseif event == "peripheral" then
|
||||||
-- peripheral connect
|
-- peripheral connect
|
||||||
local type, device = ppm.mount(param1)
|
local type, device = ppm.mount(param1)
|
||||||
|
|
||||||
if type ~= nil and device ~= nil then
|
if type ~= nil and device ~= nil then
|
||||||
if plc_state.no_reactor and (type == "fissionReactorLogicAdapter") then
|
backplane.attach(param1, type, device, println_ts)
|
||||||
-- 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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- update indicators
|
-- update indicators
|
||||||
@ -295,6 +237,8 @@ function threads.thread__rps(smem)
|
|||||||
|
|
||||||
local rps_queue = smem.q.mq_rps
|
local rps_queue = smem.q.mq_rps
|
||||||
|
|
||||||
|
local MQ__RPS_CMD = smem.q_cmds.MQ__RPS_CMD
|
||||||
|
|
||||||
local was_linked = false
|
local was_linked = false
|
||||||
local last_update = util.time()
|
local last_update = util.time()
|
||||||
|
|
||||||
@ -425,8 +369,10 @@ function threads.thread__comms_tx(smem)
|
|||||||
log.debug("OS: comms tx thread start")
|
log.debug("OS: comms tx thread start")
|
||||||
|
|
||||||
-- load in from shared memory
|
-- load in from shared memory
|
||||||
local plc_state = smem.plc_state
|
local plc_state = smem.plc_state
|
||||||
local comms_queue = smem.q.mq_comms_tx
|
local comms_queue = smem.q.mq_comms_tx
|
||||||
|
|
||||||
|
local MQ__COMM_CMD = smem.q_cmds.MQ__COMM_CMD
|
||||||
|
|
||||||
local last_update = util.time()
|
local last_update = util.time()
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user