#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

@ -762,12 +762,23 @@ function iocontrol.update_facility_status(status)
-- environment detector status -- environment detector status
if type(rtu_statuses.rad_mon) == "table" then if type(rtu_statuses.rad_mon) == "table" then
if #rtu_statuses.rad_mon > 0 then if #rtu_statuses.rad_mon > 0 then
local rad_mon = rtu_statuses.rad_mon[1] local max_rad, max_reading, any_faulted = 0, types.new_zero_radiation_reading(), false
local rtu_faulted = rad_mon[1] ---@type boolean
fac.radiation = rad_mon[2] ---@type number
fac.ps.publish("rad_computed_status", util.trinary(rtu_faulted, 2, 3)) for i = 1, #rtu_statuses.rad_mon do
fac.ps.publish("radiation", fac.radiation) 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 else
fac.radiation = types.new_zero_radiation_reading() fac.radiation = types.new_zero_radiation_reading()
fac.ps.publish("rad_computed_status", 1) 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") log.debug(log_header .. "radiation monitor list not a table")
valid = false valid = false
end end
fac.ps.publish("radiation", fac.radiation)
else else
log.debug(log_header .. "rtu statuses not a table") log.debug(log_header .. "rtu statuses not a table")
valid = false valid = false
@ -1049,12 +1062,22 @@ function iocontrol.update_unit_statuses(statuses)
-- environment detector status -- environment detector status
if type(rtu_statuses.rad_mon) == "table" then if type(rtu_statuses.rad_mon) == "table" then
if #rtu_statuses.rad_mon > 0 then local max_rad, max_reading = 0, types.new_zero_radiation_reading()
local rad_mon = rtu_statuses.rad_mon[1]
-- local rtu_faulted = rad_mon[1] ---@type boolean
unit.radiation = rad_mon[2] ---@type number
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 else
unit.radiation = types.new_zero_radiation_reading() unit.radiation = types.new_zero_radiation_reading()
end end
@ -1062,6 +1085,8 @@ function iocontrol.update_unit_statuses(statuses)
log.debug(log_header .. "radiation monitor list not a table") log.debug(log_header .. "radiation monitor list not a table")
valid = false valid = false
end end
unit.unit_ps.publish("radiation", unit.radiation)
else else
log.debug(log_header .. "rtu list not a table") log.debug(log_header .. "rtu list not a table")
valid = false valid = false

View File

