From f34747372fc170d41accc0bb63140da916ab1fcb Mon Sep 17 00:00:00 2001 From: Mikayla Date: Fri, 16 Aug 2024 21:19:25 +0000 Subject: [PATCH] #367 work on device ID check failure list --- supervisor/panel/components/chk_entry.lua | 41 +++++++++++ supervisor/panel/front_panel.lua | 24 ++++--- supervisor/panel/pgi.lua | 84 +++++++++++++++++++---- supervisor/session/svsessions.lua | 23 +++++-- 4 files changed, 143 insertions(+), 29 deletions(-) create mode 100644 supervisor/panel/components/chk_entry.lua diff --git a/supervisor/panel/components/chk_entry.lua b/supervisor/panel/components/chk_entry.lua new file mode 100644 index 0000000..5fa6d3b --- /dev/null +++ b/supervisor/panel/components/chk_entry.lua @@ -0,0 +1,41 @@ +-- +-- RTU ID Check Failure Entry +-- + +local databus = require("supervisor.databus") + +local style = require("supervisor.panel.style") + +local core = require("graphics.core") + +local Div = require("graphics.elements.div") +local TextBox = require("graphics.elements.textbox") + +local ALIGN = core.ALIGN + +local cpair = core.cpair + +-- create an ID check list entry +---@param parent graphics_element parent +---@param unit unit_session RTU session +---@param fail_code integer failure code +local function init(parent, unit, fail_code) + local s_hi_box = style.theme.highlight_box + + local label_fg = style.fp.label_fg + + -- root div + local root = Div{parent=parent,x=2,y=2,height=4,width=parent.get_width()-2,hidden=true} + local entry = Div{parent=root,x=2,y=1,height=3,fg_bg=style.theme.highlight_box_bright} + + TextBox{parent=entry,x=1,y=1,text="",width=8,fg_bg=s_hi_box} + local rtu_addr = TextBox{parent=entry,x=1,y=2,text="@ C ??",alignment=ALIGN.CENTER,width=8,fg_bg=s_hi_box,nav_active=cpair(colors.gray,colors.black)} + TextBox{parent=entry,x=1,y=3,text="",width=8,fg_bg=s_hi_box} + + TextBox{parent=entry,x=21,y=2,text="FW:",width=3} + local rtu_fw_v = TextBox{parent=entry,x=25,y=2,text=" ------- ",width=9,fg_bg=label_fg} + + return root +end + +return init diff --git a/supervisor/panel/front_panel.lua b/supervisor/panel/front_panel.lua index 5f042b0..d3428aa 100644 --- a/supervisor/panel/front_panel.lua +++ b/supervisor/panel/front_panel.lua @@ -10,6 +10,7 @@ local supervisor = require("supervisor.supervisor") local pgi = require("supervisor.panel.pgi") local style = require("supervisor.panel.style") +local chk_entry = require("supervisor.panel.components.chk_entry") local pdg_entry = require("supervisor.panel.components.pdg_entry") local rtu_entry = require("supervisor.panel.components.rtu_entry") @@ -83,7 +84,7 @@ local function init(panel) -- page handling -- - -- plc page + -- plc sessions page local plc_page = Div{parent=page_div,x=1,y=1,hidden=true} local plc_list = Div{parent=plc_page,x=2,y=2,width=49} @@ -115,13 +116,13 @@ local function init(panel) plc_list.line_break() end - -- rtu page + -- rtu sessions page local rtu_page = Div{parent=page_div,x=1,y=1,hidden=true} local rtu_list = ListBox{parent=rtu_page,x=1,y=1,height=17,width=51,scroll_height=1000,fg_bg=cpair(colors.black,colors.ivory),nav_fg_bg=cpair(colors.gray,colors.lightGray),nav_active=cpair(colors.black,colors.gray)} local _ = Div{parent=rtu_list,height=1,hidden=true} -- padding - -- coordinator page + -- coordinator session page local crd_page = Div{parent=page_div,x=1,y=1,hidden=true} local crd_box = Div{parent=crd_page,x=2,y=2,width=49,height=4,fg_bg=s_hi_bright} @@ -143,15 +144,21 @@ local function init(panel) crd_rtt.register(databus.ps, "crd_rtt", crd_rtt.update) crd_rtt.register(databus.ps, "crd_rtt_color", crd_rtt.recolor) - -- pocket diagnostics page + -- pocket sessions page local pkt_page = Div{parent=page_div,x=1,y=1,hidden=true} local pdg_list = ListBox{parent=pkt_page,x=1,y=1,height=17,width=51,scroll_height=1000,fg_bg=style.fp.text_fg,nav_fg_bg=cpair(colors.gray,colors.lightGray),nav_active=cpair(colors.black,colors.gray)} local _ = Div{parent=pdg_list,height=1,hidden=true} -- padding + -- RTU device ID check/diagnostics page + + local chk_page = Div{parent=page_div,x=1,y=1,hidden=true} + local chk_list = ListBox{parent=chk_page,x=1,y=1,height=17,width=51,scroll_height=1000,fg_bg=style.fp.text_fg,nav_fg_bg=cpair(colors.gray,colors.lightGray),nav_active=cpair(colors.black,colors.gray)} + local _ = Div{parent=chk_list,height=1,hidden=true} -- padding + -- assemble page panes - local panes = { main_page, plc_page, rtu_page, crd_page, pkt_page } + local panes = { main_page, plc_page, rtu_page, crd_page, pkt_page, chk_page } local page_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes} @@ -161,12 +168,13 @@ local function init(panel) { name = "RTU", color = style.fp.text }, { name = "CRD", color = style.fp.text }, { name = "PKT", color = style.fp.text }, + { name = "CHECK", color = style.fp.text } } - TabBar{parent=panel,y=2,tabs=tabs,min_width=9,callback=page_pane.set_value,fg_bg=style.theme.highlight_box_bright} + TabBar{parent=panel,y=2,tabs=tabs,min_width=7,callback=page_pane.set_value,fg_bg=style.theme.highlight_box_bright} - -- link RTU/PDG list management to PGI - pgi.link_elements(rtu_list, rtu_entry, pdg_list, pdg_entry) + -- link RTU/PDG/CHK list management to PGI + pgi.link_elements(rtu_list, rtu_entry, pdg_list, pdg_entry, chk_list, chk_entry) end return init diff --git a/supervisor/panel/pgi.lua b/supervisor/panel/pgi.lua index dd8b202..1e46fee 100644 --- a/supervisor/panel/pgi.lua +++ b/supervisor/panel/pgi.lua @@ -10,10 +10,12 @@ local pgi = {} local data = { rtu_list = nil, ---@type nil|graphics_element pdg_list = nil, ---@type nil|graphics_element + chk_list = nil, ---@type nil|graphics_element rtu_entry = nil, ---@type function pdg_entry = nil, ---@type function - -- session entries - s_entries = { rtu = {}, pdg = {} } + chk_entry = nil, ---@type function + -- list entries + entries = { rtu = {}, pdg = {}, chk = {} } } -- link list boxes @@ -21,19 +23,25 @@ local data = { ---@param rtu_entry function RTU entry constructor ---@param pdg_list graphics_element pocket diagnostics list element ---@param pdg_entry function pocket diagnostics entry constructor -function pgi.link_elements(rtu_list, rtu_entry, pdg_list, pdg_entry) +---@param chk_list graphics_element CHK list element +---@param chk_entry function CHK entry constructor +function pgi.link_elements(rtu_list, rtu_entry, pdg_list, pdg_entry, chk_list, chk_entry) data.rtu_list = rtu_list data.pdg_list = pdg_list + data.chk_list = chk_list data.rtu_entry = rtu_entry data.pdg_entry = pdg_entry + data.chk_entry = chk_entry end -- unlink all fields, disabling the PGI function pgi.unlink() data.rtu_list = nil data.pdg_list = nil + data.chk_list = nil data.rtu_entry = nil data.pdg_entry = nil + data.chk_entry = nil end -- add an RTU entry to the RTU list @@ -43,7 +51,8 @@ function pgi.create_rtu_entry(session_id) local success, result = pcall(data.rtu_entry, data.rtu_list, session_id) if success then - data.s_entries.rtu[session_id] = result + data.entries.rtu[session_id] = result + log.debug(util.c("PGI: created RTU entry (", session_id, ")")) else log.error(util.c("PGI: failed to create RTU entry (", result, ")"), true) end @@ -53,15 +62,17 @@ end -- delete an RTU entry from the RTU list ---@param session_id integer RTU session function pgi.delete_rtu_entry(session_id) - if data.s_entries.rtu[session_id] ~= nil then - local success, result = pcall(data.s_entries.rtu[session_id].delete) - data.s_entries.rtu[session_id] = nil + if data.entries.rtu[session_id] ~= nil then + local success, result = pcall(data.entries.rtu[session_id].delete) + data.entries.rtu[session_id] = nil - if not success then + if success then + log.debug(util.c("PGI: deleted RTU entry (", session_id, ")")) + else log.error(util.c("PGI: failed to delete RTU entry (", result, ")"), true) end else - log.debug(util.c("PGI: tried to delete unknown RTU entry ", session_id)) + log.warning(util.c("PGI: tried to delete unknown RTU entry ", session_id)) end end @@ -72,7 +83,8 @@ function pgi.create_pdg_entry(session_id) local success, result = pcall(data.pdg_entry, data.pdg_list, session_id) if success then - data.s_entries.pdg[session_id] = result + data.entries.pdg[session_id] = result + log.debug(util.c("PGI: created PDG entry (", session_id, ")")) else log.error(util.c("PGI: failed to create PDG entry (", result, ")"), true) end @@ -82,15 +94,57 @@ end -- delete a PDG entry from the PDG list ---@param session_id integer pocket diagnostics session function pgi.delete_pdg_entry(session_id) - if data.s_entries.pdg[session_id] ~= nil then - local success, result = pcall(data.s_entries.pdg[session_id].delete) - data.s_entries.pdg[session_id] = nil + if data.entries.pdg[session_id] ~= nil then + local success, result = pcall(data.entries.pdg[session_id].delete) + data.entries.pdg[session_id] = nil - if not success then + if success then + log.debug(util.c("PGI: deleted PDG entry (", session_id, ")")) + else log.error(util.c("PGI: failed to delete PDG entry (", result, ")"), true) end else - log.debug(util.c("PGI: tried to delete unknown PDG entry ", session_id)) + log.warning(util.c("PGI: tried to delete unknown PDG entry ", session_id)) + end +end + +-- add a device ID check failure entry to the CHK list +---@param unit unit_session RTU session +---@param fail_code integer failure code +function pgi.create_chk_entry(unit, fail_code) + local gw_session = unit.get_session_id() + + if data.chk_list ~= nil and data.chk_entry ~= nil then + if not data.entries.chk[gw_session] then data.entries.chk[gw_session] = {} end + + local success, result = pcall(data.chk_entry, data.chk_list, unit, fail_code) + + if success then + data.entries.chk[gw_session][unit.get_unit_id()] = result + log.debug(util.c("PGI: created CHK entry (", gw_session, ":", unit.get_unit_id(), ")")) + else + log.error(util.c("PGI: failed to create CHK entry (", result, ")"), true) + end + end +end + +-- delete a device ID check failure entry from the CHK list +---@param unit unit_session RTU session +function pgi.delete_chk_entry(unit) + local gw_session = unit.get_session_id() + local ent_chk = data.entries.chk + + if ent_chk[gw_session] ~= nil and ent_chk[gw_session][unit.get_unit_id()] ~= nil then + local success, result = pcall(ent_chk[gw_session][unit.get_unit_id()].delete) + ent_chk[gw_session][unit.get_unit_id()] = nil + + if success then + log.debug(util.c("PGI: deleted CHK entry ", gw_session, ":", unit.get_unit_id())) + else + log.error(util.c("PGI: failed to delete CHK entry (", result, ")"), true) + end + else + log.warning(util.c("PGI: tried to delete unknown CHK entry with session of ", gw_session, " and unit ID of ", unit.get_unit_id())) end end diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index f404291..0f3fece 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -4,6 +4,7 @@ local util = require("scada-common.util") local databus = require("supervisor.databus") local facility = require("supervisor.facility") +local pgi = require("supervisor.pgi") local coordinator = require("supervisor.session.coordinator") local plc = require("supervisor.session.plc") @@ -194,12 +195,8 @@ end local function _update_dev_dbg() local f = function (unit) return unit.is_connected() end - ---@param unit unit_session - local on_delete = function (unit) - end - - util.filter_table(self.dev_dbg.duplicate, f, on_delete) - util.filter_table(self.dev_dbg.out_of_range, f, on_delete) + util.filter_table(self.dev_dbg.duplicate, f, pgi.delete_chk_entry) + util.filter_table(self.dev_dbg.out_of_range, f, pgi.delete_chk_entry) end -- SHARED FUNCTIONS -- @@ -231,6 +228,20 @@ local function check_rtu_id(unit, list, max) fail_code, fail_str = 3, "too many of this type" end + -- add to the list for the user + if fail_code > 0 then + local cmp_id + + for i = 1, #self.sessions.rtu do + if self.sessions.rtu[i].instance.get_id() == unit.get_session_id() then + cmp_id = self.sessions.rtu[i].s_addr + break + end + end + + pgi.create_chk_entry(unit, fail_code, cmp_id) + end + return fail_code, fail_str end