#362 taking max of connected radiation monitors

This commit is contained in:
Mikayla Fischler 2023-11-12 11:54:47 -05:00
parent 1ba178eae8
commit f2f5c3201f
14 changed files with 116 additions and 68 deletions

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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),

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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