#367 RTU fail enum and logging messages

This commit is contained in:
Mikayla 2024-08-22 16:42:57 +00:00
parent a1b6ff4bcc
commit a087eda0ee
6 changed files with 72 additions and 36 deletions

View File

@ -5,7 +5,7 @@
---@class types ---@class types
local types = {} local types = {}
-- CLASSES -- --#region CLASSES
---@class tank_fluid ---@class tank_fluid
---@field name fluid ---@field name fluid
@ -67,12 +67,13 @@ function types.new_zero_coordinate() return { x = 0, y = 0, z = 0 } end
---@field reactor integer ---@field reactor integer
---@field rsio table|nil ---@field rsio table|nil
--#endregion
-- ALIASES -- -- ALIASES --
---@alias color integer ---@alias color integer
-- ENUMERATION TYPES -- --#region ENUMERATION TYPES
--#region
---@enum TEMP_SCALE ---@enum TEMP_SCALE
types.TEMP_SCALE = { types.TEMP_SCALE = {
@ -169,6 +170,15 @@ function types.rtu_type_to_string(utype)
end end
end end
---@enum RTU_ID_FAIL
types.RTU_ID_FAIL = {
OK = 0,
OUT_OF_RANGE = 1,
DUPLICATE = 2,
MAX_DEVICES = 3,
MISSING = 4
}
---@enum TRI_FAIL ---@enum TRI_FAIL
types.TRI_FAIL = { types.TRI_FAIL = {
OK = 1, OK = 1,
@ -290,8 +300,7 @@ types.ALARM_STATE_NAMES = {
--#endregion --#endregion
-- STRING TYPES -- --#region STRING TYPES
--#region
---@alias side ---@alias side
---|"top" ---|"top"
@ -405,8 +414,7 @@ types.DUMPING_MODE = {
--#endregion --#endregion
-- MODBUS -- --#region MODBUS
--#region
-- MODBUS function codes -- MODBUS function codes
---@enum MODBUS_FCODE ---@enum MODBUS_FCODE

View File

@ -9,6 +9,7 @@ local rsctl = require("supervisor.session.rsctl")
local svsessions = require("supervisor.session.svsessions") local svsessions = require("supervisor.session.svsessions")
local PROCESS = types.PROCESS local PROCESS = types.PROCESS
local RTU_ID_FAIL = types.RTU_ID_FAIL
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
local WASTE = types.WASTE_PRODUCT local WASTE = types.WASTE_PRODUCT
@ -254,14 +255,16 @@ function facility.new(config)
---@return boolean linked induction matrix accepted (max 1) ---@return boolean linked induction matrix accepted (max 1)
function public.add_imatrix(imatrix) function public.add_imatrix(imatrix)
local fail_code, fail_str = svsessions.check_rtu_id(imatrix, self.induction, 1) local fail_code, fail_str = svsessions.check_rtu_id(imatrix, self.induction, 1)
local ok = fail_code == RTU_ID_FAIL.OK
if fail_code == 0 then if ok then
table.insert(self.induction, imatrix) table.insert(self.induction, imatrix)
log.debug(util.c("FAC: linked induction matrix [", imatrix.get_unit_id(), "@", imatrix.get_session_id(), "]"))
else else
log.warning(util.c("FAC: rejected induction matrix linking due to failure code ", fail_code, " (", fail_str, ")")) log.warning(util.c("FAC: rejected induction matrix linking due to failure code ", fail_code, " (", fail_str, ")"))
end end
return fail_code == 0 return ok
end end
-- link an SPS RTU session -- link an SPS RTU session
@ -269,33 +272,40 @@ function facility.new(config)
---@return boolean linked SPS accepted (max 1) ---@return boolean linked SPS accepted (max 1)
function public.add_sps(sps) function public.add_sps(sps)
local fail_code, fail_str = svsessions.check_rtu_id(sps, self.sps, 1) local fail_code, fail_str = svsessions.check_rtu_id(sps, self.sps, 1)
local ok = fail_code == RTU_ID_FAIL.OK
if fail_code == 0 then if ok then
table.insert(self.sps, sps) table.insert(self.sps, sps)
log.debug(util.c("FAC: linked SPS [", sps.get_unit_id(), "@", sps.get_session_id(), "]"))
else else
log.warning(util.c("FAC: rejected SPS linking due to failure code ", fail_code, " (", fail_str, ")")) log.warning(util.c("FAC: rejected SPS linking due to failure code ", fail_code, " (", fail_str, ")"))
end end
return fail_code == 0 return ok
end end
-- link a dynamic tank RTU session -- link a dynamic tank RTU session
---@param dynamic_tank unit_session ---@param dynamic_tank unit_session
function public.add_tank(dynamic_tank) table.insert(self.tanks, dynamic_tank) end function public.add_tank(dynamic_tank)
table.insert(self.tanks, dynamic_tank)
log.debug(util.c("FAC: linked dynamic tank #", dynamic_tank.get_device_idx(), " [", dynamic_tank.get_unit_id(), "@", dynamic_tank.get_session_id(), "]"))
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 ---@return boolean linked environment detector accepted
function public.add_envd(envd) function public.add_envd(envd)
local fail_code, fail_str = svsessions.check_rtu_id(envd, self.envd, 99) local fail_code, fail_str = svsessions.check_rtu_id(envd, self.envd, 99)
local ok = fail_code == RTU_ID_FAIL.OK
if fail_code == 0 then if ok then
table.insert(self.envd, envd) table.insert(self.envd, envd)
log.debug(util.c("FAC: linked environment detector #", envd.get_device_idx(), " [", envd.get_unit_id(), "@", envd.get_session_id(), "]"))
else else
log.warning(util.c("FAC: rejected environment detector linking due to failure code ", fail_code, " (", fail_str, ")")) log.warning(util.c("FAC: rejected environment detector linking due to failure code ", fail_code, " (", fail_str, ")"))
end end
return fail_code == 0 return ok
end end
-- purge devices associated with the given RTU session ID -- purge devices associated with the given RTU session ID

View File

@ -2,6 +2,8 @@
-- RTU ID Check Failure Entry -- RTU ID Check Failure Entry
-- --
local types = require("scada-common.types")
local style = require("supervisor.panel.style") local style = require("supervisor.panel.style")
local core = require("graphics.core") local core = require("graphics.core")
@ -25,10 +27,10 @@ local function init(parent, msg, fail_code)
local fg_bg = cpair(colors.black,colors.yellow) local fg_bg = cpair(colors.black,colors.yellow)
local tag = "MISSING" local tag = "MISSING"
if fail_code == 1 then if fail_code == types.RTU_ID_FAIL.OUT_OF_RANGE then
fg_bg = cpair(colors.black,colors.orange) fg_bg = cpair(colors.black,colors.orange)
tag = "BAD INDEX" tag = "BAD INDEX"
elseif fail_code == 2 then elseif fail_code == types.RTU_ID_FAIL.DUPLICATE then
fg_bg = cpair(colors.black,colors.red) fg_bg = cpair(colors.black,colors.red)
tag = "DUPLICATE" tag = "DUPLICATE"
end end

View File

@ -109,6 +109,7 @@ function pgi.delete_pdg_entry(session_id)
end end
-- add a device ID check failure entry to the CHK list -- add a device ID check failure entry to the CHK list
---@note this assumes only one type of failure can occur per each RTU gateway session's RTU, which is the case
---@param unit unit_session RTU session ---@param unit unit_session RTU session
---@param fail_code integer failure code ---@param fail_code integer failure code
---@param msg string description to show the user ---@param msg string description to show the user
@ -130,6 +131,7 @@ function pgi.create_chk_entry(unit, fail_code, msg)
end end
-- delete a device ID check failure entry from the CHK list -- delete a device ID check failure entry from the CHK list
---@note this assumes only one type of failure can occur per each RTU gateway session's RTU, which is the case
---@param unit unit_session RTU session ---@param unit unit_session RTU session
function pgi.delete_chk_entry(unit) function pgi.delete_chk_entry(unit)
local gw_session = unit.get_session_id() local gw_session = unit.get_session_id()

View File

@ -17,14 +17,15 @@ local pocket = require("supervisor.session.pocket")
local rtu = require("supervisor.session.rtu") local rtu = require("supervisor.session.rtu")
local svqtypes = require("supervisor.session.svqtypes") local svqtypes = require("supervisor.session.svqtypes")
local RTU_TYPES = types.RTU_UNIT_TYPE local RTU_ID_FAIL = types.RTU_ID_FAIL
local RTU_TYPES = types.RTU_UNIT_TYPE
local SV_Q_DATA = svqtypes.SV_Q_DATA local SV_Q_DATA = svqtypes.SV_Q_DATA
local PLC_S_CMDS = plc.PLC_S_CMDS local PLC_S_CMDS = plc.PLC_S_CMDS
local PLC_S_DATA = plc.PLC_S_DATA local PLC_S_DATA = plc.PLC_S_DATA
local CRD_S_DATA = coordinator.CRD_S_DATA local CRD_S_DATA = coordinator.CRD_S_DATA
local svsessions = {} local svsessions = {}
@ -274,19 +275,19 @@ end
---@param unit unit_session RTU session ---@param unit unit_session RTU session
---@param list table table of RTU sessions ---@param list table table of RTU sessions
---@param max integer max of this type of RTU ---@param max integer max of this type of RTU
---@return 0|1|2|3 fail_code, string fail_str 0 = success, 1 = out-of-range, 2 = duplicate, 3 = exceeded table max ---@return RTU_ID_FAIL fail_code, string fail_str
function svsessions.check_rtu_id(unit, list, max) function svsessions.check_rtu_id(unit, list, max)
local fail_code, fail_str = 0, "OK" local fail_code, fail_str = RTU_ID_FAIL.OK, "OK"
if (unit.get_device_idx() < 1 and max ~= 1) or unit.get_device_idx() > max then if (unit.get_device_idx() < 1 and max ~= 1) or unit.get_device_idx() > max then
-- out-of-range -- out-of-range
fail_code, fail_str = 1, "index out of range" fail_code, fail_str = RTU_ID_FAIL.OUT_OF_RANGE, "index out of range"
table.insert(self.dev_dbg.out_of_range, unit) table.insert(self.dev_dbg.out_of_range, unit)
else else
for _, u in ipairs(list) do for _, u in ipairs(list) do
if u.get_device_idx() == unit.get_device_idx() then if u.get_device_idx() == unit.get_device_idx() then
-- duplicate -- duplicate
fail_code, fail_str = 2, "duplicate index" fail_code, fail_str = RTU_ID_FAIL.DUPLICATE, "duplicate index"
table.insert(self.dev_dbg.duplicate, unit) table.insert(self.dev_dbg.duplicate, unit)
break break
end end
@ -294,12 +295,12 @@ function svsessions.check_rtu_id(unit, list, max)
end end
-- make sure this won't exceed the maximum allowable devices -- make sure this won't exceed the maximum allowable devices
if fail_code == 0 and #list >= max then if fail_code == RTU_ID_FAIL.OK and #list >= max then
fail_code, fail_str = 3, "too many of this type" fail_code, fail_str = RTU_ID_FAIL.MAX_DEVICES, "too many of this type"
end end
-- add to the list for the user -- add to the list for the user
if fail_code > 0 and fail_code ~= 3 then if fail_code ~= RTU_ID_FAIL.OK and fail_code ~= RTU_ID_FAIL.MAX_DEVICES then
local r_id, idx, type = unit.get_reactor(), unit.get_device_idx(), unit.get_unit_type() local r_id, idx, type = unit.get_reactor(), unit.get_device_idx(), unit.get_unit_type()
local msg local msg
@ -641,6 +642,7 @@ function svsessions.iterate_all()
-- iterate units -- iterate units
self.facility.update_units() self.facility.update_units()
-- update tracking of bad RTU IDs and missing devices
_update_dev_dbg() _update_dev_dbg()
end end

View File

@ -15,6 +15,7 @@ local ALARM = types.ALARM
local PRIO = types.ALARM_PRIORITY local PRIO = types.ALARM_PRIORITY
local ALARM_STATE = types.ALARM_STATE local ALARM_STATE = types.ALARM_STATE
local TRI_FAIL = types.TRI_FAIL local TRI_FAIL = types.TRI_FAIL
local RTU_ID_FAIL = types.RTU_ID_FAIL
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
local PLC_S_CMDS = plc.PLC_S_CMDS local PLC_S_CMDS = plc.PLC_S_CMDS
@ -423,6 +424,8 @@ function unit.new(reactor_id, num_boilers, num_turbines, ext_idle)
self.plc_s = plc_session self.plc_s = plc_session
self.plc_i = plc_session.instance self.plc_i = plc_session.instance
log.debug(util.c(log_tag, "linked PLC [", plc_session.s_addr, ":", plc_session.r_chan, "]"))
-- reset deltas -- reset deltas
_reset_dt(DT_KEYS.ReactorTemp) _reset_dt(DT_KEYS.ReactorTemp)
_reset_dt(DT_KEYS.ReactorFuel) _reset_dt(DT_KEYS.ReactorFuel)
@ -435,6 +438,7 @@ function unit.new(reactor_id, num_boilers, num_turbines, ext_idle)
---@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) table.insert(self.redstone, rs_unit)
log.debug(util.c(log_tag, "linked redstone [", rs_unit.get_unit_id(), "@", rs_unit.get_session_id(), "]"))
-- send or re-send waste settings -- send or re-send waste settings
_set_waste_valves(self.waste_product) _set_waste_valves(self.waste_product)
@ -445,9 +449,11 @@ function unit.new(reactor_id, num_boilers, num_turbines, ext_idle)
---@return boolean linked turbine accepted to associated device slot ---@return boolean linked turbine accepted to associated device slot
function public.add_turbine(turbine) function public.add_turbine(turbine)
local fail_code, fail_str = svsessions.check_rtu_id(turbine, self.turbines, num_turbines) local fail_code, fail_str = svsessions.check_rtu_id(turbine, self.turbines, num_turbines)
local ok = fail_code == RTU_ID_FAIL.OK
if fail_code == 0 then if ok then
table.insert(self.turbines, turbine) table.insert(self.turbines, turbine)
log.debug(util.c(log_tag, "linked turbine #", turbine.get_device_idx(), " [", turbine.get_unit_id(), "@", turbine.get_session_id(), "]"))
-- reset deltas -- reset deltas
_reset_dt(DT_KEYS.TurbineSteam .. turbine.get_device_idx()) _reset_dt(DT_KEYS.TurbineSteam .. turbine.get_device_idx())
@ -456,7 +462,7 @@ function unit.new(reactor_id, num_boilers, num_turbines, ext_idle)
log.warning(util.c(log_tag, "rejected turbine linking due to failure code ", fail_code, " (", fail_str, ")")) log.warning(util.c(log_tag, "rejected turbine linking due to failure code ", fail_code, " (", fail_str, ")"))
end end
return fail_code == 0 return ok
end end
-- link a boiler RTU session -- link a boiler RTU session
@ -464,9 +470,11 @@ function unit.new(reactor_id, num_boilers, num_turbines, ext_idle)
---@return boolean linked boiler accepted to associated device slot ---@return boolean linked boiler accepted to associated device slot
function public.add_boiler(boiler) function public.add_boiler(boiler)
local fail_code, fail_str = svsessions.check_rtu_id(boiler, self.boilers, num_boilers) local fail_code, fail_str = svsessions.check_rtu_id(boiler, self.boilers, num_boilers)
local ok = fail_code == RTU_ID_FAIL.OK
if fail_code == 0 then if ok then
table.insert(self.boilers, boiler) table.insert(self.boilers, boiler)
log.debug(util.c(log_tag, "linked boiler #", boiler.get_device_idx(), " [", boiler.get_unit_id(), "@", boiler.get_session_id(), "]"))
-- reset deltas -- reset deltas
_reset_dt(DT_KEYS.BoilerWater .. boiler.get_device_idx()) _reset_dt(DT_KEYS.BoilerWater .. boiler.get_device_idx())
@ -477,7 +485,7 @@ function unit.new(reactor_id, num_boilers, num_turbines, ext_idle)
log.warning(util.c(log_tag, "rejected boiler linking due to failure code ", fail_code, " (", fail_str, ")")) log.warning(util.c(log_tag, "rejected boiler linking due to failure code ", fail_code, " (", fail_str, ")"))
end end
return fail_code == 0 return ok
end end
-- link a dynamic tank RTU session -- link a dynamic tank RTU session
@ -485,14 +493,16 @@ function unit.new(reactor_id, num_boilers, num_turbines, ext_idle)
---@return boolean linked dynamic tank accepted (max 1) ---@return boolean linked dynamic tank accepted (max 1)
function public.add_tank(dynamic_tank) function public.add_tank(dynamic_tank)
local fail_code, fail_str = svsessions.check_rtu_id(dynamic_tank, self.tanks, 1) local fail_code, fail_str = svsessions.check_rtu_id(dynamic_tank, self.tanks, 1)
local ok = fail_code == RTU_ID_FAIL.OK
if fail_code == 0 then if ok then
table.insert(self.tanks, dynamic_tank) table.insert(self.tanks, dynamic_tank)
log.debug(util.c(log_tag, "linked dynamic tank [", dynamic_tank.get_unit_id(), "@", dynamic_tank.get_session_id(), "]"))
else else
log.warning(util.c(log_tag, "rejected dynamic tank linking due to failure code ", fail_code, " (", fail_str, ")")) log.warning(util.c(log_tag, "rejected dynamic tank linking due to failure code ", fail_code, " (", fail_str, ")"))
end end
return fail_code == 0 return ok
end end
-- link a solar neutron activator RTU session -- link a solar neutron activator RTU session
@ -504,14 +514,16 @@ function unit.new(reactor_id, num_boilers, num_turbines, ext_idle)
---@return boolean linked environment detector accepted ---@return boolean linked environment detector accepted
function public.add_envd(envd) function public.add_envd(envd)
local fail_code, fail_str = svsessions.check_rtu_id(envd, self.envd, 99) local fail_code, fail_str = svsessions.check_rtu_id(envd, self.envd, 99)
local ok = fail_code == RTU_ID_FAIL.OK
if fail_code == 0 then if ok then
table.insert(self.envd, envd) table.insert(self.envd, envd)
log.debug(util.c(log_tag, "linked environment detector #", envd.get_device_idx(), " [", envd.get_unit_id(), "@", envd.get_session_id(), "]"))
else else
log.warning(util.c(log_tag, "rejected environment detector linking due to failure code ", fail_code, " (", fail_str, ")")) log.warning(util.c(log_tag, "rejected environment detector linking due to failure code ", fail_code, " (", fail_str, ")"))
end end
return fail_code == 0 return ok
end end
-- purge devices associated with the given RTU session ID -- purge devices associated with the given RTU session ID