#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
local types = {}
-- CLASSES --
--#region CLASSES
---@class tank_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 rsio table|nil
--#endregion
-- ALIASES --
---@alias color integer
-- ENUMERATION TYPES --
--#region
--#region ENUMERATION TYPES
---@enum TEMP_SCALE
types.TEMP_SCALE = {
@ -169,6 +170,15 @@ function types.rtu_type_to_string(utype)
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
types.TRI_FAIL = {
OK = 1,
@ -290,8 +300,7 @@ types.ALARM_STATE_NAMES = {
--#endregion
-- STRING TYPES --
--#region
--#region STRING TYPES
---@alias side
---|"top"
@ -405,8 +414,7 @@ types.DUMPING_MODE = {
--#endregion
-- MODBUS --
--#region
--#region MODBUS
-- MODBUS function codes
---@enum MODBUS_FCODE

View File

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

View File

@ -2,6 +2,8 @@
-- RTU ID Check Failure Entry
--
local types = require("scada-common.types")
local style = require("supervisor.panel.style")
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 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)
tag = "BAD INDEX"
elseif fail_code == 2 then
elseif fail_code == types.RTU_ID_FAIL.DUPLICATE then
fg_bg = cpair(colors.black,colors.red)
tag = "DUPLICATE"
end

View File

@ -109,6 +109,7 @@ function pgi.delete_pdg_entry(session_id)
end
-- 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 fail_code integer failure code
---@param msg string description to show the user
@ -130,6 +131,7 @@ function pgi.create_chk_entry(unit, fail_code, msg)
end
-- 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
function pgi.delete_chk_entry(unit)
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 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_DATA = plc.PLC_S_DATA
local PLC_S_CMDS = plc.PLC_S_CMDS
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 = {}
@ -274,19 +275,19 @@ end
---@param unit unit_session RTU session
---@param list table table of RTU sessions
---@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)
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
-- 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)
else
for _, u in ipairs(list) do
if u.get_device_idx() == unit.get_device_idx() then
-- 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)
break
end
@ -294,12 +295,12 @@ function svsessions.check_rtu_id(unit, list, max)
end
-- make sure this won't exceed the maximum allowable devices
if fail_code == 0 and #list >= max then
fail_code, fail_str = 3, "too many of this type"
if fail_code == RTU_ID_FAIL.OK and #list >= max then
fail_code, fail_str = RTU_ID_FAIL.MAX_DEVICES, "too many of this type"
end
-- 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 msg
@ -641,6 +642,7 @@ function svsessions.iterate_all()
-- iterate units
self.facility.update_units()
-- update tracking of bad RTU IDs and missing devices
_update_dev_dbg()
end

View File

@ -15,6 +15,7 @@ local ALARM = types.ALARM
local PRIO = types.ALARM_PRIORITY
local ALARM_STATE = types.ALARM_STATE
local TRI_FAIL = types.TRI_FAIL
local RTU_ID_FAIL = types.RTU_ID_FAIL
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
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_i = plc_session.instance
log.debug(util.c(log_tag, "linked PLC [", plc_session.s_addr, ":", plc_session.r_chan, "]"))
-- reset deltas
_reset_dt(DT_KEYS.ReactorTemp)
_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
function public.add_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
_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
function public.add_turbine(turbine)
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)
log.debug(util.c(log_tag, "linked turbine #", turbine.get_device_idx(), " [", turbine.get_unit_id(), "@", turbine.get_session_id(), "]"))
-- reset deltas
_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, ")"))
end
return fail_code == 0
return ok
end
-- 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
function public.add_boiler(boiler)
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)
log.debug(util.c(log_tag, "linked boiler #", boiler.get_device_idx(), " [", boiler.get_unit_id(), "@", boiler.get_session_id(), "]"))
-- reset deltas
_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, ")"))
end
return fail_code == 0
return ok
end
-- 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)
function public.add_tank(dynamic_tank)
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)
log.debug(util.c(log_tag, "linked dynamic tank [", dynamic_tank.get_unit_id(), "@", dynamic_tank.get_session_id(), "]"))
else
log.warning(util.c(log_tag, "rejected dynamic tank linking due to failure code ", fail_code, " (", fail_str, ")"))
end
return fail_code == 0
return ok
end
-- 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
function public.add_envd(envd)
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)
log.debug(util.c(log_tag, "linked environment detector #", envd.get_device_idx(), " [", envd.get_unit_id(), "@", envd.get_session_id(), "]"))
else
log.warning(util.c(log_tag, "rejected environment detector linking due to failure code ", fail_code, " (", fail_str, ")"))
end
return fail_code == 0
return ok
end
-- purge devices associated with the given RTU session ID