diff --git a/coordinator/iocontrol.lua b/coordinator/iocontrol.lua index 4258bc1..8f461cc 100644 --- a/coordinator/iocontrol.lua +++ b/coordinator/iocontrol.lua @@ -207,6 +207,8 @@ function iocontrol.update_statuses(statuses) unit.reactor_ps.publish("computed_status", 5) -- faulted elseif not unit.reactor_data.formed then unit.reactor_ps.publish("computed_status", 6) -- multiblock not formed + elseif unit.reactor_data.rps_status.force_dis then + unit.reactor_ps.publish("computed_status", 7) -- reactor force disabled elseif unit.reactor_data.rps_tripped and unit.reactor_data.rps_trip_cause ~= "manual" then unit.reactor_ps.publish("computed_status", 4) -- SCRAM else diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 1c6b90b..86d49be 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -16,7 +16,7 @@ local config = require("coordinator.config") local coordinator = require("coordinator.coordinator") local renderer = require("coordinator.renderer") -local COORDINATOR_VERSION = "alpha-v0.6.5" +local COORDINATOR_VERSION = "alpha-v0.6.6" local print = util.print local println = util.println diff --git a/coordinator/ui/components/reactor.lua b/coordinator/ui/components/reactor.lua index e04a34e..8efe9ce 100644 --- a/coordinator/ui/components/reactor.lua +++ b/coordinator/ui/components/reactor.lua @@ -27,7 +27,7 @@ local function new_view(root, x, y, data, ps) local text_fg_bg = cpair(colors.black, colors.lightGray) local lu_col = cpair(colors.gray, colors.gray) - local status = StateIndicator{parent=reactor,x=8,y=1,states=style.reactor.states,value=1,min_width=14} + local status = StateIndicator{parent=reactor,x=6,y=1,states=style.reactor.states,value=1,min_width=16} local core_temp = DataIndicator{parent=reactor,x=2,y=3,lu_colors=lu_col,label="Core Temp:",unit="K",format="%10.2f",value=0,width=26,fg_bg=text_fg_bg} local burn_r = DataIndicator{parent=reactor,x=2,y=4,lu_colors=lu_col,label="Burn Rate:",unit="mB/t",format="%10.1f",value=0,width=26,fg_bg=text_fg_bg} local heating_r = DataIndicator{parent=reactor,x=2,y=5,lu_colors=lu_col,label="Heating:",unit="mB/t",format="%12.0f",value=0,commas=true,width=26,fg_bg=text_fg_bg} diff --git a/coordinator/ui/style.lua b/coordinator/ui/style.lua index ae83155..67453c7 100644 --- a/coordinator/ui/style.lua +++ b/coordinator/ui/style.lua @@ -58,6 +58,10 @@ style.reactor = { { color = cpair(colors.black, colors.orange), text = "NOT FORMED" + }, + { + color = cpair(colors.black, colors.red), + text = "FORCE DISABLED" } } } diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index 578d0d8..cdc131e 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -51,14 +51,17 @@ function plc.rps_init(reactor, is_formed) fault = 7, timeout = 8, manual = 9, - sys_fail = 10 + automatic = 10, + sys_fail = 11, + force_disabled = 12 } local self = { reactor = reactor, - state = { false, false, false, false, false, false, false, false, false, false }, + state = { false, false, false, false, false, false, false, false, false, false, false, false }, reactor_enabled = false, formed = is_formed, + force_disabled = false, tripped = false, trip_cause = "" ---@type rps_trip_cause } @@ -95,6 +98,21 @@ function plc.rps_init(reactor, is_formed) end end + -- check if the reactor is force disabled + local function _is_force_disabled() + local disabled = self.reactor.isForceDisabled() + if disabled == ppm.ACCESS_FAULT then + -- lost the peripheral or terminated, handled later + _set_fault() + else + self.force_disabled = disabled + + if not self.state[state_keys.force_disabled] then + self.state[state_keys.force_disabled] = disabled + end + end + end + -- check for critical damage local function _damage_critical() local damage_percent = self.reactor.getDamagePercent() @@ -185,6 +203,11 @@ function plc.rps_init(reactor, is_formed) self.state[state_keys.manual] = true end + -- automatic SCRAM commanded by supervisor/coordinator + function public.trip_auto() + self.state[state_keys.automatic] = true + end + -- trip for unformed reactor function public.trip_sys_fail() self.state[state_keys.fault] = true @@ -237,6 +260,7 @@ function plc.rps_init(reactor, is_formed) -- update state parallel.waitForAll( _is_formed, + _is_force_disabled, _damage_critical, _high_temp, _no_coolant, @@ -255,6 +279,9 @@ function plc.rps_init(reactor, is_formed) elseif self.state[state_keys.sys_fail] then log.warning("RPS: system failure, reactor not formed") status = rps_status_t.sys_fail + elseif self.state[state_keys.force_disabled] then + log.warning("RPS: reactor was force disabled") + status = rps_status_t.force_disabled elseif self.state[state_keys.dmg_crit] then log.warning("RPS: damage critical") status = rps_status_t.dmg_crit @@ -282,6 +309,9 @@ function plc.rps_init(reactor, is_formed) elseif self.state[state_keys.manual] then log.warning("RPS: manual SCRAM requested") status = rps_status_t.manual + elseif self.state[state_keys.automatic] then + log.warning("RPS: automatic SCRAM requested") + status = rps_status_t.automatic else self.tripped = false end @@ -292,8 +322,13 @@ function plc.rps_init(reactor, is_formed) self.tripped = true self.trip_cause = status + -- in the case that the reactor is detected to be active, it will be scrammed shortly after this in the main RPS loop if we don't here if self.formed then - public.scram() + if not self.force_disabled then + public.scram() + else + log.warning("RPS: skipping SCRAM due to reactor being force disabled") + end else log.warning("RPS: skipping SCRAM due to not being formed") end @@ -306,6 +341,7 @@ function plc.rps_init(reactor, is_formed) function public.is_tripped() return self.tripped end function public.is_active() return self.reactor_enabled end function public.is_formed() return self.formed end + function public.is_force_disabled() return self.force_disabled end -- reset the RPS ---@param quiet? boolean true to suppress the info log message diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 02786f0..2d56bdd 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -13,7 +13,7 @@ local config = require("reactor-plc.config") local plc = require("reactor-plc.plc") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "beta-v0.9.2" +local R_PLC_VERSION = "beta-v0.9.3" local print = util.print local println = util.println diff --git a/scada-common/types.lua b/scada-common/types.lua index de49cf0..b86aca7 100644 --- a/scada-common/types.lua +++ b/scada-common/types.lua @@ -82,6 +82,9 @@ types.TRI_FAIL = { ---| "fault" ---| "timeout" ---| "manual" +---| "automatic" +---| "sys_fail" +---| "force_disabled" ---@alias rtu_t string types.rtu_t = { @@ -106,7 +109,9 @@ types.rps_status_t = { fault = "fault", timeout = "timeout", manual = "manual", - sys_fail = "sys_fail" + automatic = "automatic", + sys_fail = "sys_fail", + force_disabled = "force_disabled" } -- turbine steam dumping modes diff --git a/supervisor/session/plc.lua b/supervisor/session/plc.lua index 4e72a68..6ee2115 100644 --- a/supervisor/session/plc.lua +++ b/supervisor/session/plc.lua @@ -103,7 +103,9 @@ function plc.new_session(id, for_reactor, in_queue, out_queue) fault = false, timeout = false, manual = false, - sys_fail = false + automatic = false, + sys_fail = false, + force_dis = false }, ---@class mek_status mek_status = { @@ -134,7 +136,6 @@ function plc.new_session(id, for_reactor, in_queue, out_queue) }, ---@class mek_struct mek_struct = { - formed = false, length = 0, width = 0, height = 0, @@ -167,7 +168,9 @@ function plc.new_session(id, for_reactor, in_queue, out_queue) self.sDB.rps_status.fault = rps_status[7] self.sDB.rps_status.timeout = rps_status[8] self.sDB.rps_status.manual = rps_status[9] - self.sDB.rps_status.sys_fail = rps_status[10] + self.sDB.rps_status.automatic = rps_status[10] + self.sDB.rps_status.sys_fail = rps_status[11] + self.sDB.rps_status.force_dis = rps_status[12] end -- copy in the reactor status @@ -382,7 +385,7 @@ function plc.new_session(id, for_reactor, in_queue, out_queue) }) elseif pkt.type == RPLC_TYPES.RPS_STATUS then -- RPS status packet received, copy data - if pkt.length == 10 then + if pkt.length == 12 then local status = pcall(_copy_rps_status, pkt.data) if status then -- copied in RPS status data OK diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 2459673..b84fecf 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -13,7 +13,7 @@ local svsessions = require("supervisor.session.svsessions") local config = require("supervisor.config") local supervisor = require("supervisor.supervisor") -local SUPERVISOR_VERSION = "beta-v0.7.0" +local SUPERVISOR_VERSION = "beta-v0.7.1" local print = util.print local println = util.println