From f2f5c3201f73504baac43283e5cc3742ed26de72 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 12 Nov 2023 11:54:47 -0500 Subject: [PATCH] #362 taking max of connected radiation monitors --- coordinator/iocontrol.lua | 69 ++++++++++++++++++++--------- rtu/configure.lua | 25 +++++++---- rtu/startup.lua | 3 +- rtu/threads.lua | 5 +++ supervisor/facility.lua | 36 ++++++--------- supervisor/session/rtu/boilerv.lua | 7 ++- supervisor/session/rtu/dynamicv.lua | 7 ++- supervisor/session/rtu/envd.lua | 9 ++-- supervisor/session/rtu/imatrix.lua | 7 ++- supervisor/session/rtu/redstone.lua | 2 +- supervisor/session/rtu/sna.lua | 2 +- supervisor/session/rtu/sps.lua | 2 +- supervisor/session/rtu/turbinev.lua | 7 ++- supervisor/unit.lua | 3 +- 14 files changed, 116 insertions(+), 68 deletions(-) diff --git a/coordinator/iocontrol.lua b/coordinator/iocontrol.lua index 5ccffae..96911e7 100644 --- a/coordinator/iocontrol.lua +++ b/coordinator/iocontrol.lua @@ -469,7 +469,7 @@ function iocontrol.record_unit_builds(builds) -- note: if not all units and RTUs are connected, some will be nil for id, build in pairs(builds) do - local unit = io.units[id] ---@type ioctl_unit + local unit = io.units[id] ---@type ioctl_unit local log_header = util.c("iocontrol.record_unit_builds[UNIT ", id, "]: ") @@ -694,8 +694,8 @@ function iocontrol.update_facility_status(status) for id, sps in pairs(rtu_statuses.sps) do if type(fac.sps_data_tbl[id]) == "table" then - local data = fac.sps_data_tbl[id] ---@type sps_session_db - local ps = fac.sps_ps_tbl[id] ---@type psil + local data = fac.sps_data_tbl[id] ---@type sps_session_db + local ps = fac.sps_ps_tbl[id] ---@type psil local rtu_faulted = _record_multiblock_status(sps, data, ps) @@ -732,8 +732,8 @@ function iocontrol.update_facility_status(status) for id, tank in pairs(rtu_statuses.tanks) do if type(fac.tank_data_tbl[id]) == "table" then - local data = fac.tank_data_tbl[id] ---@type dynamicv_session_db - local ps = fac.tank_ps_tbl[id] ---@type psil + local data = fac.tank_data_tbl[id] ---@type dynamicv_session_db + local ps = fac.tank_ps_tbl[id] ---@type psil local rtu_faulted = _record_multiblock_status(tank, data, ps) @@ -762,12 +762,23 @@ function iocontrol.update_facility_status(status) -- environment detector status if type(rtu_statuses.rad_mon) == "table" then if #rtu_statuses.rad_mon > 0 then - local rad_mon = rtu_statuses.rad_mon[1] - local rtu_faulted = rad_mon[1] ---@type boolean - fac.radiation = rad_mon[2] ---@type number + local max_rad, max_reading, any_faulted = 0, types.new_zero_radiation_reading(), false - fac.ps.publish("rad_computed_status", util.trinary(rtu_faulted, 2, 3)) - fac.ps.publish("radiation", fac.radiation) + for i = 1, #rtu_statuses.rad_mon do + local rad_mon = rtu_statuses.rad_mon[i] + local rtu_faulted = rad_mon[1] ---@type boolean + local radiation = rad_mon[2] ---@type radiation_reading + local rad_raw = rad_mon[3] ---@type number + + any_faulted = any_faulted or rtu_faulted + if rad_raw > max_rad then + max_rad = rad_raw + max_reading = radiation + end + end + + fac.radiation = max_reading + fac.ps.publish("rad_computed_status", util.trinary(any_faulted, 2, 3)) else fac.radiation = types.new_zero_radiation_reading() fac.ps.publish("rad_computed_status", 1) @@ -776,6 +787,8 @@ function iocontrol.update_facility_status(status) log.debug(log_header .. "radiation monitor list not a table") valid = false end + + fac.ps.publish("radiation", fac.radiation) else log.debug(log_header .. "rtu statuses not a table") valid = false @@ -917,8 +930,8 @@ function iocontrol.update_unit_statuses(statuses) for id, boiler in pairs(rtu_statuses.boilers) do if type(unit.boiler_data_tbl[id]) == "table" then - local data = unit.boiler_data_tbl[id] ---@type boilerv_session_db - local ps = unit.boiler_ps_tbl[id] ---@type psil + local data = unit.boiler_data_tbl[id] ---@type boilerv_session_db + local ps = unit.boiler_ps_tbl[id] ---@type psil local rtu_faulted = _record_multiblock_status(boiler, data, ps) @@ -960,8 +973,8 @@ function iocontrol.update_unit_statuses(statuses) for id, turbine in pairs(rtu_statuses.turbines) do if type(unit.turbine_data_tbl[id]) == "table" then - local data = unit.turbine_data_tbl[id] ---@type turbinev_session_db - local ps = unit.turbine_ps_tbl[id] ---@type psil + local data = unit.turbine_data_tbl[id] ---@type turbinev_session_db + local ps = unit.turbine_ps_tbl[id] ---@type psil local rtu_faulted = _record_multiblock_status(turbine, data, ps) @@ -1033,9 +1046,9 @@ function iocontrol.update_unit_statuses(statuses) -- solar neutron activator status info if type(rtu_statuses.sna) == "table" then - unit.num_snas = rtu_statuses.sna[1] ---@type integer - unit.sna_prod_rate = rtu_statuses.sna[2] ---@type number - unit.sna_peak_rate = rtu_statuses.sna[3] ---@type number + unit.num_snas = rtu_statuses.sna[1] ---@type integer + unit.sna_prod_rate = rtu_statuses.sna[2] ---@type number + unit.sna_peak_rate = rtu_statuses.sna[3] ---@type number unit.unit_ps.publish("sna_count", unit.num_snas) unit.unit_ps.publish("sna_prod_rate", unit.sna_prod_rate) @@ -1049,12 +1062,22 @@ function iocontrol.update_unit_statuses(statuses) -- environment detector status if type(rtu_statuses.rad_mon) == "table" then - if #rtu_statuses.rad_mon > 0 then - local rad_mon = rtu_statuses.rad_mon[1] - -- local rtu_faulted = rad_mon[1] ---@type boolean - unit.radiation = rad_mon[2] ---@type number + local max_rad, max_reading = 0, types.new_zero_radiation_reading() - unit.unit_ps.publish("radiation", unit.radiation) + if #rtu_statuses.rad_mon > 0 then + + for id = 1, #rtu_statuses.rad_mon do + local rad_mon = rtu_statuses.rad_mon[id] + local radiation = rad_mon[2] ---@type radiation_reading + local rad_raw = rad_mon[3] ---@type number + + if rad_raw > max_rad then + max_rad = rad_raw + max_reading = radiation + end + end + + unit.radiation = max_reading else unit.radiation = types.new_zero_radiation_reading() end @@ -1062,6 +1085,8 @@ function iocontrol.update_unit_statuses(statuses) log.debug(log_header .. "radiation monitor list not a table") valid = false end + + unit.unit_ps.publish("radiation", unit.radiation) else log.debug(log_header .. "rtu list not a table") valid = false diff --git a/rtu/configure.lua b/rtu/configure.lua index 106724e..0c19800 100644 --- a/rtu/configure.lua +++ b/rtu/configure.lua @@ -87,7 +87,6 @@ local changes = {} local RTU_DEV_TYPES = { "boilerValve", "turbineValve", "dynamicValve", "inductionPort", "spsPort", "solarNeutronActivator", "environmentDetector" } local NEEDS_UNIT = { "boilerValve", "turbineValve", "dynamicValve", "solarNeutronActivator", "environmentDetector" } -local NEEDS_IDX = { "boilerValve", "turbineValve", "dynamicValve" } ---@class rtu_configurator local configurator = {} @@ -732,8 +731,10 @@ local function config_view(display) tool_ctl.p_desc.reposition(1, 8) tool_ctl.p_desc.set_value("Each reactor unit can have at most 1 tank and the facility can have at most 4. Each facility tank must have a unique # 1 through 4, regardless of where it is connected. Only a total of 4 tanks can be displayed on the flow monitor.") elseif type == "environmentDetector" then - tool_ctl.p_idx.hide() - tool_ctl.p_prompt.set_value("This will be an environment detector for...") + tool_ctl.p_prompt.set_value("This is the # environment detector for...") + tool_ctl.p_idx.show() + tool_ctl.p_idx.redraw() + tool_ctl.p_idx.set_max(99) tool_ctl.p_unit.reposition(18, 6) if tool_ctl.p_assign_btn.get_value() == 1 then tool_ctl.p_unit.disable() else tool_ctl.p_unit.enable() end tool_ctl.p_assign_btn.show() @@ -741,12 +742,12 @@ local function config_view(display) tool_ctl.p_assign_end.show() tool_ctl.p_assign_end.redraw() tool_ctl.p_desc.reposition(1, 8) - tool_ctl.p_desc.set_value("You can connect more than one environment detector for a particular unit or the facility, in which case the maximum radiation reading from those assigned to that particular unit or the facility will be used.") + tool_ctl.p_desc.set_value("You can connect more than one environment detector for a particular unit or the facility. In that case, the maximum radiation reading from those assigned to that particular unit or the facility will be used for alarms and display.") elseif type == "inductionPort" or type == "spsPort" then local dev = util.trinary(type == "inductionPort", "induction matrix", "SPS") tool_ctl.p_idx.hide(true) tool_ctl.p_unit.hide(true) - tool_ctl.p_prompt.set_value("This will be the " .. dev .. " for the facility.") + tool_ctl.p_prompt.set_value("This is the " .. dev .. " for the facility.") tool_ctl.p_assign_btn.hide(true) tool_ctl.p_assign_end.hide(true) tool_ctl.p_desc.reposition(1, 7) @@ -815,11 +816,13 @@ local function config_view(display) function tool_ctl.p_assign(opt) if opt == 1 then tool_ctl.p_unit.disable() - tool_ctl.p_idx.enable() + if new_peri_attrs[2] == "dynamicValve" then tool_ctl.p_idx.enable() end else tool_ctl.p_unit.enable() - tool_ctl.p_idx.set_value(1) - tool_ctl.p_idx.disable() + if new_peri_attrs[2] == "dynamicValve" then + tool_ctl.p_idx.set_value(1) + tool_ctl.p_idx.disable() + end end end @@ -879,6 +882,12 @@ local function config_view(display) tool_ctl.p_err.show() return else index = idx end + elseif peri_type == "environmentDetector" then + if not (util.is_int(idx) and idx > 0) then + tool_ctl.p_err.set_value("Index must be greater than 0.") + tool_ctl.p_err.show() + return + else index = idx end end tool_ctl.p_err.hide(true) diff --git a/rtu/startup.lua b/rtu/startup.lua index 6ad5401..2ce87d4 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -284,7 +284,7 @@ local function main() -- CHECK: index range local function validate_index(min, max) - if (util.is_int(index) and index < min) and (max == nil or index > max) then + if (util.is_int(index) and index < min) and (max ~= nil and index > max) then local message = util.c("configure> device entry #", i, ": index ", index, " isn't >= ", min, " and <= ", max) println(message) log.fatal(message) @@ -413,6 +413,7 @@ local function main() rtu_iface, faulted = sna_rtu.new(device) elseif type == "environmentDetector" then -- advanced peripherals environment detector + if not validate_index(1) then return false end if not validate_assign(entry.unit == nil) then return false end rtu_type = RTU_UNIT_TYPE.ENV_DETECTOR diff --git a/rtu/threads.lua b/rtu/threads.lua index 02d809a..2a93638 100644 --- a/rtu/threads.lua +++ b/rtu/threads.lua @@ -121,6 +121,11 @@ local function handle_unit_mount(smem, println_ts, iface, type, device, unit) log.error(util.c("environment detector '", unit.name, "' cannot init, no valid assignment provided in config")) end + if (unit.index == false) or unit.index < 1 then + invalid = true + log.error(util.c("environment detector '", unit.name, "' cannot init, invalid index provided in config")) + end + unit.type = RTU_UNIT_TYPE.ENV_DETECTOR else resend_advert = false diff --git a/supervisor/facility.lua b/supervisor/facility.lua index 28bd6e2..791aabd 100644 --- a/supervisor/facility.lua +++ b/supervisor/facility.lua @@ -232,9 +232,7 @@ function facility.new(num_reactors, cooling_conf) -- link a redstone RTU session ---@param rs_unit unit_session - function public.add_redstone(rs_unit) - table.insert(self.redstone, rs_unit) - end + function public.add_redstone(rs_unit) table.insert(self.redstone, rs_unit) end -- link an induction matrix RTU session ---@param imatrix unit_session @@ -258,23 +256,11 @@ function facility.new(num_reactors, cooling_conf) -- link a dynamic tank RTU session ---@param dynamic_tank unit_session - ---@return boolean linked dynamic tank accepted (max 1) - function public.add_tank(dynamic_tank) - if #self.tanks == 0 then - table.insert(self.tanks, dynamic_tank) - return true - else return false end - end + function public.add_tank(dynamic_tank) table.insert(self.tanks, dynamic_tank) end -- link an environment detector RTU session ---@param envd unit_session - ---@return boolean linked environment detector accepted (max 1) - function public.add_envd(envd) - if #self.envd == 0 then - table.insert(self.envd, envd) - return true - else return false end - end + function public.add_envd(envd) table.insert(self.envd, envd) end -- purge devices associated with the given RTU session ID ---@param session integer RTU session ID @@ -643,11 +629,16 @@ function facility.new(num_reactors, cooling_conf) end -- check for facility radiation - if self.envd[1] ~= nil then - local envd = self.envd[1] ---@type unit_session - local e_db = envd.get_db() ---@type envd_session_db + if #self.envd > 0 then + local max_rad = 0 - astatus.radiation = e_db.radiation_raw > ALARM_LIMS.FAC_HIGH_RAD + for i = 1, #self.envd do + local envd = self.envd[i] ---@type unit_session + local e_db = envd.get_db() ---@type envd_session_db + if e_db.radiation_raw > max_rad then max_rad = e_db.radiation_raw end + end + + astatus.radiation = max_rad > ALARM_LIMS.FAC_HIGH_RAD else -- don't clear, if it is true then we lost it with high radiation, so just keep alarming -- operator can restart the system or hit the stop/reset button @@ -1183,7 +1174,8 @@ function facility.new(num_reactors, cooling_conf) status.rad_mon = {} for i = 1, #self.envd do local envd = self.envd[i] ---@type unit_session - status.rad_mon[i] = { envd.is_faulted(), envd.get_db().radiation } + local db = envd.get_db() ---@type envd_session_db + status.rad_mon[envd.get_device_idx()] = { envd.is_faulted(), db.radiation, db.radiation_raw } end return status diff --git a/supervisor/session/rtu/boilerv.lua b/supervisor/session/rtu/boilerv.lua index 5af6f83..33759f2 100644 --- a/supervisor/session/rtu/boilerv.lua +++ b/supervisor/session/rtu/boilerv.lua @@ -37,9 +37,12 @@ local PERIODICS = { ---@param advert rtu_advertisement RTU advertisement table ---@param out_queue mqueue RTU unit message out queue function boilerv.new(session_id, unit_id, advert, out_queue) - -- type check + -- checks if advert.type ~= RTU_UNIT_TYPE.BOILER_VALVE then - log.error("attempt to instantiate boilerv RTU for type '" .. types.rtu_type_to_string(advert.type) .. "'. this is a bug.") + log.error("attempt to instantiate boilerv RTU for type " .. types.rtu_type_to_string(advert.type)) + return nil + elseif not util.is_int(advert.index) then + log.error("attempt to instantiate boilerv RTU without index") return nil end diff --git a/supervisor/session/rtu/dynamicv.lua b/supervisor/session/rtu/dynamicv.lua index 68cd6e9..b1e5b4a 100644 --- a/supervisor/session/rtu/dynamicv.lua +++ b/supervisor/session/rtu/dynamicv.lua @@ -49,9 +49,12 @@ local PERIODICS = { ---@param advert rtu_advertisement RTU advertisement table ---@param out_queue mqueue RTU unit message out queue function dynamicv.new(session_id, unit_id, advert, out_queue) - -- type check + -- checks if advert.type ~= RTU_UNIT_TYPE.DYNAMIC_VALVE then - log.error("attempt to instantiate dynamicv RTU for type '" .. types.rtu_type_to_string(advert.type) .. "'. this is a bug.") + log.error("attempt to instantiate dynamicv RTU for type " .. types.rtu_type_to_string(advert.type)) + return nil + elseif not util.is_int(advert.index) then + log.error("attempt to instantiate dynamicv RTU without index") return nil end diff --git a/supervisor/session/rtu/envd.lua b/supervisor/session/rtu/envd.lua index cf342b7..8eacf1d 100644 --- a/supervisor/session/rtu/envd.lua +++ b/supervisor/session/rtu/envd.lua @@ -28,13 +28,16 @@ local PERIODICS = { ---@param advert rtu_advertisement ---@param out_queue mqueue function envd.new(session_id, unit_id, advert, out_queue) - -- type check + -- checks if advert.type ~= RTU_UNIT_TYPE.ENV_DETECTOR then - log.error("attempt to instantiate envd RTU for type '" .. types.rtu_type_to_string(advert.type) .. "'. this is a bug.") + log.error("attempt to instantiate envd RTU for type " .. types.rtu_type_to_string(advert.type)) + return nil + elseif not util.is_int(advert.index) then + log.error("attempt to instantiate envd RTU without index") return nil end - local log_tag = util.c("session.rtu(", session_id, ").envd[@", unit_id, "]: ") + local log_tag = util.c("session.rtu(", session_id, ").envd(", advert.index, ")[@", unit_id, "]: ") local self = { session = unit_session.new(session_id, unit_id, advert, out_queue, log_tag, TXN_TAGS), diff --git a/supervisor/session/rtu/imatrix.lua b/supervisor/session/rtu/imatrix.lua index b3c23d8..1bcf286 100644 --- a/supervisor/session/rtu/imatrix.lua +++ b/supervisor/session/rtu/imatrix.lua @@ -37,9 +37,12 @@ local PERIODICS = { ---@param advert rtu_advertisement RTU advertisement table ---@param out_queue mqueue RTU unit message out queue function imatrix.new(session_id, unit_id, advert, out_queue) - -- type check + -- checks if advert.type ~= RTU_UNIT_TYPE.IMATRIX then - log.error("attempt to instantiate imatrix RTU for type '" .. types.rtu_type_to_string(advert.type) .. "'. this is a bug.") + log.error("attempt to instantiate imatrix RTU for type " .. types.rtu_type_to_string(advert.type)) + return nil + elseif not util.is_int(advert.index) then + log.error("attempt to instantiate dynamicv RTU without index") return nil end diff --git a/supervisor/session/rtu/redstone.lua b/supervisor/session/rtu/redstone.lua index f142023..b248902 100644 --- a/supervisor/session/rtu/redstone.lua +++ b/supervisor/session/rtu/redstone.lua @@ -52,7 +52,7 @@ local PERIODICS = { function redstone.new(session_id, unit_id, advert, out_queue) -- type check if advert.type ~= RTU_UNIT_TYPE.REDSTONE then - log.error("attempt to instantiate redstone RTU for type '" .. types.rtu_type_to_string(advert.type) .. "'. this is a bug.") + log.error("attempt to instantiate redstone RTU for type " .. types.rtu_type_to_string(advert.type)) return nil end diff --git a/supervisor/session/rtu/sna.lua b/supervisor/session/rtu/sna.lua index cc5a6fc..39ab1d0 100644 --- a/supervisor/session/rtu/sna.lua +++ b/supervisor/session/rtu/sna.lua @@ -36,7 +36,7 @@ local PERIODICS = { function sna.new(session_id, unit_id, advert, out_queue) -- type check if advert.type ~= RTU_UNIT_TYPE.SNA then - log.error("attempt to instantiate sna RTU for type '" .. types.rtu_type_to_string(advert.type) .. "'. this is a bug.") + log.error("attempt to instantiate sna RTU for type " .. types.rtu_type_to_string(advert.type)) return nil end diff --git a/supervisor/session/rtu/sps.lua b/supervisor/session/rtu/sps.lua index e53a540..3143658 100644 --- a/supervisor/session/rtu/sps.lua +++ b/supervisor/session/rtu/sps.lua @@ -39,7 +39,7 @@ local PERIODICS = { function sps.new(session_id, unit_id, advert, out_queue) -- type check if advert.type ~= RTU_UNIT_TYPE.SPS then - log.error("attempt to instantiate sps RTU for type '" .. types.rtu_type_to_string(advert.type) .. "'. this is a bug.") + log.error("attempt to instantiate sps RTU for type " .. types.rtu_type_to_string(advert.type)) return nil end diff --git a/supervisor/session/rtu/turbinev.lua b/supervisor/session/rtu/turbinev.lua index 1112106..e6c08f5 100644 --- a/supervisor/session/rtu/turbinev.lua +++ b/supervisor/session/rtu/turbinev.lua @@ -49,9 +49,12 @@ local PERIODICS = { ---@param advert rtu_advertisement RTU advertisement table ---@param out_queue mqueue RTU unit message out queue function turbinev.new(session_id, unit_id, advert, out_queue) - -- type check + -- checks if advert.type ~= RTU_UNIT_TYPE.TURBINE_VALVE then - log.error("attempt to instantiate turbinev RTU for type '" .. types.rtu_type_to_string(advert.type) .. "'. this is a bug.") + log.error("attempt to instantiate turbinev RTU for type " .. types.rtu_type_to_string(advert.type)) + return nil + elseif not util.is_int(advert.index) then + log.error("attempt to instantiate turbinev RTU without index") return nil end diff --git a/supervisor/unit.lua b/supervisor/unit.lua index eff23de..999f30b 100644 --- a/supervisor/unit.lua +++ b/supervisor/unit.lua @@ -867,7 +867,8 @@ function unit.new(reactor_id, num_boilers, num_turbines) status.rad_mon = {} for i = 1, #self.envd do local envd = self.envd[i] ---@type unit_session - status.rad_mon[i] = { envd.is_faulted(), envd.get_db().radiation } + local db = envd.get_db() ---@type envd_session_db + status.rad_mon[envd.get_device_idx()] = { envd.is_faulted(), db.radiation, db.radiation_raw } end return status