@ -87,7 +87,6 @@ local changes = {}
local RTU_DEV_TYPES = { "boilerValve", "turbineValve", "dynamicValve", "inductionPort", "spsPort", "solarNeutronActivator", "environmentDetector" } local RTU_DEV_TYPES = { "boilerValve", "turbineValve", "dynamicValve", "inductionPort", "spsPort", "solarNeutronActivator", "environmentDetector" }
local NEEDS_UNIT = { "boilerValve", "turbineValve", "dynamicValve", "solarNeutronActivator", "environmentDetector" } local NEEDS_UNIT = { "boilerValve", "turbineValve", "dynamicValve", "solarNeutronActivator", "environmentDetector" }
local NEEDS_IDX = { "boilerValve", "turbineValve", "dynamicValve" }
---@class rtu_configurator ---@class rtu_configurator
local configurator = {} local configurator = {}
@ -732,8 +731,10 @@ local function config_view(display)
tool_ctl.p_desc.reposition(1, 8) 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.") 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 elseif type == "environmentDetector" then
tool_ctl.p_idx.hide() tool_ctl.p_prompt.set_value("This is the # environment detector for...")
tool_ctl.p_prompt.set_value("This will be an 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) 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 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() 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.show()
tool_ctl.p_assign_end.redraw() tool_ctl.p_assign_end.redraw()
tool_ctl.p_desc.reposition(1, 8) 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 elseif type == "inductionPort" or type == "spsPort" then
local dev = util.trinary(type == "inductionPort", "induction matrix", "SPS") local dev = util.trinary(type == "inductionPort", "induction matrix", "SPS")
tool_ctl.p_idx.hide(true) tool_ctl.p_idx.hide(true)
tool_ctl.p_unit.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_btn.hide(true)
tool_ctl.p_assign_end.hide(true) tool_ctl.p_assign_end.hide(true)
tool_ctl.p_desc.reposition(1, 7) tool_ctl.p_desc.reposition(1, 7)
@ -815,13 +816,15 @@ local function config_view(display)
function tool_ctl.p_assign(opt) function tool_ctl.p_assign(opt)
if opt == 1 then if opt == 1 then
tool_ctl.p_unit.disable() tool_ctl.p_unit.disable()
tool_ctl.p_idx.enable() if new_peri_attrs[2] == "dynamicValve" then tool_ctl.p_idx.enable() end
else else
tool_ctl.p_unit.enable() tool_ctl.p_unit.enable()
if new_peri_attrs[2] == "dynamicValve" then
tool_ctl.p_idx.set_value(1) tool_ctl.p_idx.set_value(1)
tool_ctl.p_idx.disable() tool_ctl.p_idx.disable()
end end
end end
end
tool_ctl.p_desc = TextBox{parent=peri_c_4,x=1,y=7,height=6,text_align=LEFT,text="",fg_bg=g_lg_fg_bg} tool_ctl.p_desc = TextBox{parent=peri_c_4,x=1,y=7,height=6,text_align=LEFT,text="",fg_bg=g_lg_fg_bg}
tool_ctl.p_desc_ext = TextBox{parent=peri_c_4,x=1,y=6,height=7,text_align=LEFT,text="",fg_bg=g_lg_fg_bg} tool_ctl.p_desc_ext = TextBox{parent=peri_c_4,x=1,y=6,height=7,text_align=LEFT,text="",fg_bg=g_lg_fg_bg}
@ -879,6 +882,12 @@ local function config_view(display)
tool_ctl.p_err.show() tool_ctl.p_err.show()
return return
else index = idx end 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 end
tool_ctl.p_err.hide(true) tool_ctl.p_err.hide(true)

View File

@ -284,7 +284,7 @@ local function main()
-- CHECK: index range -- CHECK: index range
local function validate_index(min, max) 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) local message = util.c("configure> device entry #", i, ": index ", index, " isn't >= ", min, " and <= ", max)
println(message) println(message)
log.fatal(message) log.fatal(message)
@ -413,6 +413,7 @@ local function main()
rtu_iface, faulted = sna_rtu.new(device) rtu_iface, faulted = sna_rtu.new(device)
elseif type == "environmentDetector" then elseif type == "environmentDetector" then
-- advanced peripherals environment detector -- advanced peripherals environment detector
if not validate_index(1) then return false end
if not validate_assign(entry.unit == nil) then return false end if not validate_assign(entry.unit == nil) then return false end
rtu_type = RTU_UNIT_TYPE.ENV_DETECTOR 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")) log.error(util.c("environment detector '", unit.name, "' cannot init, no valid assignment provided in config"))
end 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 unit.type = RTU_UNIT_TYPE.ENV_DETECTOR
else else
resend_advert = false resend_advert = false

View File

@ -232,9 +232,7 @@ function facility.new(num_reactors, cooling_conf)
-- link a redstone RTU session -- link a redstone RTU session
---@param rs_unit unit_session ---@param rs_unit unit_session
function public.add_redstone(rs_unit) function public.add_redstone(rs_unit) table.insert(self.redstone, rs_unit) end
table.insert(self.redstone, rs_unit)
end
-- link an induction matrix RTU session -- link an induction matrix RTU session
---@param imatrix unit_session ---@param imatrix unit_session
@ -258,23 +256,11 @@ function facility.new(num_reactors, cooling_conf)
-- link a dynamic tank RTU session -- link a dynamic tank RTU session
---@param dynamic_tank unit_session ---@param dynamic_tank unit_session
---@return boolean linked dynamic tank accepted (max 1) function public.add_tank(dynamic_tank) table.insert(self.tanks, dynamic_tank) end
function public.add_tank(dynamic_tank)
if #self.tanks == 0 then
table.insert(self.tanks, dynamic_tank)
return true
else return false end
end
-- link an environment detector RTU session -- link an environment detector RTU session
---@param envd unit_session ---@param envd unit_session
---@return boolean linked environment detector accepted (max 1) function public.add_envd(envd) table.insert(self.envd, envd) end
function public.add_envd(envd)
if #self.envd == 0 then
table.insert(self.envd, envd)
return true
else return false end
end
-- purge devices associated with the given RTU session ID -- purge devices associated with the given RTU session ID
---@param session integer RTU session ID ---@param session integer RTU session ID
@ -643,11 +629,16 @@ function facility.new(num_reactors, cooling_conf)
end end
-- check for facility radiation -- check for facility radiation
if self.envd[1] ~= nil then if #self.envd > 0 then
local envd = self.envd[1] ---@type unit_session local max_rad = 0
local e_db = envd.get_db() ---@type envd_session_db
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 else
-- don't clear, if it is true then we lost it with high radiation, so just keep alarming -- 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 -- 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 = {} status.rad_mon = {}
for i = 1, #self.envd do for i = 1, #self.envd do
local envd = self.envd[i] ---@type unit_session 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 end
return status return status

