From a087eda0eed3aebf48e66c56193cd375a3420f96 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 22 Aug 2024 16:42:57 +0000 Subject: [PATCH] #367 RTU fail enum and logging messages --- scada-common/types.lua | 22 ++++++++++++------ supervisor/facility.lua | 24 +++++++++++++------ supervisor/panel/components/chk_entry.lua | 6 +++-- supervisor/panel/pgi.lua | 2 ++ supervisor/session/svsessions.lua | 26 +++++++++++---------- supervisor/unit.lua | 28 ++++++++++++++++------- 6 files changed, 72 insertions(+), 36 deletions(-) diff --git a/scada-common/types.lua b/scada-common/types.lua index e392f53..c27d2d7 100644 --- a/scada-common/types.lua +++ b/scada-common/types.lua @@ -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 diff --git a/supervisor/facility.lua b/supervisor/facility.lua index 503d454..dcc3171 100644 --- a/supervisor/facility.lua +++ b/supervisor/facility.lua @@ -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 diff --git a/supervisor/panel/components/chk_entry.lua b/supervisor/panel/components/chk_entry.lua index 02ecc21..ff4a24b 100644 --- a/supervisor/panel/components/chk_entry.lua +++ b/supervisor/panel/components/chk_entry.lua @@ -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 diff --git a/supervisor/panel/pgi.lua b/supervisor/panel/pgi.lua index cb3721e..2d8ee93 100644 --- a/supervisor/panel/pgi.lua +++ b/supervisor/panel/pgi.lua @@ -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() diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index ff17bb9..30ef729 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -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 diff --git a/supervisor/unit.lua b/supervisor/unit.lua index 9ee6706..3290af0 100644 --- a/supervisor/unit.lua +++ b/supervisor/unit.lua @@ -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