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" })
sect("CRD Tab")
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_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_mon_flow", "FLOW MONITOR", "The connection status of the coolant and waste flow display monitor.")
doc("fp_crd_mon_unit", "UNIT X MONITOR", "The connection status of the monitor associated with a given unit.")
doc("fp_crd_spkr", "SPEAKER", "This indicates if the speaker is connected.")
list(DOC_LIST_TYPE.LED, { "Disconnected", "Display View Unloaded", "Display View Loaded" }, { colors.gray, colors.red, colors.green })
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")
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 util = require("scada-common.util")
local databus = require("reactor-plc.databus")
local println = util.println
---@class plc_backplane
@@ -118,6 +120,16 @@ function backplane.init(config, __shared_memory)
plc_state.reactor_formed = false
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
-- get the active NIC
@@ -139,7 +151,15 @@ function backplane.attach(iface, type, device, print_no_fp)
local sys = _bp.smem.plc_sys
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
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.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
---@cast device Modem

View File

@@ -141,6 +141,7 @@ local function self_check()
self.self_check_msg("> check fission reactor formed...")
-- 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("> 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")

View File

@@ -56,6 +56,12 @@ function databus.tx_hw_status(plc_state)
databus.ps.publish("has_wl_modem", plc_state.wl_modem)
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
---@param thread string thread name
---@param ok boolean thread state

View File

@@ -2,6 +2,7 @@
-- Reactor PLC Front Panel GUI
--
local tcd = require("scada-common.tcd")
local types = require("scada-common.types")
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="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
--

View File

@@ -19,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.10.0"
local R_PLC_VERSION = "v1.10.1"
local println = util.println
local println_ts = util.println_ts

View File

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

View File

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