View File

@ -37,9 +37,12 @@ local PERIODICS = {
---@param advert rtu_advertisement RTU advertisement table ---@param advert rtu_advertisement RTU advertisement table
---@param out_queue mqueue RTU unit message out queue ---@param out_queue mqueue RTU unit message out queue
function boilerv.new(session_id, unit_id, advert, out_queue) function boilerv.new(session_id, unit_id, advert, out_queue)
-- type check -- checks
if advert.type ~= RTU_UNIT_TYPE.BOILER_VALVE then 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 return nil
end end

View File

@ -49,9 +49,12 @@ local PERIODICS = {
---@param advert rtu_advertisement RTU advertisement table ---@param advert rtu_advertisement RTU advertisement table
---@param out_queue mqueue RTU unit message out queue ---@param out_queue mqueue RTU unit message out queue
function dynamicv.new(session_id, unit_id, advert, out_queue) function dynamicv.new(session_id, unit_id, advert, out_queue)
-- type check -- checks
if advert.type ~= RTU_UNIT_TYPE.DYNAMIC_VALVE then 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 return nil
end end

View File

@ -28,13 +28,16 @@ local PERIODICS = {
---@param advert rtu_advertisement ---@param advert rtu_advertisement
---@param out_queue mqueue ---@param out_queue mqueue
function envd.new(session_id, unit_id, advert, out_queue) function envd.new(session_id, unit_id, advert, out_queue)
-- type check -- checks
if advert.type ~= RTU_UNIT_TYPE.ENV_DETECTOR then 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 return nil
end 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 = { local self = {
session = unit_session.new(session_id, unit_id, advert, out_queue, log_tag, TXN_TAGS), 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 advert rtu_advertisement RTU advertisement table
---@param out_queue mqueue RTU unit message out queue ---@param out_queue mqueue RTU unit message out queue
function imatrix.new(session_id, unit_id, advert, out_queue) function imatrix.new(session_id, unit_id, advert, out_queue)
-- type check -- checks
if advert.type ~= RTU_UNIT_TYPE.IMATRIX then 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 return nil
end end

View File

@ -52,7 +52,7 @@ local PERIODICS = {
function redstone.new(session_id, unit_id, advert, out_queue) function redstone.new(session_id, unit_id, advert, out_queue)
-- type check -- type check
if advert.type ~= RTU_UNIT_TYPE.REDSTONE then 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 return nil
end end

View File

@ -36,7 +36,7 @@ local PERIODICS = {
function sna.new(session_id, unit_id, advert, out_queue) function sna.new(session_id, unit_id, advert, out_queue)
-- type check -- type check
if advert.type ~= RTU_UNIT_TYPE.SNA then 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 return nil
end end

View File

@ -39,7 +39,7 @@ local PERIODICS = {
function sps.new(session_id, unit_id, advert, out_queue) function sps.new(session_id, unit_id, advert, out_queue)
-- type check -- type check
if advert.type ~= RTU_UNIT_TYPE.SPS then 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 return nil
end end

View File

@ -49,9 +49,12 @@ local PERIODICS = {
---@param advert rtu_advertisement RTU advertisement table ---@param advert rtu_advertisement RTU advertisement table
---@param out_queue mqueue RTU unit message out queue ---@param out_queue mqueue RTU unit message out queue
function turbinev.new(session_id, unit_id, advert, out_queue) function turbinev.new(session_id, unit_id, advert, out_queue)
-- type check -- checks
if advert.type ~= RTU_UNIT_TYPE.TURBINE_VALVE then 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 return nil
end end

View File

@ -867,7 +867,8 @@ function unit.new(reactor_id, num_boilers, num_turbines)
status.rad_mon = {} status.rad_mon = {}
for i = 1, #self.envd do for i = 1, #self.envd do
local envd = self.envd[i] ---@type unit_session 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 end
return status return status