Compare commits

...

3 Commits

8 changed files with 85 additions and 16 deletions

View File

@@ -515,12 +515,13 @@ doc("fp_crd_rtt", "RTT", "Each connection has a round trip time, or RTT. Since t
list(DOC_LIST_TYPE.BULLET, { "green: <=1000ms", "yellow: <=1500ms ", "red: >1500ms" }) list(DOC_LIST_TYPE.BULLET, { "green: <=1000ms", "yellow: <=1500ms ", "red: >1500ms" })
sect("CRD Tab") sect("CRD Tab")
text("This tab includes information about the Coordinator, partially covered by 'Common Items'.") text("This tab includes information about the Coordinator, partially covered by 'Common Items'.")
doc("fp_crd_spkr", "SPEAKER", "This indicates if the speaker is connected.")
doc("fp_crd_rt_main", "RT MAIN", "This indicates that the device's main loop co-routine is running.") doc("fp_crd_rt_main", "RT MAIN", "This indicates that the device's main loop co-routine is running.")
doc("fp_crd_rt_render", "RT RENDER", "This indicates that the Coordinator graphics renderer co-routine is running.") doc("fp_crd_rt_render", "RT RENDER", "This indicates that the Coordinator graphics renderer co-routine is running.")
doc("fp_crd_mon_main", "MAIN MONITOR", "The connection status of the main display monitor.") doc("fp_crd_spkr", "SPEAKER", "This indicates if the speaker is connected.")
doc("fp_crd_mon_flow", "FLOW MONITOR", "The connection status of the coolant and waste flow display monitor.") list(DOC_LIST_TYPE.LED, { "Disconnected", "Display View Unloaded", "Display View Loaded" }, { colors.gray, colors.red, colors.green })
doc("fp_crd_mon_unit", "UNIT X MONITOR", "The connection status of the monitor associated with a given unit.") doc("fp_crd_mon_main", "MAIN DISPLAY", "The connection status of the main display monitor.")
doc("fp_crd_mon_flow", "FLOW DISPLAY", "The connection status of the coolant and waste flow display monitor.")
doc("fp_crd_mon_unit", "UNIT X DISPLAY", "The connection status of the monitor associated with a given unit.")
sect("API Tab") sect("API Tab")
text("This tab lists connected pocket computers. Refer to the Supervisor PKT tab documentation for details on fields.") text("This tab lists connected pocket computers. Refer to the Supervisor PKT tab documentation for details on fields.")

View File

@@ -7,6 +7,8 @@ local network = require("scada-common.network")
local ppm = require("scada-common.ppm") local ppm = require("scada-common.ppm")
local util = require("scada-common.util") local util = require("scada-common.util")
local databus = require("reactor-plc.databus")
local println = util.println local println = util.println
---@class plc_backplane ---@class plc_backplane
@@ -118,6 +120,16 @@ function backplane.init(config, __shared_memory)
plc_state.reactor_formed = false plc_state.reactor_formed = false
end end
end end
-- detect and warn about multiple reactors
if #ppm.get_all_devices("fissionReactorLogicAdapter") > 1 then
println("startup> !! DANGER !! more than one reactor was detected! do not share reactor connections between multiple PLCs! they may not all be protected and used as configured")
log.warning("BKPLN: !! DANGER !! more than one reactor was detected on startup!")
log.warning("BKPLN: do NOT share reactor connections between multiple PLCs! they may not all be protected and used as configured")
databus.tx_multi_reactor(true)
end
end end
-- get the active NIC -- get the active NIC
@@ -139,7 +151,15 @@ function backplane.attach(iface, type, device, print_no_fp)
local sys = _bp.smem.plc_sys local sys = _bp.smem.plc_sys
if type ~= nil and device ~= nil then if type ~= nil and device ~= nil then
if state.no_reactor and (type == "fissionReactorLogicAdapter") then if type == "fissionReactorLogicAdapter" then
if not state.no_reactor then
log.warning("BKPLN: !! DANGER !! an additional reactor (" .. iface .. ") was connected and will not be used!")
log.warning("BKPLN: do NOT share reactor connections between multiple PLCs! they may not all be protected and used as configured")
databus.tx_multi_reactor(true)
return
end
-- reconnected reactor -- reconnected reactor
log.info("BKPLN: REACTOR LINK_UP " .. iface) log.info("BKPLN: REACTOR LINK_UP " .. iface)
@@ -250,6 +270,17 @@ function backplane.detach(iface, type, device, print_no_fp)
state.no_reactor = true state.no_reactor = true
state.degraded = true state.degraded = true
-- clear this tentatively, so then if there is >1, that will be reported in backplane.attach in the following if statement
databus.tx_multi_reactor(false)
-- try to find another reactor (this should not work unless multiple were incorrectly connected)
local reactor, r_iface = ppm.get_fission_reactor()
if reactor and r_iface then
log.info("BKPLN: found another fission reactor logic adapter")
backplane.attach(r_iface, type, reactor, print_no_fp)
end
elseif _bp.smem.networked and type == "modem" then elseif _bp.smem.networked and type == "modem" then
---@cast device Modem ---@cast device Modem

View File

@@ -141,6 +141,7 @@ local function self_check()
self.self_check_msg("> check fission reactor formed...") self.self_check_msg("> check fission reactor formed...")
-- this consumes events, but that is fine here -- this consumes events, but that is fine here
self.self_check_msg(nil, reactor and reactor.isFormed(), "ensure the fission reactor multiblock is formed") self.self_check_msg(nil, reactor and reactor.isFormed(), "ensure the fission reactor multiblock is formed")
self.self_check_msg("> check for no more than one reactor...", #ppm.get_all_devices("fissionReactorLogicAdapter") <= 1, "there MUST be no more than one reactor connected, as a PLC uses the first one it finds, which may not always be the same one")
self.self_check_msg("> check configuration...", valid_cfg, "go through Configure System and apply settings to set any missing settings and repair any corrupted ones") self.self_check_msg("> check configuration...", valid_cfg, "go through Configure System and apply settings to set any missing settings and repair any corrupted ones")

View File

@@ -56,6 +56,12 @@ function databus.tx_hw_status(plc_state)
databus.ps.publish("has_wl_modem", plc_state.wl_modem) databus.ps.publish("has_wl_modem", plc_state.wl_modem)
end end
-- transmiti f the reactor dangerously has multiple fission reactor logic adapters
---@param multi boolean has multiple reactors
function databus.tx_multi_reactor(multi)
databus.ps.publish("has_multi_reactor", multi)
end
-- transmit thread (routine) statuses -- transmit thread (routine) statuses
---@param thread string thread name ---@param thread string thread name
---@param ok boolean thread state ---@param ok boolean thread state

View File

@@ -2,6 +2,7 @@
-- Reactor PLC Front Panel GUI -- Reactor PLC Front Panel GUI
-- --
local tcd = require("scada-common.tcd")
local types = require("scada-common.types") local types = require("scada-common.types")
local util = require("scada-common.util") local util = require("scada-common.util")
@@ -161,6 +162,34 @@ local function init(panel, config)
TextBox{parent=hw_labels,text="NT v"..databus.ps.get("comms_version"),fg_bg=s_hi_box} TextBox{parent=hw_labels,text="NT v"..databus.ps.get("comms_version"),fg_bg=s_hi_box}
TextBox{parent=hw_labels,text="SN "..comp_id.."-PLC",fg_bg=s_hi_box} TextBox{parent=hw_labels,text="SN "..comp_id.."-PLC",fg_bg=s_hi_box}
-- warning about multiple reactors connected
local warn_strings = { "!! DANGER !!\n>1 REACTOR\nLOGIC ADAPTER", "REMOVE\nALL BUT ONE\nLOGIC ADAPTER" }
local multi_warn = TextBox{parent=status,text=warn_strings[1],width=status.get_width()-2,alignment=ALIGN.CENTER,fg_bg=cpair(colors.yellow,colors.red),hidden=true}
local warn_toggle = true
local function flash_warn()
multi_warn.recolor(util.trinary(warn_toggle, colors.black, colors.yellow))
multi_warn.set_value(util.trinary(warn_toggle, warn_strings[2], warn_strings[1]))
warn_toggle = not warn_toggle
if databus.ps.get("has_multi_reactor") then tcd.dispatch_unique(2, flash_warn) end
end
multi_warn.register(databus.ps, "has_multi_reactor", function (v)
if v then
multi_warn.show(true)
warn_toggle = false
flash_warn()
tcd.dispatch_unique(2, flash_warn)
else
tcd.abort(flash_warn)
multi_warn.hide(true)
end
end)
-- --
-- rps list -- rps list
-- --

View File

@@ -19,7 +19,7 @@ local plc = require("reactor-plc.plc")
local renderer = require("reactor-plc.renderer") local renderer = require("reactor-plc.renderer")
local threads = require("reactor-plc.threads") local threads = require("reactor-plc.threads")
local R_PLC_VERSION = "v1.10.0" local R_PLC_VERSION = "v1.10.1"
local println = util.println local println = util.println
local println_ts = util.println_ts local println_ts = util.println_ts

View File

@@ -425,26 +425,27 @@ end
-- get a mounted peripheral by type (if multiple, returns the first) -- get a mounted peripheral by type (if multiple, returns the first)
---@nodiscard ---@nodiscard
---@param name string type name ---@param type string type name
---@return table|nil device function table ---@return table|nil device, string|nil iface device and interface
function ppm.get_device(name) function ppm.get_device(type)
local device = nil local device, d_iface = nil, nil
for _, data in pairs(_ppm.mounts) do for iface, data in pairs(_ppm.mounts) do
if data.type == name then if data.type == type then
device = data.dev device = data.dev
d_iface = iface
break break
end end
end end
return device return device, d_iface
end end
-- SPECIFIC DEVICE ACCESSORS -- -- SPECIFIC DEVICE ACCESSORS --
-- get the fission reactor (if multiple, returns the first) -- get the fission reactor (if multiple, returns the first)
---@nodiscard ---@nodiscard
---@return table|nil reactor function table ---@return table|nil reactor, string|nil iface reactor and interface
function ppm.get_fission_reactor() return ppm.get_device("fissionReactorLogicAdapter") end function ppm.get_fission_reactor() return ppm.get_device("fissionReactorLogicAdapter") end
-- get a modem by name -- get a modem by name
@@ -470,8 +471,8 @@ function ppm.get_wireless_modem()
for iface, device in pairs(_ppm.mounts) do for iface, device in pairs(_ppm.mounts) do
if device.type == "modem" and (emulated_env or device.dev.isWireless()) then if device.type == "modem" and (emulated_env or device.dev.isWireless()) then
w_iface = iface
w_modem = device.dev w_modem = device.dev
w_iface = iface
break break
end end
end end

View File

@@ -24,7 +24,7 @@ local t_pack = table.pack
local util = {} local util = {}
-- scada-common version -- scada-common version
util.version = "1.6.0" util.version = "1.6.1"
util.TICK_TIME_S = 0.05 util.TICK_TIME_S = 0.05
util.TICK_TIME_MS = 50 util.TICK_TIME_MS = 50