From 3ae39b2455d4a3721e94c6e7a90f1b4912062d07 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Tue, 11 Apr 2023 23:53:42 -0400 Subject: [PATCH 01/51] #204 replaced util.strwrap implementation with cc.strings.wrap --- coordinator/startup.lua | 2 +- install_manifest.json | 2 +- reactor-plc/startup.lua | 2 +- scada-common/util.lua | 47 ++++------------------------------------- 4 files changed, 7 insertions(+), 46 deletions(-) diff --git a/coordinator/startup.lua b/coordinator/startup.lua index b169b06..e74b6af 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -19,7 +19,7 @@ local iocontrol = require("coordinator.iocontrol") local renderer = require("coordinator.renderer") local sounder = require("coordinator.sounder") -local COORDINATOR_VERSION = "v0.12.5" +local COORDINATOR_VERSION = "v0.12.6" local print = util.print local println = util.println diff --git a/install_manifest.json b/install_manifest.json index 7485e70..e0413fe 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.0", "reactor-plc": "v1.1.4", "rtu": "v0.13.2", "supervisor": "v0.14.3", "coordinator": "v0.12.5", "pocket": "alpha-v0.0.0"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/threads.lua", "rtu/rtu.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/apisessions.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/unit_waiting.lua", "coordinator/ui/components/turbine.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5040, "system": 1982, "common": 91616, "graphics": 111150, "lockbox": 100797, "reactor-plc": 95087, "rtu": 86291, "supervisor": 274510, "coordinator": 181151, "pocket": 6873}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.0", "reactor-plc": "v1.1.5", "rtu": "v0.13.2", "supervisor": "v0.14.3", "coordinator": "v0.12.6", "pocket": "alpha-v0.0.0"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/threads.lua", "rtu/rtu.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/apisessions.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/unit_waiting.lua", "coordinator/ui/components/turbine.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5040, "system": 1982, "common": 90101, "graphics": 111150, "lockbox": 100797, "reactor-plc": 95087, "rtu": 86291, "supervisor": 274510, "coordinator": 181151, "pocket": 9122}} \ No newline at end of file diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 293281c..0596f14 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.1.4" +local R_PLC_VERSION = "v1.1.5" local print = util.print local println = util.println diff --git a/scada-common/util.lua b/scada-common/util.lua index 2913e9f..e13f9fc 100644 --- a/scada-common/util.lua +++ b/scada-common/util.lua @@ -2,6 +2,8 @@ -- Utility Functions -- +local cc_strings = require("cc.strings") + ---@class util local util = {} @@ -104,53 +106,12 @@ function util.pad(str, n) return util.spaces(lpad) .. str .. util.spaces(rpad) end --- wrap a string into a table of lines, supporting single dash splits +-- wrap a string into a table of lines ---@nodiscard ---@param str string ---@param limit integer line limit ---@return table lines -function util.strwrap(str, limit) - local lines = {} - local ln_start = 1 - - local first_break = str:find("([%-%s]+)") - - if first_break ~= nil then - lines[1] = string.sub(str, 1, first_break - 1) - else - lines[1] = str - end - ----@diagnostic disable-next-line: discard-returns - str:gsub("(%s+)()(%S+)()", - function(space, start, word, stop) - -- support splitting SINGLE DASH words - word:gsub("(%S+)(%-)()(%S+)()", - function (pre, dash, d_start, post, d_stop) - if (stop + d_stop) - ln_start <= limit then - -- do nothing, it will entirely fit - elseif ((start + d_start) + 1) - ln_start <= limit then - -- we can fit including the dash - lines[#lines] = lines[#lines] .. space .. pre .. dash - -- drop the space and replace the word with the post - space = "" - word = post - -- force a wrap - stop = limit + 1 + ln_start - -- change start position for new line start - start = start + d_start - 1 - end - end) - -- can we append this or do we have to start a new line? - if stop - ln_start > limit then - -- starting new line - ln_start = start - lines[#lines + 1] = word - else lines[#lines] = lines[#lines] .. space .. word end - end) - - return lines -end +function util.strwrap(str, limit) return cc_strings.wrap(str, limit) end -- concatenation with built-in to string ---@nodiscard From 075a0280acff8a7442196bdfec7a37cc6f95826a Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 12:40:13 -0400 Subject: [PATCH 02/51] #193 WIP pocket initial app, sidebar added --- coordinator/ui/components/unit_waiting.lua | 33 ----- graphics/element.lua | 1 + graphics/elements/animations/waiting.lua | 2 +- graphics/elements/controls/sidebar.lua | 104 +++++++++++++ pocket/config.lua | 21 +++ pocket/pocket.lua | 5 + pocket/renderer.lua | 78 ++++++++++ pocket/startup.lua | 164 ++++++++++++++++++++- pocket/ui/components/conn_waiting.lua | 38 +++++ pocket/ui/main.lua | 67 +++++++++ pocket/ui/style.lua | 158 ++++++++++++++++++++ 11 files changed, 633 insertions(+), 38 deletions(-) delete mode 100644 coordinator/ui/components/unit_waiting.lua create mode 100644 graphics/elements/controls/sidebar.lua create mode 100644 pocket/pocket.lua create mode 100644 pocket/renderer.lua create mode 100644 pocket/ui/components/conn_waiting.lua create mode 100644 pocket/ui/main.lua create mode 100644 pocket/ui/style.lua diff --git a/coordinator/ui/components/unit_waiting.lua b/coordinator/ui/components/unit_waiting.lua deleted file mode 100644 index 3b1a846..0000000 --- a/coordinator/ui/components/unit_waiting.lua +++ /dev/null @@ -1,33 +0,0 @@ --- --- Reactor Unit Waiting Spinner --- - -local style = require("coordinator.ui.style") - -local core = require("graphics.core") - -local Div = require("graphics.elements.div") -local TextBox = require("graphics.elements.textbox") - -local WaitingAnim = require("graphics.elements.animations.waiting") - -local TEXT_ALIGN = core.graphics.TEXT_ALIGN - -local cpair = core.graphics.cpair - --- create a unit waiting view ----@param parent graphics_element parent ----@param y integer y offset -local function init(parent, y) - -- bounding box div - local root = Div{parent=parent,x=1,y=y,height=5} - - local waiting_x = math.floor(parent.width() / 2) - 2 - - TextBox{parent=root,text="Waiting for status...",alignment=TEXT_ALIGN.CENTER,y=1,height=1,fg_bg=cpair(colors.black,style.root.bkg)} - WaitingAnim{parent=root,x=waiting_x,y=3,fg_bg=cpair(colors.blue,style.root.bkg)} - - return root -end - -return init diff --git a/graphics/element.lua b/graphics/element.lua index d9bc489..cd69dd4 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -25,6 +25,7 @@ local element = {} ---|multi_button_args ---|push_button_args ---|radio_button_args +---|sidebar_args ---|spinbox_args ---|switch_button_args ---|alarm_indicator_light diff --git a/graphics/elements/animations/waiting.lua b/graphics/elements/animations/waiting.lua index 2b08092..a0d7b3e 100644 --- a/graphics/elements/animations/waiting.lua +++ b/graphics/elements/animations/waiting.lua @@ -85,7 +85,7 @@ local function waiting(args) if state >= 12 then state = 0 end if run_animation then - tcd.dispatch_unique(0.5, animate) + tcd.dispatch_unique(0.15, animate) end end diff --git a/graphics/elements/controls/sidebar.lua b/graphics/elements/controls/sidebar.lua new file mode 100644 index 0000000..885761d --- /dev/null +++ b/graphics/elements/controls/sidebar.lua @@ -0,0 +1,104 @@ +-- Sidebar Graphics Element + +local tcd = require("scada-common.tcallbackdsp") + +local element = require("graphics.element") + +---@class sidebar_tab +---@field char string character identifier +---@field color cpair tab colors (fg/bg) + +---@class sidebar_args +---@field tabs table sidebar tab options +---@field callback function function to call on tab change +---@field parent graphics_element +---@field id? string element id +---@field x? integer 1 if omitted +---@field y? integer 1 if omitted +---@field height? integer parent height if omitted +---@field fg_bg? cpair foreground/background colors + +-- new sidebar tab selector +---@param args sidebar_args +---@return graphics_element element, element_id id +local function sidebar(args) + assert(type(args.tabs) == "table", "graphics.elements.controls.sidebar: tabs is a required field") + assert(#args.tabs > 0, "graphics.elements.controls.sidebar: at least one tab is required") + assert(type(args.callback) == "function", "graphics.elements.controls.sidebar: callback is a required field") + + -- always 3 wide + args.width = 3 + + -- create new graphics element base object + local e = element.new(args) + + assert(e.frame.h >= (#args.tabs * 3), "graphics.elements.controls.sidebar: height insufficent to display all tabs") + + -- default to 1st tab + e.value = 1 + + -- show the button state + ---@param pressed boolean if the currently selected tab should appear as actively pressed + local function draw(pressed) + for i = 1, #args.tabs do + local tab = args.tabs[i] ---@type sidebar_tab + + local y = ((i - 1) * 3) + 1 + + e.window.setCursorPos(1, y) + + if pressed and e.value == i then + e.window.setTextColor(e.fg_bg.fgd) + e.window.setBackgroundColor(e.fg_bg.bkg) + else + e.window.setTextColor(tab.color.fgd) + e.window.setBackgroundColor(tab.color.bkg) + end + + e.window.write(" ") + e.window.setCursorPos(1, y + 1) + if e.value == i then + -- show as selected + e.window.write(" " .. tab.char .. "\x10") + else + -- show as unselected + e.window.write(" " .. tab.char .. " ") + end + e.window.setCursorPos(1, y + 2) + e.window.write(" ") + end + end + + -- handle mouse interaction + ---@param event mouse_interaction mouse event + function e.handle_mouse(event) + -- determine what was pressed + if e.enabled then + local idx = math.ceil(event.y / 3) + + if args.tabs[idx] ~= nil then + e.value = idx + draw(true) + + -- show as unpressed in 0.25 seconds + tcd.dispatch(0.25, function () draw(false) end) + + args.callback(e.value) + end + end + end + + -- set the value + ---@param val integer new value + function e.set_value(val) + e.value = val + draw(false) + end + + -- initial draw + draw(false) + + return e.get() +end + +return sidebar diff --git a/pocket/config.lua b/pocket/config.lua index e69de29..cacd9f1 100644 --- a/pocket/config.lua +++ b/pocket/config.lua @@ -0,0 +1,21 @@ +local config = {} + +-- port of the SCADA supervisor +config.SCADA_SV_PORT = 16100 +-- port for SCADA coordinator API access +config.SCADA_API_PORT = 16200 +-- port to listen to incoming packets FROM servers +config.LISTEN_PORT = 16201 +-- max trusted modem message distance (0 to disable check) +config.TRUSTED_RANGE = 0 +-- time in seconds (>= 2) before assuming a remote device is no longer active +config.COMMS_TIMEOUT = 5 + +-- log path +config.LOG_PATH = "/log.txt" +-- log mode +-- 0 = APPEND (adds to existing file on start) +-- 1 = NEW (replaces existing file on start) +config.LOG_MODE = 0 + +return config diff --git a/pocket/pocket.lua b/pocket/pocket.lua new file mode 100644 index 0000000..2f537a3 --- /dev/null +++ b/pocket/pocket.lua @@ -0,0 +1,5 @@ + + +local pocket = {} + +return pocket diff --git a/pocket/renderer.lua b/pocket/renderer.lua new file mode 100644 index 0000000..d394acc --- /dev/null +++ b/pocket/renderer.lua @@ -0,0 +1,78 @@ +-- +-- Graphics Rendering Control +-- + +local log = require("scada-common.log") +local util = require("scada-common.util") + +local main_view = require("pocket.ui.main") +local style = require("pocket.ui.style") + +local flasher = require("graphics.flasher") + +local renderer = {} + +local ui = { + view = nil +} + +-- start the coordinator GUI +function renderer.start_ui() + if ui.view == nil then + -- reset screen + term.setTextColor(colors.white) + term.setBackgroundColor(colors.black) + term.clear() + term.setCursorPos(1, 1) + + -- set overridden colors + for i = 1, #style.colors do + term.setPaletteColor(style.colors[i].c, style.colors[i].hex) + end + + -- start flasher callback task + flasher.run() + + -- init front panel view + ui.view = main_view(term.current()) + end +end + +-- close out the UI +function renderer.close_ui() + -- stop blinking indicators + flasher.clear() + + if ui.view ~= nil then + -- hide to stop animation callbacks + ui.view.hide() + end + + -- clear root UI elements + ui.view = nil + + -- restore colors + for i = 1, #style.colors do + local r, g, b = term.nativePaletteColor(style.colors[i].c) + term.setPaletteColor(style.colors[i].c, r, g, b) + end + + -- reset terminal + term.setTextColor(colors.white) + term.setBackgroundColor(colors.black) + term.clear() + term.setCursorPos(1, 1) +end + +-- is the UI ready? +---@nodiscard +---@return boolean ready +function renderer.ui_ready() return ui.view ~= nil end + +-- handle a mouse event +---@param event mouse_interaction +function renderer.handle_mouse(event) + ui.view.handle_mouse(event) +end + +return renderer diff --git a/pocket/startup.lua b/pocket/startup.lua index 032bba9..b869975 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -1,16 +1,172 @@ -- --- SCADA Coordinator Access on a Pocket Computer +-- SCADA System Access on a Pocket Computer -- require("/initenv").init_env() -local util = require("scada-common.util") +local crash = require("scada-common.crash") +local log = require("scada-common.log") +local ppm = require("scada-common.ppm") +local tcallbackdsp = require("scada-common.tcallbackdsp") +local util = require("scada-common.util") -local POCKET_VERSION = "alpha-v0.0.0" +local core = require("graphics.core") + +local config = require("pocket.config") +local pocket = require("pocket.pocket") +local renderer = require("pocket.renderer") + +local POCKET_VERSION = "alpha-v0.1.0" local print = util.print local println = util.println local print_ts = util.print_ts local println_ts = util.println_ts -println("Sorry, this isn't written yet :(") +---------------------------------------- +-- config validation +---------------------------------------- + +local cfv = util.new_validator() + +cfv.assert_port(config.SCADA_SV_PORT) +cfv.assert_port(config.SCADA_API_PORT) +cfv.assert_port(config.LISTEN_PORT) +cfv.assert_type_int(config.TRUSTED_RANGE) +cfv.assert_type_num(config.COMMS_TIMEOUT) +cfv.assert_min(config.COMMS_TIMEOUT, 2) +cfv.assert_type_str(config.LOG_PATH) +cfv.assert_type_int(config.LOG_MODE) + +assert(cfv.valid(), "bad config file: missing/invalid fields") + +---------------------------------------- +-- log init +---------------------------------------- + +log.init(config.LOG_PATH, config.LOG_MODE) + +log.info("========================================") +log.info("BOOTING pocket.startup " .. POCKET_VERSION) +log.info("========================================") + +crash.set_env("pocket", POCKET_VERSION) + +---------------------------------------- +-- main application +---------------------------------------- + +local function main() + ---------------------------------------- + -- system startup + ---------------------------------------- + + -- mount connected devices + ppm.mount_all() + + ---------------------------------------- + -- setup communications + ---------------------------------------- + + -- get the communications modem + local modem = ppm.get_wireless_modem() + if modem == nil then + println("startup> wireless modem not found: please craft the pocket computer with a wireless modem") + log.fatal("no wireless modem on startup") + return + end + + -- create connection watchdog + local conn_watchdog = util.new_watchdog(config.COMMS_TIMEOUT) + conn_watchdog.cancel() + log.debug("startup> conn watchdog created") + + -- start comms, open all channels + -- local pocket_comms = pocket.comms(POCKET_VERSION, modem, config.SCADA_SV_PORT, config.SCADA_API_PORT, + -- config.LISTEN_PORT, config.TRUSTED_RANGE, conn_watchdog) + -- log.debug("startup> comms init") + + -- base loop clock (2Hz, 10 ticks) + local MAIN_CLOCK = 0.5 + local loop_clock = util.new_clock(MAIN_CLOCK) + + ---------------------------------------- + -- start the UI + ---------------------------------------- + + local ui_ok, message = pcall(renderer.start_ui) + if not ui_ok then + renderer.close_ui() + println_ts(util.c("UI error: ", message)) + log.error(util.c("GUI crashed with error ", message)) + else + -- start clock + loop_clock.start() + end + + ---------------------------------------- + -- main event loop + ---------------------------------------- + + if ui_ok then + -- start connection watchdog + conn_watchdog.feed() + log.debug("startup> conn watchdog started") + end + + -- main event loop + while ui_ok do + local event, param1, param2, param3, param4, param5 = util.pull_event() + + -- handle event + if event == "timer" then + if loop_clock.is_clock(param1) then + -- main loop tick + loop_clock.start() + elseif conn_watchdog.is_timer(param1) then + -- supervisor watchdog timeout + log.info("server timeout") + + -- pocket_comms.close() + else + -- a non-clock/main watchdog timer event + + -- notify timer callback dispatcher + tcallbackdsp.handle(param1) + end + elseif event == "modem_message" then + -- got a packet + -- local packet = pocket_comms.parse_packet(param1, param2, param3, param4, param5) + -- pocket_comms.handle_packet(packet) + + -- -- check if it was a disconnect + -- if not pocket_comms.is_linked() then + -- log_comms("supervisor closed connection") + + -- -- close connection + -- pocket_comms.close() + -- end + elseif event == "mouse_click" then + -- handle a monitor touch event + renderer.handle_mouse(core.events.touch(param1, param2, param3)) + end + + -- check for termination request + if event == "terminate" or ppm.should_terminate() then + log.info("terminate requested, closing connections...") + -- pocket_comms.close() + log.info("supervisor connection closed") + break + end + end + + renderer.close_ui() + + println_ts("exited") + log.info("exited") +end + +if not xpcall(main, crash.handler) then + pcall(renderer.close_ui) + crash.exit() +end diff --git a/pocket/ui/components/conn_waiting.lua b/pocket/ui/components/conn_waiting.lua new file mode 100644 index 0000000..d83d09e --- /dev/null +++ b/pocket/ui/components/conn_waiting.lua @@ -0,0 +1,38 @@ +-- +-- Connection Waiting Spinner +-- + +local style = require("pocket.ui.style") + +local core = require("graphics.core") + +local Div = require("graphics.elements.div") +local TextBox = require("graphics.elements.textbox") + +local WaitingAnim = require("graphics.elements.animations.waiting") + +local TEXT_ALIGN = core.graphics.TEXT_ALIGN + +local cpair = core.graphics.cpair + +-- create a waiting view +---@param parent graphics_element parent +---@param y integer y offset +local function init(parent, y, is_api) + -- bounding box div + local root = Div{parent=parent,x=1,y=y,height=5} + + local waiting_x = math.floor(parent.width() / 2) - 1 + + if is_api then + TextBox{parent=root,text="Connecting to API",alignment=TEXT_ALIGN.CENTER,y=1,height=1,fg_bg=cpair(colors.white,style.root.bkg)} + WaitingAnim{parent=root,x=waiting_x,y=3,fg_bg=cpair(colors.blue,style.root.bkg)} + else + TextBox{parent=root,text="Connecting to Supervisor",alignment=TEXT_ALIGN.CENTER,y=1,height=1,fg_bg=cpair(colors.white,style.root.bkg)} + WaitingAnim{parent=root,x=waiting_x,y=3,fg_bg=cpair(colors.green,style.root.bkg)} + end + + return root +end + +return init diff --git a/pocket/ui/main.lua b/pocket/ui/main.lua new file mode 100644 index 0000000..94f6ca5 --- /dev/null +++ b/pocket/ui/main.lua @@ -0,0 +1,67 @@ +-- +-- Pocket GUI Root +-- + +local util = require("scada-common.util") + +local style = require("pocket.ui.style") + +local conn_waiting = require("pocket.ui.components.conn_waiting") + +local core = require("graphics.core") + +local ColorMap = require("graphics.elements.colormap") +local DisplayBox = require("graphics.elements.displaybox") +local Div = require("graphics.elements.div") +local TextBox = require("graphics.elements.textbox") + +local PushButton = require("graphics.elements.controls.push_button") +local SwitchButton = require("graphics.elements.controls.switch_button") +local Sidebar = require("graphics.elements.controls.sidebar") + +local DataIndicator = require("graphics.elements.indicators.data") + +local TEXT_ALIGN = core.graphics.TEXT_ALIGN + +local cpair = core.graphics.cpair + +-- create new main view +---@param monitor table main viewscreen +local function init(monitor) + local main = DisplayBox{window=monitor,fg_bg=style.root} + + -- window header message + local header = TextBox{parent=main,y=1,text="",alignment=TEXT_ALIGN.LEFT,height=1,fg_bg=style.header} + + -- local api_wait = conn_waiting(main, 8, true) + -- local sv_wait = conn_waiting(main, 8, false) + + local sidebar_tabs = { + { + char = "#", + color = cpair(colors.black,colors.green) + }, + { + char = "U", + color = cpair(colors.black,colors.yellow) + }, + { + char = "R", + color = cpair(colors.black,colors.cyan) + }, + { + char = "B", + color = cpair(colors.black,colors.lightGray) + }, + { + char = "T", + color = cpair(colors.black,colors.white) + } + } + + local sidebar = Sidebar{parent=main,x=1,y=2,tabs=sidebar_tabs,fg_bg=cpair(colors.white,colors.gray),callback=function()end} + + return main +end + +return init diff --git a/pocket/ui/style.lua b/pocket/ui/style.lua new file mode 100644 index 0000000..b9a09fc --- /dev/null +++ b/pocket/ui/style.lua @@ -0,0 +1,158 @@ +-- +-- Graphics Style Options +-- + +local core = require("graphics.core") + +local style = {} + +local cpair = core.graphics.cpair + +-- GLOBAL -- + +style.root = cpair(colors.white, colors.black) +style.header = cpair(colors.white, colors.gray) +style.label = cpair(colors.gray, colors.lightGray) + +style.colors = { + { c = colors.red, hex = 0xdf4949 }, + { c = colors.orange, hex = 0xffb659 }, + { c = colors.yellow, hex = 0xfffc79 }, + { c = colors.lime, hex = 0x80ff80 }, + { c = colors.green, hex = 0x4aee8a }, + { c = colors.cyan, hex = 0x34bac8 }, + { c = colors.lightBlue, hex = 0x6cc0f2 }, + { c = colors.blue, hex = 0x0096ff }, + { c = colors.purple, hex = 0xb156ee }, + { c = colors.pink, hex = 0xf26ba2 }, + { c = colors.magenta, hex = 0xf9488a }, + -- { c = colors.white, hex = 0xf0f0f0 }, + { c = colors.lightGray, hex = 0xcacaca }, + { c = colors.gray, hex = 0x575757 }, + -- { c = colors.black, hex = 0x191919 }, + -- { c = colors.brown, hex = 0x7f664c } +} + +-- MAIN LAYOUT -- + +style.reactor = { + -- reactor states + states = { + { + color = cpair(colors.black, colors.yellow), + text = "PLC OFF-LINE" + }, + { + color = cpair(colors.black, colors.orange), + text = "NOT FORMED" + }, + { + color = cpair(colors.black, colors.orange), + text = "PLC FAULT" + }, + { + color = cpair(colors.white, colors.gray), + text = "DISABLED" + }, + { + color = cpair(colors.black, colors.green), + text = "ACTIVE" + }, + { + color = cpair(colors.black, colors.red), + text = "SCRAMMED" + }, + { + color = cpair(colors.black, colors.red), + text = "FORCE DISABLED" + } + } +} + +style.boiler = { + -- boiler states + states = { + { + color = cpair(colors.black, colors.yellow), + text = "OFF-LINE" + }, + { + color = cpair(colors.black, colors.orange), + text = "NOT FORMED" + }, + { + color = cpair(colors.black, colors.orange), + text = "RTU FAULT" + }, + { + color = cpair(colors.white, colors.gray), + text = "IDLE" + }, + { + color = cpair(colors.black, colors.green), + text = "ACTIVE" + } + } +} + +style.turbine = { + -- turbine states + states = { + { + color = cpair(colors.black, colors.yellow), + text = "OFF-LINE" + }, + { + color = cpair(colors.black, colors.orange), + text = "NOT FORMED" + }, + { + color = cpair(colors.black, colors.orange), + text = "RTU FAULT" + }, + { + color = cpair(colors.white, colors.gray), + text = "IDLE" + }, + { + color = cpair(colors.black, colors.green), + text = "ACTIVE" + }, + { + color = cpair(colors.black, colors.red), + text = "TRIP" + } + } +} + +style.imatrix = { + -- induction matrix states + states = { + { + color = cpair(colors.black, colors.yellow), + text = "OFF-LINE" + }, + { + color = cpair(colors.black, colors.orange), + text = "NOT FORMED" + }, + { + color = cpair(colors.black, colors.orange), + text = "RTU FAULT" + }, + { + color = cpair(colors.black, colors.green), + text = "ONLINE" + }, + { + color = cpair(colors.black, colors.yellow), + text = "LOW CHARGE" + }, + { + color = cpair(colors.black, colors.yellow), + text = "HIGH CHARGE" + }, + } +} + +return style From c987d14d8d5010d89530227e8e913e1950b8a476 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Wed, 12 Apr 2023 16:02:29 -0400 Subject: [PATCH 03/51] added Luacheck GitHub action (#210) * added shields.io elements * #209 luacheck action * #209 cleanup to pass luacheck * added check statuses to readme --- .github/workflows/check.yml | 28 +++++++++++++++++++ .vscode/settings.json | 1 - README.md | 5 ++++ coordinator/apisessions.lua | 2 ++ coordinator/coordinator.lua | 3 +- coordinator/iocontrol.lua | 4 +-- coordinator/sounder.lua | 3 +- coordinator/startup.lua | 4 +-- coordinator/ui/components/reactor.lua | 3 +- coordinator/ui/components/unit_overview.lua | 7 ++--- coordinator/ui/layout/main_view.lua | 6 ---- .../elements/controls/spinbox_numeric.lua | 3 +- graphics/elements/indicators/coremap.lua | 2 +- graphics/elements/indicators/ledrgb.lua | 2 +- install_manifest.json | 2 +- pocket/startup.lua | 8 +++--- reactor-plc/plc.lua | 6 ---- reactor-plc/startup.lua | 5 ++-- reactor-plc/threads.lua | 4 +-- rtu/dev/redstone_rtu.lua | 6 ++-- rtu/modbus.lua | 12 ++++---- rtu/rtu.lua | 7 ++--- rtu/startup.lua | 14 ++++------ rtu/threads.lua | 3 -- scada-common/crypto.lua | 23 ++++++--------- startup.lua | 2 +- supervisor/session/coordinator.lua | 8 ++---- supervisor/session/plc.lua | 5 +--- supervisor/session/rtu.lua | 9 ++---- supervisor/session/rtu/redstone.lua | 1 - supervisor/session/svsessions.lua | 2 -- supervisor/startup.lua | 4 +-- supervisor/supervisor.lua | 3 -- test/lockbox-benchmark.lua | 9 +++--- test/rstest.lua | 1 - 35 files changed, 93 insertions(+), 114 deletions(-) create mode 100644 .github/workflows/check.yml diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..e0bcf50 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,28 @@ +name: Lua Checks + +on: + workflow_dispatch: + push: + branches: + - main + - latest + - devel + pull_request: + branches: + - main + - latest + - devel +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3.5.1 + - name: Luacheck + uses: lunarmodules/luacheck@v1.1.0 + with: + # -a = disable warning for unused arguments + # -i 121 = Setting a read-only global variable. + # -u 512 = Loop can be executed at most once. + # -i 542 = An empty if branch. + args: . --no-max-line-length -a -i 121 512 542 --exclude-files ./lockbox/* ./*/config.lua --globals _HOST term fs peripheral rs bit parallel colors textutils shell settings window read periphemu http os diff --git a/.vscode/settings.json b/.vscode/settings.json index 70230fe..732eb4a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,7 +13,6 @@ "window", "read", "periphemu", - "mekanismEnergyHelper", "_HOST", "http" ], diff --git a/README.md b/README.md index 925d853..464d754 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,11 @@ # cc-mek-scada Configurable ComputerCraft SCADA system for multi-reactor control of Mekanism fission reactors with a GUI, automatic safety features, waste processing control, and more! +![GitHub](https://img.shields.io/github/license/MikaylaFischler/cc-mek-scada) +![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/MikaylaFischler/cc-mek-scada?include_prereleases) +![GitHub branch checks state](https://img.shields.io/github/checks-status/MikaylaFischler/cc-mek-scada/main?label=main) +![GitHub branch checks state](https://img.shields.io/github/checks-status/MikaylaFischler/cc-mek-scada/devel?label=devel) + Mod Requirements: - CC: Tweaked - Mekanism v10.1+ diff --git a/coordinator/apisessions.lua b/coordinator/apisessions.lua index 268052e..8646837 100644 --- a/coordinator/apisessions.lua +++ b/coordinator/apisessions.lua @@ -1,11 +1,13 @@ local apisessions = {} ---@param packet capi_frame +---@diagnostic disable-next-line: unused-local function apisessions.handle_packet(packet) end -- attempt to identify which session's watchdog timer fired ---@param timer_event number +---@diagnostic disable-next-line: unused-local function apisessions.check_all_watchdogs(timer_event) end diff --git a/coordinator/coordinator.lua b/coordinator/coordinator.lua index 821c82a..d8d43a2 100644 --- a/coordinator/coordinator.lua +++ b/coordinator/coordinator.lua @@ -11,7 +11,6 @@ local dialog = require("coordinator.ui.dialog") local print = util.print local println = util.println -local print_ts = util.print_ts local println_ts = util.println_ts local PROTOCOL = comms.PROTOCOL @@ -246,7 +245,7 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range ---@param msg table local function _send_sv(protocol, msg_type, msg) local s_pkt = comms.scada_packet() - local pkt = nil ---@type mgmt_packet|crdn_packet + local pkt ---@type mgmt_packet|crdn_packet if protocol == PROTOCOL.SCADA_MGMT then pkt = comms.mgmt_packet() diff --git a/coordinator/iocontrol.lua b/coordinator/iocontrol.lua index cfb3be7..ac45a2f 100644 --- a/coordinator/iocontrol.lua +++ b/coordinator/iocontrol.lua @@ -657,8 +657,8 @@ function iocontrol.update_unit_statuses(statuses) if type(rtu_statuses.rad_mon) == "table" then if #rtu_statuses.rad_mon > 0 then local rad_mon = rtu_statuses.rad_mon[1] - local rtu_faulted = rad_mon[1] ---@type boolean - unit.radiation = rad_mon[2] ---@type number + -- local rtu_faulted = rad_mon[1] ---@type boolean + unit.radiation = rad_mon[2] ---@type number unit.unit_ps.publish("radiation", unit.radiation) else diff --git a/coordinator/sounder.lua b/coordinator/sounder.lua index 6eafb8d..86fb9b4 100644 --- a/coordinator/sounder.lua +++ b/coordinator/sounder.lua @@ -12,10 +12,11 @@ local ALARM_STATE = types.ALARM_STATE ---@class sounder local sounder = {} +-- note: max samples = 0x20000 (128 * 1024 samples) + local _2_PI = 2 * math.pi -- 2 whole pies, hope you're hungry local _DRATE = 48000 -- 48kHz audio local _MAX_VAL = 127 / 2 -- max signed integer in this 8-bit audio -local _MAX_SAMPLES = 0x20000 -- 128 * 1024 samples local _05s_SAMPLES = 24000 -- half a second worth of samples local test_alarms = { false, false, false, false, false, false, false, false, false, false, false, false } diff --git a/coordinator/startup.lua b/coordinator/startup.lua index e74b6af..d59e528 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -21,9 +21,7 @@ local sounder = require("coordinator.sounder") local COORDINATOR_VERSION = "v0.12.6" -local print = util.print local println = util.println -local print_ts = util.print_ts local println_ts = util.println_ts local log_graphics = coordinator.log_graphics @@ -287,7 +285,7 @@ local function main() else log_sys("wired modem reconnected") end - elseif type == "monitor" then + -- elseif type == "monitor" then -- not supported, system will exit on loss of in-use monitors elseif type == "speaker" then local msg = "alarm sounder speaker reconnected" diff --git a/coordinator/ui/components/reactor.lua b/coordinator/ui/components/reactor.lua index a17fc75..db75fb1 100644 --- a/coordinator/ui/components/reactor.lua +++ b/coordinator/ui/components/reactor.lua @@ -18,9 +18,8 @@ local border = core.graphics.border ---@param root graphics_element parent ---@param x integer top left x ---@param y integer top left y ----@param data reactor_db reactor data ---@param ps psil ps interface -local function new_view(root, x, y, data, ps) +local function new_view(root, x, y, ps) local reactor = Rectangle{parent=root,border=border(1, colors.gray, true),width=30,height=7,x=x,y=y} local text_fg_bg = cpair(colors.black, colors.lightGray) diff --git a/coordinator/ui/components/unit_overview.lua b/coordinator/ui/components/unit_overview.lua index e5a07f9..24bc02e 100644 --- a/coordinator/ui/components/unit_overview.lua +++ b/coordinator/ui/components/unit_overview.lua @@ -24,19 +24,18 @@ local pipe = core.graphics.pipe ---@param y integer top left y ---@param unit ioctl_unit unit database entry local function make(parent, x, y, unit) - local height = 0 local num_boilers = #unit.boiler_data_tbl local num_turbines = #unit.turbine_data_tbl assert(num_boilers >= 0 and num_boilers <= 2, "minimum 0 boilers, maximum 2 boilers") assert(num_turbines >= 1 and num_turbines <= 3, "minimum 1 turbine, maximum 3 turbines") + local height = 25 + if num_boilers == 0 and num_turbines == 1 then height = 9 elseif num_boilers == 1 and num_turbines <= 2 then height = 17 - else - height = 25 end assert(parent.height() >= (y + height), "main display not of sufficient vertical resolution (add an additional row of monitors)") @@ -51,7 +50,7 @@ local function make(parent, x, y, unit) -- REACTOR -- ------------- - reactor_view(root, 1, 3, unit.reactor_data, unit.unit_ps) + reactor_view(root, 1, 3, unit.unit_ps) if num_boilers > 0 then local coolant_pipes = {} diff --git a/coordinator/ui/layout/main_view.lua b/coordinator/ui/layout/main_view.lua index d9a726f..5c8da4b 100644 --- a/coordinator/ui/layout/main_view.lua +++ b/coordinator/ui/layout/main_view.lua @@ -5,7 +5,6 @@ local util = require("scada-common.util") local iocontrol = require("coordinator.iocontrol") -local sounder = require("coordinator.sounder") local style = require("coordinator.ui.style") @@ -15,14 +14,9 @@ local unit_overview = require("coordinator.ui.components.unit_overview") local core = require("graphics.core") -local ColorMap = require("graphics.elements.colormap") local DisplayBox = require("graphics.elements.displaybox") -local Div = require("graphics.elements.div") local TextBox = require("graphics.elements.textbox") -local PushButton = require("graphics.elements.controls.push_button") -local SwitchButton = require("graphics.elements.controls.switch_button") - local DataIndicator = require("graphics.elements.indicators.data") local TEXT_ALIGN = core.graphics.TEXT_ALIGN diff --git a/graphics/elements/controls/spinbox_numeric.lua b/graphics/elements/controls/spinbox_numeric.lua index ffbd1f8..15e0e76 100644 --- a/graphics/elements/controls/spinbox_numeric.lua +++ b/graphics/elements/controls/spinbox_numeric.lua @@ -30,8 +30,7 @@ local function spinbox(args) assert(util.is_int(wn_prec), "graphics.element.controls.spinbox_numeric: whole number precision must be an integer") assert(util.is_int(fr_prec), "graphics.element.controls.spinbox_numeric: fractional precision must be an integer") - local fmt = "" - local fmt_init = "" + local fmt, fmt_init ---@type string, string if fr_prec > 0 then fmt = "%" .. (wn_prec + fr_prec + 1) .. "." .. fr_prec .. "f" diff --git a/graphics/elements/indicators/coremap.lua b/graphics/elements/indicators/coremap.lua index c50348b..323e17c 100644 --- a/graphics/elements/indicators/coremap.lua +++ b/graphics/elements/indicators/coremap.lua @@ -73,7 +73,7 @@ local function core_map(args) local function draw_core(t) local i = 1 local back_c = "F" - local text_c = "8" + local text_c ---@type string -- determine fuel assembly coloring if t <= 300 then diff --git a/graphics/elements/indicators/ledrgb.lua b/graphics/elements/indicators/ledrgb.lua index c58b835..e779785 100644 --- a/graphics/elements/indicators/ledrgb.lua +++ b/graphics/elements/indicators/ledrgb.lua @@ -38,7 +38,7 @@ local function indicator_led_rgb(args) e.value = new_state e.window.setCursorPos(1, 1) if type(args.colors[new_state]) == "number" then - e.window.blit("\x8c", colors.toBlit(args.colors[new_state]), e.fg_bg.blit_bkg) + e.window.blit("\x8c", colors.toBlit(args.colors[new_state]), e.fg_bg.blit_bkg) end end diff --git a/install_manifest.json b/install_manifest.json index e0413fe..c75fc9e 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.0", "reactor-plc": "v1.1.5", "rtu": "v0.13.2", "supervisor": "v0.14.3", "coordinator": "v0.12.6", "pocket": "alpha-v0.0.0"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/threads.lua", "rtu/rtu.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/apisessions.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/unit_waiting.lua", "coordinator/ui/components/turbine.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/conn_waiting.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5040, "system": 1982, "common": 90101, "graphics": 111150, "lockbox": 100797, "reactor-plc": 95087, "rtu": 86291, "supervisor": 274510, "coordinator": 181151, "pocket": 9122}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.0", "reactor-plc": "v1.1.5", "rtu": "v0.13.3", "supervisor": "v0.14.4", "coordinator": "v0.12.6", "pocket": "alpha-v0.0.0"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/threads.lua", "rtu/rtu.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/apisessions.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/unit_waiting.lua", "coordinator/ui/components/turbine.lua"], "pocket": ["pocket/config.lua", "pocket/startup.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 4909, "system": 1991, "common": 91556, "graphics": 111156, "lockbox": 100797, "reactor-plc": 94599, "rtu": 86149, "supervisor": 273852, "coordinator": 180746, "pocket": 347}} \ No newline at end of file diff --git a/pocket/startup.lua b/pocket/startup.lua index 032bba9..3782412 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -6,11 +6,11 @@ require("/initenv").init_env() local util = require("scada-common.util") -local POCKET_VERSION = "alpha-v0.0.0" +-- local POCKET_VERSION = "alpha-v0.0.0" -local print = util.print +-- local print = util.print local println = util.println -local print_ts = util.print_ts -local println_ts = util.println_ts +-- local print_ts = util.print_ts +-- local println_ts = util.println_ts println("Sorry, this isn't written yet :(") diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index 2879290..2faefb5 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -68,11 +68,6 @@ function plc.rps_init(reactor, is_formed, emer_cool) end end - -- clear reactor access fault flag - local function _clear_fault() - self.state[state_keys.fault] = false - end - -- set emergency coolant control (if configured) ---@param state boolean true to enable emergency coolant, false to disable local function _set_emer_cool(state) @@ -779,7 +774,6 @@ function plc.comms(id, version, modem, local_port, server_port, range, reactor, ---@param setpoints setpoints setpoint control table function public.handle_packet(packet, plc_state, setpoints) -- print a log message to the terminal as long as the UI isn't running - local function println(message) if not plc_state.fp_ok then util.println(message) end end local function println_ts(message) if not plc_state.fp_ok then util.println_ts(message) end end -- handle packets now that we have prints setup diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 0596f14..010c36e 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -20,9 +20,7 @@ local threads = require("reactor-plc.threads") local R_PLC_VERSION = "v1.1.5" -local print = util.print local println = util.println -local print_ts = util.print_ts local println_ts = util.println_ts ---------------------------------------- @@ -176,8 +174,9 @@ local function main() -- front panel time! if not renderer.ui_ready() then - local message = nil + local message plc_state.fp_ok, message = pcall(renderer.start_ui) + if not plc_state.fp_ok then renderer.close_ui() println_ts(util.c("UI error: ", message)) diff --git a/reactor-plc/threads.lua b/reactor-plc/threads.lua index c307999..8470430 100644 --- a/reactor-plc/threads.lua +++ b/reactor-plc/threads.lua @@ -34,7 +34,6 @@ local MQ__COMM_CMD = { ---@param init function function threads.thread__main(smem, init) -- print a log message to the terminal as long as the UI isn't running - local function println(message) if not smem.plc_state.fp_ok then util.println(message) end end local function println_ts(message) if not smem.plc_state.fp_ok then util.println_ts(message) end end ---@class parallel_thread @@ -307,7 +306,6 @@ end ---@param smem plc_shared_memory function threads.thread__rps(smem) -- print a log message to the terminal as long as the UI isn't running - local function println(message) if not smem.plc_state.fp_ok then util.println(message) end end local function println_ts(message) if not smem.plc_state.fp_ok then util.println_ts(message) end end ---@class parallel_thread @@ -682,7 +680,7 @@ function threads.thread__setpoint_control(smem) -- we yielded, check enable again if setpoints.burn_rate_en and (type(current_burn_rate) == "number") and (current_burn_rate ~= setpoints.burn_rate) then -- calculate new burn rate - local new_burn_rate = current_burn_rate + local new_burn_rate ---@type number if setpoints.burn_rate > current_burn_rate then -- need to ramp up diff --git a/rtu/dev/redstone_rtu.lua b/rtu/dev/redstone_rtu.lua index c482999..c073250 100644 --- a/rtu/dev/redstone_rtu.lua +++ b/rtu/dev/redstone_rtu.lua @@ -34,7 +34,7 @@ function redstone_rtu.new() ---@param side string ---@param color integer function public.link_di(side, color) - local f_read = nil + local f_read ---@type function if color then f_read = function () @@ -53,8 +53,8 @@ function redstone_rtu.new() ---@param side string ---@param color integer function public.link_do(side, color) - local f_read = nil - local f_write = nil + local f_read ---@type function + local f_write ---@type function if color then f_read = function () diff --git a/rtu/modbus.lua b/rtu/modbus.lua index 20c5939..06c1273 100644 --- a/rtu/modbus.lua +++ b/rtu/modbus.lua @@ -347,11 +347,9 @@ function modbus.new(rtu_dev, use_parallel_read) response = { MODBUS_EXCODE.NEG_ACKNOWLEDGE } end - -- default is to echo back - local func_code = packet.func_code - - -- echo back with error flag, on success the "error" will be acknowledgement - func_code = bit.bor(packet.func_code, MODBUS_FCODE.ERROR_FLAG) + -- default is to echo back
+ -- but here we echo back with error flag, on success the "error" will be acknowledgement + local func_code = bit.bor(packet.func_code, MODBUS_FCODE.ERROR_FLAG) -- create reply local reply = comms.modbus_packet() @@ -365,8 +363,8 @@ function modbus.new(rtu_dev, use_parallel_read) ---@param packet modbus_frame ---@return boolean return_code, modbus_packet reply function public.handle_packet(packet) - local return_code = true - local response = nil + local return_code ---@type boolean + local response ---@type table|MODBUS_EXCODE if packet.length >= 2 then -- handle by function code diff --git a/rtu/rtu.lua b/rtu/rtu.lua index a1b9fbd..b8dee99 100644 --- a/rtu/rtu.lua +++ b/rtu/rtu.lua @@ -14,9 +14,6 @@ local ESTABLISH_ACK = comms.ESTABLISH_ACK local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE -local print = util.print -local println = util.println -local print_ts = util.print_ts local println_ts = util.println_ts -- create a new RTU unit @@ -347,8 +344,8 @@ function rtu.comms(version, modem, local_port, server_port, range, conn_watchdog if protocol == PROTOCOL.MODBUS_TCP then ---@cast packet modbus_frame if rtu_state.linked then - local return_code = false - local reply = modbus.reply__neg_ack(packet) + local return_code ---@type boolean + local reply ---@type modbus_packet -- handle MODBUS instruction if packet.unit_id <= #units then diff --git a/rtu/startup.lua b/rtu/startup.lua index 40c0498..2ebbd8d 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -25,13 +25,11 @@ local sna_rtu = require("rtu.dev.sna_rtu") local sps_rtu = require("rtu.dev.sps_rtu") local turbinev_rtu = require("rtu.dev.turbinev_rtu") -local RTU_VERSION = "v0.13.2" +local RTU_VERSION = "v0.13.3" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE -local print = util.print local println = util.println -local print_ts = util.print_ts local println_ts = util.println_ts ---------------------------------------- @@ -287,9 +285,9 @@ local function main() local device = ppm.get_periph(name) - local type = nil ---@type string|nil - local rtu_iface = nil ---@type rtu_device - local rtu_type = nil ---@type RTU_UNIT_TYPE + local type ---@type string|nil + local rtu_iface ---@type rtu_device + local rtu_type ---@type RTU_UNIT_TYPE local is_multiblock = false ---@type boolean local formed = nil ---@type boolean|nil local faulted = nil ---@type boolean|nil @@ -356,11 +354,11 @@ local function main() elseif type == "solarNeutronActivator" then -- SNA rtu_type = RTU_UNIT_TYPE.SNA - rtu_iface, _ = sna_rtu.new(device) + rtu_iface, faulted = sna_rtu.new(device) elseif type == "environmentDetector" then -- advanced peripherals environment detector rtu_type = RTU_UNIT_TYPE.ENV_DETECTOR - rtu_iface, _ = envd_rtu.new(device) + rtu_iface, faulted = envd_rtu.new(device) elseif type == ppm.VIRTUAL_DEVICE_TYPE then -- placeholder device rtu_type = RTU_UNIT_TYPE.VIRTUAL diff --git a/rtu/threads.lua b/rtu/threads.lua index 27ad68e..7b2a6fa 100644 --- a/rtu/threads.lua +++ b/rtu/threads.lua @@ -17,9 +17,6 @@ local threads = {} local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE -local print = util.print -local println = util.println -local print_ts = util.print_ts local println_ts = util.println_ts local MAIN_CLOCK = 2 -- (2Hz, 40 ticks) diff --git a/scada-common/crypto.lua b/scada-common/crypto.lua index a1053bf..4417ae3 100644 --- a/scada-common/crypto.lua +++ b/scada-common/crypto.lua @@ -5,7 +5,6 @@ local aes128 = require("lockbox.cipher.aes128") local ctr_mode = require("lockbox.cipher.mode.ctr") local sha1 = require("lockbox.digest.sha1") -local sha2_224 = require("lockbox.digest.sha2_224") local sha2_256 = require("lockbox.digest.sha2_256") local pbkdf2 = require("lockbox.kdf.pbkdf2") local hmac = require("lockbox.mac.hmac") @@ -157,10 +156,6 @@ end -- wrap a modem as a secure modem to send encrypted traffic ---@param modem table modem to wrap function crypto.secure_modem(modem) - local self = { - modem = modem - } - ---@class secure_modem ---@field open function ---@field isOpen function @@ -177,17 +172,17 @@ function crypto.secure_modem(modem) local public = {} -- wrap a modem - ---@param modem table + ---@param reconnected_modem table ---@diagnostic disable-next-line: redefined-local - function public.wrap(modem) - self.modem = modem - for key, func in pairs(self.modem) do + function public.wrap(reconnected_modem) + modem = reconnected_modem + for key, func in pairs(modem) do public[key] = func end end -- wrap modem functions, then we replace transmit - public.wrap(self.modem) + public.wrap(modem) -- send a packet with encryption ---@param channel integer @@ -198,9 +193,9 @@ function crypto.secure_modem(modem) local iv, ciphertext = crypto.encrypt(plaintext) ---@diagnostic disable-next-line: redefined-local - local hmac = crypto.hmac(iv .. ciphertext) + local computed_hmac = crypto.hmac(iv .. ciphertext) - self.modem.transmit(channel, reply_channel, { hmac, iv, ciphertext }) + modem.transmit(channel, reply_channel, { computed_hmac, iv, ciphertext }) end -- parse in a modem message as a network packet @@ -217,13 +212,13 @@ function crypto.secure_modem(modem) if type(message) == "table" then if #message == 3 then ---@diagnostic disable-next-line: redefined-local - local hmac = message[1] + local rx_hmac = message[1] local iv = message[2] local ciphertext = message[3] local computed_hmac = crypto.hmac(iv .. ciphertext) - if hmac == computed_hmac then + if rx_hmac == computed_hmac then -- message intact local plaintext = crypto.decrypt(iv, ciphertext) body = textutils.unserialize(plaintext) diff --git a/startup.lua b/startup.lua index 482c919..d312de3 100644 --- a/startup.lua +++ b/startup.lua @@ -7,7 +7,7 @@ local println_ts = util.println_ts println("SCADA BOOTLOADER V" .. BOOTLOADER_VERSION) -local exit_code = false +local exit_code ---@type boolean println_ts("BOOT> SCANNING FOR APPLICATIONS...") diff --git a/supervisor/session/coordinator.lua b/supervisor/session/coordinator.lua index 44dbefe..ad706e8 100644 --- a/supervisor/session/coordinator.lua +++ b/supervisor/session/coordinator.lua @@ -16,16 +16,12 @@ local FAC_COMMAND = comms.FAC_COMMAND local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE -local SV_Q_CMDS = svqtypes.SV_Q_CMDS local SV_Q_DATA = svqtypes.SV_Q_DATA -local print = util.print local println = util.println -local print_ts = util.print_ts -local println_ts = util.println_ts -- retry time constants in ms -local INITIAL_WAIT = 1500 +-- local INITIAL_WAIT = 1500 local RETRY_PERIOD = 1000 local PARTIAL_RETRY_PERIOD = 2000 @@ -198,7 +194,7 @@ function coordinator.new_session(id, in_queue, out_queue, timeout, facility) -- keep alive reply if pkt.length == 2 then local srv_start = pkt.data[1] - local coord_send = pkt.data[2] + -- local coord_send = pkt.data[2] local srv_now = util.time() self.last_rtt = srv_now - srv_start diff --git a/supervisor/session/plc.lua b/supervisor/session/plc.lua index 3bba325..40efd8c 100644 --- a/supervisor/session/plc.lua +++ b/supervisor/session/plc.lua @@ -14,10 +14,7 @@ local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE local PLC_AUTO_ACK = comms.PLC_AUTO_ACK local UNIT_COMMAND = comms.UNIT_COMMAND -local print = util.print local println = util.println -local print_ts = util.print_ts -local println_ts = util.println_ts -- retry time constants in ms local INITIAL_WAIT = 1500 @@ -476,7 +473,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) -- keep alive reply if pkt.length == 2 then local srv_start = pkt.data[1] - local plc_send = pkt.data[2] + -- local plc_send = pkt.data[2] local srv_now = util.time() self.last_rtt = srv_now - srv_start diff --git a/supervisor/session/rtu.lua b/supervisor/session/rtu.lua index d265cad..da5648c 100644 --- a/supervisor/session/rtu.lua +++ b/supervisor/session/rtu.lua @@ -22,10 +22,7 @@ local PROTOCOL = comms.PROTOCOL local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE -local print = util.print local println = util.println -local print_ts = util.print_ts -local println_ts = util.println_ts local PERIODICS = { KEEP_ALIVE = 2000 @@ -78,9 +75,7 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili end for i = 1, #self.advert do - local unit = nil ---@type unit_session|nil - local rs_in_q = nil ---@type mqueue|nil - local tbv_in_q = nil ---@type mqueue|nil + local unit = nil ---@type unit_session|nil ---@type rtu_advertisement local unit_advert = { @@ -242,7 +237,7 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili -- keep alive reply if pkt.length == 2 then local srv_start = pkt.data[1] - local rtu_send = pkt.data[2] + -- local rtu_send = pkt.data[2] local srv_now = util.time() self.last_rtt = srv_now - srv_start diff --git a/supervisor/session/rtu/redstone.lua b/supervisor/session/rtu/redstone.lua index 7c813a2..65831d6 100644 --- a/supervisor/session/rtu/redstone.lua +++ b/supervisor/session/rtu/redstone.lua @@ -12,7 +12,6 @@ local MODBUS_FCODE = types.MODBUS_FCODE local IO_PORT = rsio.IO local IO_LVL = rsio.IO_LVL -local IO_DIR = rsio.IO_DIR local IO_MODE = rsio.IO_MODE local TXN_READY = -1 diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index 76fb6d1..aa3506b 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -13,12 +13,10 @@ local rtu = require("supervisor.session.rtu") -- Supervisor Sessions Handler -local SV_Q_CMDS = svqtypes.SV_Q_CMDS 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 CRD_S_CMDS = coordinator.CRD_S_CMDS local CRD_S_DATA = coordinator.CRD_S_DATA local svsessions = {} diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 14e7bb3..87bd902 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -14,11 +14,9 @@ local svsessions = require("supervisor.session.svsessions") local config = require("supervisor.config") local supervisor = require("supervisor.supervisor") -local SUPERVISOR_VERSION = "v0.14.3" +local SUPERVISOR_VERSION = "v0.14.4" -local print = util.print local println = util.println -local print_ts = util.print_ts local println_ts = util.println_ts ---------------------------------------- diff --git a/supervisor/supervisor.lua b/supervisor/supervisor.lua index 848dfc3..937dac8 100644 --- a/supervisor/supervisor.lua +++ b/supervisor/supervisor.lua @@ -11,10 +11,7 @@ local DEVICE_TYPE = comms.DEVICE_TYPE local ESTABLISH_ACK = comms.ESTABLISH_ACK local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE -local print = util.print local println = util.println -local print_ts = util.print_ts -local println_ts = util.println_ts -- supervisory controller communications ---@nodiscard diff --git a/test/lockbox-benchmark.lua b/test/lockbox-benchmark.lua index 0191c2a..198f41b 100644 --- a/test/lockbox-benchmark.lua +++ b/test/lockbox-benchmark.lua @@ -4,14 +4,14 @@ local pbkdf2 = require("lockbox.kdf.pbkdf2") local AES128Cipher = require("lockbox.cipher.aes128") local HMAC = require("lockbox.mac.hmac") local SHA1 = require("lockbox.digest.sha1") -local SHA2_224 = require("lockbox.digest.sha2_224") +-- local SHA2_224 = require("lockbox.digest.sha2_224") local SHA2_256 = require("lockbox.digest.sha2_256") local Stream = require("lockbox.util.stream") local Array = require("lockbox.util.array") -local CBCMode = require("lockbox.cipher.mode.cbc") -local CFBMode = require("lockbox.cipher.mode.cfb") -local OFBMode = require("lockbox.cipher.mode.ofb") +-- local CBCMode = require("lockbox.cipher.mode.cbc") +-- local CFBMode = require("lockbox.cipher.mode.cfb") +-- local OFBMode = require("lockbox.cipher.mode.ofb") local CTRMode = require("lockbox.cipher.mode.ctr") local ZeroPadding = require("lockbox.padding.zero") @@ -35,6 +35,7 @@ util.println("pbkdf2: took " .. (util.time() - start) .. "ms") util.println(keyd.asHex()) local pkt = comms.modbus_packet() +---@diagnostic disable-next-line: param-type-mismatch pkt.make(1, 2, 7, {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}) local spkt = comms.scada_packet() spkt.make(1, 1, pkt.raw_sendable()) diff --git a/test/rstest.lua b/test/rstest.lua index d195fc6..e322e28 100644 --- a/test/rstest.lua +++ b/test/rstest.lua @@ -10,7 +10,6 @@ local println = util.println local IO = rsio.IO local IO_LVL = rsio.IO_LVL -local IO_DIR = rsio.IO_DIR local IO_MODE = rsio.IO_MODE println("starting RSIO tester") From df0ee7c4f7e6b90ce9df22ac1a9ffdf1514ebd03 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 16:07:15 -0400 Subject: [PATCH 04/51] updated shields readme elements --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 464d754..89cd3f4 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,9 @@ Configurable ComputerCraft SCADA system for multi-reactor control of Mekanism fi ![GitHub](https://img.shields.io/github/license/MikaylaFischler/cc-mek-scada) ![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/MikaylaFischler/cc-mek-scada?include_prereleases) -![GitHub branch checks state](https://img.shields.io/github/checks-status/MikaylaFischler/cc-mek-scada/main?label=main) -![GitHub branch checks state](https://img.shields.io/github/checks-status/MikaylaFischler/cc-mek-scada/devel?label=devel) +![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/MikaylaFischler/cc-mek-scada/check.yml?branch=main&label=main) +![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/MikaylaFischler/cc-mek-scada/check.yml?branch=latest&label=latest) +![GitHub Workflow Status (with branch)](https://img.shields.io/github/actions/workflow/status/MikaylaFischler/cc-mek-scada/check.yml?branch=devel&label=devel) Mod Requirements: - CC: Tweaked From 5c333c2a07f392f83dd982f7bfe2e19f3a50501a Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 17:04:28 -0400 Subject: [PATCH 05/51] test for adding subversions to shields.io --- .github/shields.io/bootloader.json | 1 + .github/shields.io/comms.json | 1 + .github/shields.io/coordinator.json | 1 + .github/shields.io/installer.json | 1 + .github/shields.io/pocket.json | 1 + .github/shields.io/reactor-plc.json | 1 + .github/shields.io/rtu.json | 1 + .github/shields.io/supervisor.json | 1 + imgen.py | 24 +++++++++++++++++++++++- install_manifest.json | 2 +- 10 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 .github/shields.io/bootloader.json create mode 100644 .github/shields.io/comms.json create mode 100644 .github/shields.io/coordinator.json create mode 100644 .github/shields.io/installer.json create mode 100644 .github/shields.io/pocket.json create mode 100644 .github/shields.io/reactor-plc.json create mode 100644 .github/shields.io/rtu.json create mode 100644 .github/shields.io/supervisor.json diff --git a/.github/shields.io/bootloader.json b/.github/shields.io/bootloader.json new file mode 100644 index 0000000..d7303d3 --- /dev/null +++ b/.github/shields.io/bootloader.json @@ -0,0 +1 @@ +{"schemaVersion": 1, "label": "bootloader", "message": "0.2", "color": "blue"} \ No newline at end of file diff --git a/.github/shields.io/comms.json b/.github/shields.io/comms.json new file mode 100644 index 0000000..bc8e4ac --- /dev/null +++ b/.github/shields.io/comms.json @@ -0,0 +1 @@ +{"schemaVersion": 1, "label": "comms", "message": "1.4.0", "color": "blue"} \ No newline at end of file diff --git a/.github/shields.io/coordinator.json b/.github/shields.io/coordinator.json new file mode 100644 index 0000000..76d7be2 --- /dev/null +++ b/.github/shields.io/coordinator.json @@ -0,0 +1 @@ +{"schemaVersion": 1, "label": "coordinator", "message": "v0.12.6", "color": "blue"} \ No newline at end of file diff --git a/.github/shields.io/installer.json b/.github/shields.io/installer.json new file mode 100644 index 0000000..4bfe644 --- /dev/null +++ b/.github/shields.io/installer.json @@ -0,0 +1 @@ +{"schemaVersion": 1, "label": "installer", "message": "v1.0", "color": "blue"} \ No newline at end of file diff --git a/.github/shields.io/pocket.json b/.github/shields.io/pocket.json new file mode 100644 index 0000000..a51febe --- /dev/null +++ b/.github/shields.io/pocket.json @@ -0,0 +1 @@ +{"schemaVersion": 1, "label": "pocket", "message": "alpha-v0.0.0", "color": "yellow"} \ No newline at end of file diff --git a/.github/shields.io/reactor-plc.json b/.github/shields.io/reactor-plc.json new file mode 100644 index 0000000..975d087 --- /dev/null +++ b/.github/shields.io/reactor-plc.json @@ -0,0 +1 @@ +{"schemaVersion": 1, "label": "reactor-plc", "message": "v1.1.5", "color": "blue"} \ No newline at end of file diff --git a/.github/shields.io/rtu.json b/.github/shields.io/rtu.json new file mode 100644 index 0000000..1eed29f --- /dev/null +++ b/.github/shields.io/rtu.json @@ -0,0 +1 @@ +{"schemaVersion": 1, "label": "rtu", "message": "v0.13.3", "color": "blue"} \ No newline at end of file diff --git a/.github/shields.io/supervisor.json b/.github/shields.io/supervisor.json new file mode 100644 index 0000000..cfdd8f6 --- /dev/null +++ b/.github/shields.io/supervisor.json @@ -0,0 +1 @@ +{"schemaVersion": 1, "label": "supervisor", "message": "v0.14.4", "color": "blue"} \ No newline at end of file diff --git a/imgen.py b/imgen.py index 30e7e69..7197619 100644 --- a/imgen.py +++ b/imgen.py @@ -100,7 +100,29 @@ f.close() manifest_size = os.path.getsize("install_manifest.json") +final_manifest = make_manifest(manifest_size) + # calculate file size then regenerate with embedded size f = open("install_manifest.json", "w") -json.dump(make_manifest(manifest_size), f) +json.dump(final_manifest, f) f.close() + +# write all the JSON files for shields.io +for key, version in final_manifest["versions"].items(): + f = open(".github/shields.io/" + key + ".json", "w") + + if version.find("alpha") >= 0: + color = "yellow" + elif version.find("beta") >= 0: + color = "orange" + else: + color = "blue" + + json.dump({ + "schemaVersion": 1, + "label": key, + "message": "" + version, + "color": color + }, f) + + f.close() diff --git a/install_manifest.json b/install_manifest.json index c75fc9e..b762a3e 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.0", "reactor-plc": "v1.1.5", "rtu": "v0.13.3", "supervisor": "v0.14.4", "coordinator": "v0.12.6", "pocket": "alpha-v0.0.0"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/threads.lua", "rtu/rtu.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/apisessions.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/unit_waiting.lua", "coordinator/ui/components/turbine.lua"], "pocket": ["pocket/config.lua", "pocket/startup.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 4909, "system": 1991, "common": 91556, "graphics": 111156, "lockbox": 100797, "reactor-plc": 94599, "rtu": 86149, "supervisor": 273852, "coordinator": 180746, "pocket": 347}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.0", "reactor-plc": "v1.1.5", "rtu": "v0.13.3", "supervisor": "v0.14.4", "coordinator": "v0.12.6", "pocket": "alpha-v0.0.0"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/threads.lua", "rtu/rtu.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/apisessions.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/unit_waiting.lua", "coordinator/ui/components/turbine.lua"], "pocket": ["pocket/config.lua", "pocket/startup.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 4909, "system": 1991, "common": 90041, "graphics": 111156, "lockbox": 100797, "reactor-plc": 94599, "rtu": 86149, "supervisor": 273852, "coordinator": 180746, "pocket": 347}} \ No newline at end of file From f48266e27c0b68d9911460887e91b94a66a6a055 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 17:09:53 -0400 Subject: [PATCH 06/51] added subversions to readme --- README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/README.md b/README.md index 89cd3f4..d96f297 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,25 @@ v10.1+ is required due the complete support of CC:Tweaked added in Mekanism v10. There was also an apparent bug with boilers disconnecting and reconnecting when active in my test world on 10.0.24, so it may not even have been an option to fully implement this with support for 10.0. +## Component Versions + +### Core + +![Bootloader](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Fbootloader.json) +![Comms](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Fcomms.json) + +### Utilities + +![Installer](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Finstaller.json) + +### Applications + +![Reactor PLC](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Freactor-plc.json) +![RTU](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Frtu.json) +![Supervisor](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Fsupervisor.json) +![Coordinator](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Fcoordinator.json) +![Pocket](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Fpocket.json) + ## Installation You can install this on a ComputerCraft computer using either: From f108db9cfcad41d4307cd9231e650353c917cdb4 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 17:21:39 -0400 Subject: [PATCH 07/51] alternate plan for shields --- .github/shields.io/bootloader.json | 1 - .github/shields.io/comms.json | 1 - .github/shields.io/coordinator.json | 1 - .github/shields.io/installer.json | 1 - .github/shields.io/pocket.json | 1 - .github/shields.io/reactor-plc.json | 1 - .github/shields.io/rtu.json | 1 - .github/shields.io/supervisor.json | 1 - imgen.py | 34 +++++++++++++++-------------- 9 files changed, 18 insertions(+), 24 deletions(-) delete mode 100644 .github/shields.io/bootloader.json delete mode 100644 .github/shields.io/comms.json delete mode 100644 .github/shields.io/coordinator.json delete mode 100644 .github/shields.io/installer.json delete mode 100644 .github/shields.io/pocket.json delete mode 100644 .github/shields.io/reactor-plc.json delete mode 100644 .github/shields.io/rtu.json delete mode 100644 .github/shields.io/supervisor.json diff --git a/.github/shields.io/bootloader.json b/.github/shields.io/bootloader.json deleted file mode 100644 index d7303d3..0000000 --- a/.github/shields.io/bootloader.json +++ /dev/null @@ -1 +0,0 @@ -{"schemaVersion": 1, "label": "bootloader", "message": "0.2", "color": "blue"} \ No newline at end of file diff --git a/.github/shields.io/comms.json b/.github/shields.io/comms.json deleted file mode 100644 index bc8e4ac..0000000 --- a/.github/shields.io/comms.json +++ /dev/null @@ -1 +0,0 @@ -{"schemaVersion": 1, "label": "comms", "message": "1.4.0", "color": "blue"} \ No newline at end of file diff --git a/.github/shields.io/coordinator.json b/.github/shields.io/coordinator.json deleted file mode 100644 index 76d7be2..0000000 --- a/.github/shields.io/coordinator.json +++ /dev/null @@ -1 +0,0 @@ -{"schemaVersion": 1, "label": "coordinator", "message": "v0.12.6", "color": "blue"} \ No newline at end of file diff --git a/.github/shields.io/installer.json b/.github/shields.io/installer.json deleted file mode 100644 index 4bfe644..0000000 --- a/.github/shields.io/installer.json +++ /dev/null @@ -1 +0,0 @@ -{"schemaVersion": 1, "label": "installer", "message": "v1.0", "color": "blue"} \ No newline at end of file diff --git a/.github/shields.io/pocket.json b/.github/shields.io/pocket.json deleted file mode 100644 index a51febe..0000000 --- a/.github/shields.io/pocket.json +++ /dev/null @@ -1 +0,0 @@ -{"schemaVersion": 1, "label": "pocket", "message": "alpha-v0.0.0", "color": "yellow"} \ No newline at end of file diff --git a/.github/shields.io/reactor-plc.json b/.github/shields.io/reactor-plc.json deleted file mode 100644 index 975d087..0000000 --- a/.github/shields.io/reactor-plc.json +++ /dev/null @@ -1 +0,0 @@ -{"schemaVersion": 1, "label": "reactor-plc", "message": "v1.1.5", "color": "blue"} \ No newline at end of file diff --git a/.github/shields.io/rtu.json b/.github/shields.io/rtu.json deleted file mode 100644 index 1eed29f..0000000 --- a/.github/shields.io/rtu.json +++ /dev/null @@ -1 +0,0 @@ -{"schemaVersion": 1, "label": "rtu", "message": "v0.13.3", "color": "blue"} \ No newline at end of file diff --git a/.github/shields.io/supervisor.json b/.github/shields.io/supervisor.json deleted file mode 100644 index cfdd8f6..0000000 --- a/.github/shields.io/supervisor.json +++ /dev/null @@ -1 +0,0 @@ -{"schemaVersion": 1, "label": "supervisor", "message": "v0.14.4", "color": "blue"} \ No newline at end of file diff --git a/imgen.py b/imgen.py index 7197619..3da13d2 100644 --- a/imgen.py +++ b/imgen.py @@ -1,5 +1,6 @@ import json import os +import sys # list files in a directory def list_files(path): @@ -107,22 +108,23 @@ f = open("install_manifest.json", "w") json.dump(final_manifest, f) f.close() -# write all the JSON files for shields.io -for key, version in final_manifest["versions"].items(): - f = open(".github/shields.io/" + key + ".json", "w") +if sys.argv[1] == "shields": + # write all the JSON files for shields.io + for key, version in final_manifest["versions"].items(): + f = open("shields-" + key + ".json", "w") - if version.find("alpha") >= 0: - color = "yellow" - elif version.find("beta") >= 0: - color = "orange" - else: - color = "blue" + if version.find("alpha") >= 0: + color = "yellow" + elif version.find("beta") >= 0: + color = "orange" + else: + color = "blue" - json.dump({ - "schemaVersion": 1, - "label": key, - "message": "" + version, - "color": color - }, f) + json.dump({ + "schemaVersion": 1, + "label": key, + "message": "" + version, + "color": color + }, f) - f.close() + f.close() From 8c42a05bbdc5765becb233bd3cafe1c4746aa343 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 17:34:46 -0400 Subject: [PATCH 08/51] test for sheilds --- .github/workflows/shields.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/shields.yml b/.github/workflows/shields.yml index 2574318..f10ab31 100644 --- a/.github/workflows/shields.yml +++ b/.github/workflows/shields.yml @@ -4,7 +4,7 @@ name: Deploy static content to Pages on: # Runs on pushes targeting the default branch push: - branches: ["main"] + branches: ["devel"] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: From a8e05388046372828f1436a364979b983af5a46d Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 17:37:16 -0400 Subject: [PATCH 09/51] debugging actions --- .github/workflows/shields.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/shields.yml b/.github/workflows/shields.yml index f10ab31..956354e 100644 --- a/.github/workflows/shields.yml +++ b/.github/workflows/shields.yml @@ -36,6 +36,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v3.1.3 - run: python imgen.py shields + - run: ls - name: Upload artifact uses: actions/upload-pages-artifact@v1 with: From 982fded31df9e5a23782fe35ce82ef68c25b745b Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 17:39:38 -0400 Subject: [PATCH 10/51] possible fix for actions --- .github/workflows/shields.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/shields.yml b/.github/workflows/shields.yml index 956354e..a959766 100644 --- a/.github/workflows/shields.yml +++ b/.github/workflows/shields.yml @@ -41,7 +41,7 @@ jobs: uses: actions/upload-pages-artifact@v1 with: # Upload shields JSON - path: ./shields-* + path: shields-* - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v2 From ab9e487a2dc66a6e555e7050a952e604b1db625c Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 17:41:06 -0400 Subject: [PATCH 11/51] possible fix for actions 2 --- .github/workflows/shields.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/shields.yml b/.github/workflows/shields.yml index a959766..eae17a2 100644 --- a/.github/workflows/shields.yml +++ b/.github/workflows/shields.yml @@ -37,11 +37,12 @@ jobs: uses: actions/setup-python@v3.1.3 - run: python imgen.py shields - run: ls + - run: cat shields-*.json - name: Upload artifact uses: actions/upload-pages-artifact@v1 with: # Upload shields JSON - path: shields-* + path: shields-*.json - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v2 From 76f6cca42da3a8383bd72793e196b3ac6c178c11 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 17:44:00 -0400 Subject: [PATCH 12/51] possible fix for actions 3 --- .github/workflows/shields.yml | 3 +-- imgen.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/shields.yml b/.github/workflows/shields.yml index eae17a2..65cbe25 100644 --- a/.github/workflows/shields.yml +++ b/.github/workflows/shields.yml @@ -37,12 +37,11 @@ jobs: uses: actions/setup-python@v3.1.3 - run: python imgen.py shields - run: ls - - run: cat shields-*.json - name: Upload artifact uses: actions/upload-pages-artifact@v1 with: # Upload shields JSON - path: shields-*.json + path: **-shields.json - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v2 diff --git a/imgen.py b/imgen.py index 3da13d2..b1b3b8b 100644 --- a/imgen.py +++ b/imgen.py @@ -111,7 +111,7 @@ f.close() if sys.argv[1] == "shields": # write all the JSON files for shields.io for key, version in final_manifest["versions"].items(): - f = open("shields-" + key + ".json", "w") + f = open(key + "-shields.json", "w") if version.find("alpha") >= 0: color = "yellow" From 2b23dac1febac8f00d43c85cac72c2b85382811f Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 17:44:43 -0400 Subject: [PATCH 13/51] possible fix for actions 4 --- .github/workflows/shields.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/shields.yml b/.github/workflows/shields.yml index 65cbe25..f30bb07 100644 --- a/.github/workflows/shields.yml +++ b/.github/workflows/shields.yml @@ -41,7 +41,7 @@ jobs: uses: actions/upload-pages-artifact@v1 with: # Upload shields JSON - path: **-shields.json + path: ./**-shields.json - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v2 From 6b8b38b8cbe0fcca65f3d646f5ff7b0670f1c564 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 17:49:08 -0400 Subject: [PATCH 14/51] possible fix for actions 6 --- .github/workflows/shields.yml | 7 ++++--- imgen.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/shields.yml b/.github/workflows/shields.yml index f30bb07..1b934af 100644 --- a/.github/workflows/shields.yml +++ b/.github/workflows/shields.yml @@ -35,13 +35,14 @@ jobs: uses: actions/configure-pages@v3 - name: Setup Python uses: actions/setup-python@v3.1.3 - - run: python imgen.py shields - - run: ls + - run: mkdir shields + - run: python imgen.py 0 + - run: ls shields/ - name: Upload artifact uses: actions/upload-pages-artifact@v1 with: # Upload shields JSON - path: ./**-shields.json + path: shields/* - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v2 diff --git a/imgen.py b/imgen.py index b1b3b8b..34355a4 100644 --- a/imgen.py +++ b/imgen.py @@ -111,7 +111,7 @@ f.close() if sys.argv[1] == "shields": # write all the JSON files for shields.io for key, version in final_manifest["versions"].items(): - f = open(key + "-shields.json", "w") + f = open("shields/" + key + ".json", "w") if version.find("alpha") >= 0: color = "yellow" From 37dd52b12b18261e20262e78ce5fe455dbaeb1a4 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 17:50:43 -0400 Subject: [PATCH 15/51] possible fix for actions 7 --- .github/workflows/shields.yml | 4 ++-- imgen.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/shields.yml b/.github/workflows/shields.yml index 1b934af..b31bb3a 100644 --- a/.github/workflows/shields.yml +++ b/.github/workflows/shields.yml @@ -37,12 +37,12 @@ jobs: uses: actions/setup-python@v3.1.3 - run: mkdir shields - run: python imgen.py 0 - - run: ls shields/ + - run: ls ./shields/ - name: Upload artifact uses: actions/upload-pages-artifact@v1 with: # Upload shields JSON - path: shields/* + path: ./shields/* - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v2 diff --git a/imgen.py b/imgen.py index 34355a4..92d82db 100644 --- a/imgen.py +++ b/imgen.py @@ -111,7 +111,7 @@ f.close() if sys.argv[1] == "shields": # write all the JSON files for shields.io for key, version in final_manifest["versions"].items(): - f = open("shields/" + key + ".json", "w") + f = open("./shields/" + key + ".json", "w") if version.find("alpha") >= 0: color = "yellow" From 36b86a4825c7bac6824634c52ff5b044d92f2e0c Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 17:52:31 -0400 Subject: [PATCH 16/51] possible fix for actions 8 --- .github/workflows/shields.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/shields.yml b/.github/workflows/shields.yml index b31bb3a..30fee00 100644 --- a/.github/workflows/shields.yml +++ b/.github/workflows/shields.yml @@ -36,8 +36,10 @@ jobs: - name: Setup Python uses: actions/setup-python@v3.1.3 - run: mkdir shields - - run: python imgen.py 0 - - run: ls ./shields/ + - run: python imgen.py shields + - run: ls + - run: ls coordinator/ + - run: ls shields/ - name: Upload artifact uses: actions/upload-pages-artifact@v1 with: From c0547fe463c87e9f243689cae51170cb70fc63c0 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 17:54:18 -0400 Subject: [PATCH 17/51] possible fix for actions 9 --- .github/workflows/shields.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/shields.yml b/.github/workflows/shields.yml index 30fee00..f84094e 100644 --- a/.github/workflows/shields.yml +++ b/.github/workflows/shields.yml @@ -37,14 +37,12 @@ jobs: uses: actions/setup-python@v3.1.3 - run: mkdir shields - run: python imgen.py shields - - run: ls - - run: ls coordinator/ - run: ls shields/ - name: Upload artifact uses: actions/upload-pages-artifact@v1 with: # Upload shields JSON - path: ./shields/* + path: './shields/*' - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v2 From e2a3252d8acc324360a8c4411d4f0cbd87daaff2 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 17:55:18 -0400 Subject: [PATCH 18/51] possible fix for actions 10 --- .github/workflows/shields.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/shields.yml b/.github/workflows/shields.yml index f84094e..ccc19af 100644 --- a/.github/workflows/shields.yml +++ b/.github/workflows/shields.yml @@ -42,7 +42,7 @@ jobs: uses: actions/upload-pages-artifact@v1 with: # Upload shields JSON - path: './shields/*' + path: '.' - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v2 From 9b9ce7eae10a5a4306f57badc25876426e60dba1 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 12 Apr 2023 18:03:48 -0400 Subject: [PATCH 19/51] finally got shields component versions working with github actions --- .github/workflows/shields.yml | 5 ++--- README.md | 18 +++++++++--------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/.github/workflows/shields.yml b/.github/workflows/shields.yml index ccc19af..6790d7e 100644 --- a/.github/workflows/shields.yml +++ b/.github/workflows/shields.yml @@ -1,10 +1,10 @@ # Simple workflow for deploying static content to GitHub Pages -name: Deploy static content to Pages +name: Deploy Component Versions on: # Runs on pushes targeting the default branch push: - branches: ["devel"] + branches: ["main"] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -37,7 +37,6 @@ jobs: uses: actions/setup-python@v3.1.3 - run: mkdir shields - run: python imgen.py shields - - run: ls shields/ - name: Upload artifact uses: actions/upload-pages-artifact@v1 with: diff --git a/README.md b/README.md index d96f297..f0e6c89 100644 --- a/README.md +++ b/README.md @@ -18,24 +18,24 @@ v10.1+ is required due the complete support of CC:Tweaked added in Mekanism v10. There was also an apparent bug with boilers disconnecting and reconnecting when active in my test world on 10.0.24, so it may not even have been an option to fully implement this with support for 10.0. -## Component Versions +## Released Component Versions ### Core -![Bootloader](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Fbootloader.json) -![Comms](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Fcomms.json) +![Bootloader](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Fbootloader.json) +![Comms](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Fcomms.json) ### Utilities -![Installer](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Finstaller.json) +![Installer](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Finstaller.json) ### Applications -![Reactor PLC](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Freactor-plc.json) -![RTU](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Frtu.json) -![Supervisor](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Fsupervisor.json) -![Coordinator](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Fcoordinator.json) -![Pocket](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2FMikaylaFischler%2Fcc-mek-scada%2Fdevel%2F.github%2Fshields.io%2Fpocket.json) +![Reactor PLC](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Freactor-plc.json) +![RTU](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Frtu.json) +![Supervisor](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Fsupervisor.json) +![Coordinator](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Fcoordinator.json) +![Pocket](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Fpocket.json) ## Installation From ba70aa31dcd8af3d223becf833acb9fbf427ffb8 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 13 Apr 2023 09:29:16 -0400 Subject: [PATCH 20/51] test update of shields.yml --- .github/workflows/shields.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/shields.yml b/.github/workflows/shields.yml index 6790d7e..3bf8913 100644 --- a/.github/workflows/shields.yml +++ b/.github/workflows/shields.yml @@ -4,7 +4,7 @@ name: Deploy Component Versions on: # Runs on pushes targeting the default branch push: - branches: ["main"] + branches: ["main","devel"] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -41,7 +41,7 @@ jobs: uses: actions/upload-pages-artifact@v1 with: # Upload shields JSON - path: '.' + path: 'shields/' - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v2 From 5bcd885f53badedfdef4fe557d2974ed2f99e053 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 13 Apr 2023 09:33:44 -0400 Subject: [PATCH 21/51] shortened shields URLs after adjustment to action --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index f0e6c89..7c953be 100644 --- a/README.md +++ b/README.md @@ -22,20 +22,20 @@ There was also an apparent bug with boilers disconnecting and reconnecting when ### Core -![Bootloader](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Fbootloader.json) -![Comms](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Fcomms.json) +![Bootloader](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fbootloader.json) +![Comms](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fcomms.json) ### Utilities -![Installer](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Finstaller.json) +![Installer](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Finstaller.json) ### Applications -![Reactor PLC](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Freactor-plc.json) -![RTU](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Frtu.json) -![Supervisor](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Fsupervisor.json) -![Coordinator](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Fcoordinator.json) -![Pocket](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fshields%2Fpocket.json) +![Reactor PLC](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Freactor-plc.json) +![RTU](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Frtu.json) +![Supervisor](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fsupervisor.json) +![Coordinator](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fcoordinator.json) +![Pocket](https://img.shields.io/endpoint?url=https%3A%2F%2Fmikaylafischler.github.io%2Fcc-mek-scada%2Fpocket.json) ## Installation From 64449c66749f89c384efc63606ba32120cc11827 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 13 Apr 2023 09:41:56 -0400 Subject: [PATCH 22/51] restore shields action to just main branch --- .github/workflows/shields.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/shields.yml b/.github/workflows/shields.yml index 3bf8913..50698af 100644 --- a/.github/workflows/shields.yml +++ b/.github/workflows/shields.yml @@ -4,7 +4,7 @@ name: Deploy Component Versions on: # Runs on pushes targeting the default branch push: - branches: ["main","devel"] + branches: ["main"] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: From 59512bb0cf3bc0fd78d2f010ccd8252faf9e27db Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 13 Apr 2023 10:43:03 -0400 Subject: [PATCH 23/51] Create devcontainer.json --- .devcontainer/devcontainer.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..ad93c14 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,5 @@ +{ + "image": "mcr.microsoft.com/devcontainers/universal:2", + "features": { + } +} From b35bf98deca73676eddc85b99c5cede6ed3b276a Mon Sep 17 00:00:00 2001 From: Mikayla Date: Thu, 13 Apr 2023 14:45:02 +0000 Subject: [PATCH 24/51] update devcontainer with extensions --- .devcontainer/devcontainer.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ad93c14..9cdcab8 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,5 +1,14 @@ { "image": "mcr.microsoft.com/devcontainers/universal:2", "features": { - } +}, +"customizations": { + "vscode": { + "extensions": [ + "sumneko.lua", + "jackmacwindows.vscode-computercraft", + "jackmacwindows.craftos-pc" + ] + } +} } From e9290540f57de03c3458c226e0470635d9a18b72 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 16 Apr 2023 15:05:28 -0400 Subject: [PATCH 25/51] #193 pocket main application core --- graphics/element.lua | 1 + graphics/elements/multipane.lua | 42 +++++++++++++++++++++++++++ pocket/startup.lua | 2 +- pocket/ui/components/boiler_page.lua | 22 ++++++++++++++ pocket/ui/components/home_page.lua | 22 ++++++++++++++ pocket/ui/components/reactor_page.lua | 22 ++++++++++++++ pocket/ui/components/turbine_page.lua | 22 ++++++++++++++ pocket/ui/components/unit_page.lua | 22 ++++++++++++++ pocket/ui/main.lua | 21 +++++++++++++- 9 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 graphics/elements/multipane.lua create mode 100644 pocket/ui/components/boiler_page.lua create mode 100644 pocket/ui/components/home_page.lua create mode 100644 pocket/ui/components/reactor_page.lua create mode 100644 pocket/ui/components/turbine_page.lua create mode 100644 pocket/ui/components/unit_page.lua diff --git a/graphics/element.lua b/graphics/element.lua index cd69dd4..77012fd 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -45,6 +45,7 @@ local element = {} ---|colormap_args ---|displaybox_args ---|div_args +---|multipane_args ---|pipenet_args ---|rectangle_args ---|textbox_args diff --git a/graphics/elements/multipane.lua b/graphics/elements/multipane.lua new file mode 100644 index 0000000..8e25bab --- /dev/null +++ b/graphics/elements/multipane.lua @@ -0,0 +1,42 @@ +-- Multi-Pane Display Graphics Element + +local element = require("graphics.element") + +---@class multipane_args +---@field panes table panes to swap between +---@field parent graphics_element +---@field id? string element id +---@field x? integer 1 if omitted +---@field y? integer 1 if omitted +---@field width? integer parent width if omitted +---@field height? integer parent height if omitted +---@field gframe? graphics_frame frame instead of x/y/width/height +---@field fg_bg? cpair foreground/background colors + +-- new multipane element +---@nodiscard +---@param args multipane_args +---@return graphics_element element, element_id id +local function multipane(args) + assert(type(args.panes) == "table", "graphics.elements.multipane: panes is a required field") + + -- create new graphics element base object + local e = element.new(args) + + -- select which pane is shown + ---@param value integer pane to show + function e.set_value(value) + if (e.value ~= value) and (value > 0) and (value <= #args.panes) then + e.value = value + + for i = 1, #args.panes do args.panes[i].hide() end + args.panes[value].show() + end + end + + e.set_value(1) + + return e.get() +end + +return multipane diff --git a/pocket/startup.lua b/pocket/startup.lua index 4e820b1..90837d3 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -16,7 +16,7 @@ local config = require("pocket.config") local pocket = require("pocket.pocket") local renderer = require("pocket.renderer") -local POCKET_VERSION = "alpha-v0.1.0" +local POCKET_VERSION = "alpha-v0.1.1" -- local print = util.print local println = util.println diff --git a/pocket/ui/components/boiler_page.lua b/pocket/ui/components/boiler_page.lua new file mode 100644 index 0000000..204896a --- /dev/null +++ b/pocket/ui/components/boiler_page.lua @@ -0,0 +1,22 @@ +local style = require("pocket.ui.style") + +local core = require("graphics.core") + +local Div = require("graphics.elements.div") +local TextBox = require("graphics.elements.textbox") + +local cpair = core.graphics.cpair + +local TEXT_ALIGN = core.graphics.TEXT_ALIGN + +-- new boiler page view +---@param root graphics_element parent +local function new_view(root) + local main = Div{parent=root,x=1,y=1} + + TextBox{parent=main,text="BOILERS",x=1,y=1,height=1,alignment=TEXT_ALIGN.CENTER} + + return main +end + +return new_view diff --git a/pocket/ui/components/home_page.lua b/pocket/ui/components/home_page.lua new file mode 100644 index 0000000..6715f19 --- /dev/null +++ b/pocket/ui/components/home_page.lua @@ -0,0 +1,22 @@ +local style = require("pocket.ui.style") + +local core = require("graphics.core") + +local Div = require("graphics.elements.div") +local TextBox = require("graphics.elements.textbox") + +local cpair = core.graphics.cpair + +local TEXT_ALIGN = core.graphics.TEXT_ALIGN + +-- new home page view +---@param root graphics_element parent +local function new_view(root) + local main = Div{parent=root,x=1,y=1} + + TextBox{parent=main,text="HOME",x=1,y=1,height=1,alignment=TEXT_ALIGN.CENTER} + + return main +end + +return new_view diff --git a/pocket/ui/components/reactor_page.lua b/pocket/ui/components/reactor_page.lua new file mode 100644 index 0000000..4775d81 --- /dev/null +++ b/pocket/ui/components/reactor_page.lua @@ -0,0 +1,22 @@ +local style = require("pocket.ui.style") + +local core = require("graphics.core") + +local Div = require("graphics.elements.div") +local TextBox = require("graphics.elements.textbox") + +local cpair = core.graphics.cpair + +local TEXT_ALIGN = core.graphics.TEXT_ALIGN + +-- new reactor page view +---@param root graphics_element parent +local function new_view(root) + local main = Div{parent=root,x=1,y=1} + + TextBox{parent=main,text="REACTOR",x=1,y=1,height=1,alignment=TEXT_ALIGN.CENTER} + + return main +end + +return new_view diff --git a/pocket/ui/components/turbine_page.lua b/pocket/ui/components/turbine_page.lua new file mode 100644 index 0000000..9c060cc --- /dev/null +++ b/pocket/ui/components/turbine_page.lua @@ -0,0 +1,22 @@ +local style = require("pocket.ui.style") + +local core = require("graphics.core") + +local Div = require("graphics.elements.div") +local TextBox = require("graphics.elements.textbox") + +local cpair = core.graphics.cpair + +local TEXT_ALIGN = core.graphics.TEXT_ALIGN + +-- new turbine page view +---@param root graphics_element parent +local function new_view(root) + local main = Div{parent=root,x=1,y=1} + + TextBox{parent=main,text="TURBINES",x=1,y=1,height=1,alignment=TEXT_ALIGN.CENTER} + + return main +end + +return new_view diff --git a/pocket/ui/components/unit_page.lua b/pocket/ui/components/unit_page.lua new file mode 100644 index 0000000..60c91b1 --- /dev/null +++ b/pocket/ui/components/unit_page.lua @@ -0,0 +1,22 @@ +local style = require("pocket.ui.style") + +local core = require("graphics.core") + +local Div = require("graphics.elements.div") +local TextBox = require("graphics.elements.textbox") + +local cpair = core.graphics.cpair + +local TEXT_ALIGN = core.graphics.TEXT_ALIGN + +-- new unit page view +---@param root graphics_element parent +local function new_view(root) + local main = Div{parent=root,x=1,y=1} + + TextBox{parent=main,text="UNITS",x=1,y=1,height=1,alignment=TEXT_ALIGN.CENTER} + + return main +end + +return new_view diff --git a/pocket/ui/main.lua b/pocket/ui/main.lua index 94f6ca5..3360b9b 100644 --- a/pocket/ui/main.lua +++ b/pocket/ui/main.lua @@ -8,11 +8,18 @@ local style = require("pocket.ui.style") local conn_waiting = require("pocket.ui.components.conn_waiting") +local home_page = require("pocket.ui.components.home_page") +local unit_page = require("pocket.ui.components.unit_page") +local reactor_page = require("pocket.ui.components.reactor_page") +local boiler_page = require("pocket.ui.components.boiler_page") +local turbine_page = require("pocket.ui.components.turbine_page") + local core = require("graphics.core") local ColorMap = require("graphics.elements.colormap") local DisplayBox = require("graphics.elements.displaybox") local Div = require("graphics.elements.div") +local MultiPane = require("graphics.elements.multipane") local TextBox = require("graphics.elements.textbox") local PushButton = require("graphics.elements.controls.push_button") @@ -59,7 +66,19 @@ local function init(monitor) } } - local sidebar = Sidebar{parent=main,x=1,y=2,tabs=sidebar_tabs,fg_bg=cpair(colors.white,colors.gray),callback=function()end} + local mp_div = Div{parent=main,x=4,y=2} + + local pane_1 = home_page(mp_div) + local pane_2 = unit_page(mp_div) + local pane_3 = reactor_page(mp_div) + local pane_4 = boiler_page(mp_div) + local pane_5 = turbine_page(mp_div) + + local panes = { pane_1, pane_2, pane_3, pane_4, pane_5 } + + local multipane = MultiPane{parent=mp_div,x=1,y=1,panes=panes} + + local sidebar = Sidebar{parent=main,x=1,y=2,tabs=sidebar_tabs,fg_bg=cpair(colors.white,colors.gray),callback=multipane.set_value} return main end From a7ba0e43e8aa573cdad40054d9e33879f00aa75c Mon Sep 17 00:00:00 2001 From: Mikayla Date: Sun, 16 Apr 2023 23:50:16 +0000 Subject: [PATCH 26/51] #201 pocket comms establishes --- pocket/pocket.lua | 379 +++++++++++++++++++++++++++++++++++++++++ pocket/startup.lua | 76 +++++---- scada-common/comms.lua | 5 +- 3 files changed, 426 insertions(+), 34 deletions(-) diff --git a/pocket/pocket.lua b/pocket/pocket.lua index 2f537a3..11a8307 100644 --- a/pocket/pocket.lua +++ b/pocket/pocket.lua @@ -1,5 +1,384 @@ +local comms = require("scada-common.comms") +local log = require("scada-common.log") +local util = require("scada-common.util") +local PROTOCOL = comms.PROTOCOL +local DEVICE_TYPE = comms.DEVICE_TYPE +local ESTABLISH_ACK = comms.ESTABLISH_ACK +local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE +local CAPI_TYPE = comms.CAPI_TYPE local pocket = {} +-- pocket coordinator + supervisor communications +---@nodiscard +---@param version string pocket version +---@param modem table modem device +---@param local_port integer local pocket port +---@param sv_port integer port of supervisor +---@param api_port integer port of coordinator API +---@param range integer trusted device connection range +---@param sv_watchdog watchdog +---@param api_watchdog watchdog +function pocket.comms(version, modem, local_port, sv_port, api_port, range, sv_watchdog, api_watchdog) + local self = { + sv = { + linked = false, + seq_num = 0, + r_seq_num = nil, ---@type nil|integer + last_est_ack = ESTABLISH_ACK.ALLOW + }, + api = { + linked = false, + seq_num = 0, + r_seq_num = nil, ---@type nil|integer + last_est_ack = ESTABLISH_ACK.ALLOW + }, + establish_delay_counter = 0 + } + + comms.set_trusted_range(range) + + -- PRIVATE FUNCTIONS -- + + -- configure modem channels + local function _conf_channels() + modem.closeAll() + modem.open(local_port) + end + + _conf_channels() + + -- send a management packet to the supervisor + ---@param msg_type SCADA_MGMT_TYPE + ---@param msg table + local function _send_sv(msg_type, msg) + local s_pkt = comms.scada_packet() + local pkt = comms.mgmt_packet() + + pkt.make(msg_type, msg) + s_pkt.make(self.sv.seq_num, PROTOCOL.SCADA_MGMT, pkt.raw_sendable()) + + modem.transmit(sv_port, local_port, s_pkt.raw_sendable()) + self.sv.seq_num = self.sv.seq_num + 1 + end + + -- send a management packet to the coordinator + ---@param msg_type SCADA_MGMT_TYPE + ---@param msg table + local function _send_crd(msg_type, msg) + local s_pkt = comms.scada_packet() + local pkt = comms.mgmt_packet() + + pkt.make(msg_type, msg) + s_pkt.make(self.api.seq_num, PROTOCOL.SCADA_MGMT, pkt.raw_sendable()) + + modem.transmit(api_port, local_port, s_pkt.raw_sendable()) + self.api.seq_num = self.api.seq_num + 1 + end + + -- send a packet to the coordinator API + ---@param msg_type CAPI_TYPE + ---@param msg table + local function _send_api(msg_type, msg) + local s_pkt = comms.scada_packet() + local pkt = comms.capi_packet() + + pkt.make(msg_type, msg) + s_pkt.make(self.api.seq_num, PROTOCOL.COORD_API, pkt.raw_sendable()) + + modem.transmit(api_port, local_port, s_pkt.raw_sendable()) + self.api.seq_num = self.api.seq_num + 1 + end + + -- attempt supervisor connection establishment + local function _send_sv_establish() + _send_sv(SCADA_MGMT_TYPE.ESTABLISH, { comms.version, version, DEVICE_TYPE.PKT }) + end + + -- attempt coordinator API connection establishment + local function _send_api_establish() + _send_crd(SCADA_MGMT_TYPE.ESTABLISH, { comms.version, version, DEVICE_TYPE.PKT }) + end + + -- keep alive ack to supervisor + ---@param srv_time integer + local function _send_sv_keep_alive_ack(srv_time) + _send_sv(SCADA_MGMT_TYPE.KEEP_ALIVE, { srv_time, util.time() }) + end + + -- keep alive ack to coordinator + ---@param srv_time integer + local function _send_api_keep_alive_ack(srv_time) + _send_crd(SCADA_MGMT_TYPE.KEEP_ALIVE, { srv_time, util.time() }) + end + + -- PUBLIC FUNCTIONS -- + + ---@class pocket_comms + local public = {} + + -- reconnect a newly connected modem + ---@param new_modem table + function public.reconnect_modem(new_modem) + modem = new_modem + _conf_channels() + end + + -- close connection to the supervisor + function public.close_sv() + sv_watchdog.cancel() + self.sv.linked = false + _send_sv(SCADA_MGMT_TYPE.CLOSE, {}) + end + + -- close connection to coordinator API server + function public.close_api() + api_watchdog.cancel() + self.api.linked = false + _send_crd(SCADA_MGMT_TYPE.CLOSE, {}) + end + + -- close the connections to the servers + function public.close() + public.close_sv() + public.close_api() + end + + -- attempt to re-link if any of the dependent links aren't active + function public.link_update() + if not self.sv.linked then + if self.establish_delay_counter <= 0 then + _send_sv_establish() + self.establish_delay_counter = 4 + else + self.establish_delay_counter = self.establish_delay_counter - 1 + end + elseif not self.api.linked then + if self.establish_delay_counter <= 0 then + _send_api_establish() + self.establish_delay_counter = 4 + else + self.establish_delay_counter = self.establish_delay_counter - 1 + end + else + -- linked, all good! + end + end + + -- parse a packet + ---@param side string + ---@param sender integer + ---@param reply_to integer + ---@param message any + ---@param distance integer + ---@return mgmt_frame|capi_frame|nil packet + function public.parse_packet(side, sender, reply_to, message, distance) + local pkt = nil + local s_pkt = comms.scada_packet() + + -- parse packet as generic SCADA packet + s_pkt.receive(side, sender, reply_to, message, distance) + + if s_pkt.is_valid() then + -- get as SCADA management packet + if s_pkt.protocol() == PROTOCOL.SCADA_MGMT then + local mgmt_pkt = comms.mgmt_packet() + if mgmt_pkt.decode(s_pkt) then + pkt = mgmt_pkt.get() + end + -- get as coordinator API packet + elseif s_pkt.protocol() == PROTOCOL.COORD_API then + local capi_pkt = comms.capi_packet() + if capi_pkt.decode(s_pkt) then + pkt = capi_pkt.get() + end + else + log.debug("attempted parse of illegal packet type " .. s_pkt.protocol(), true) + end + end + + return pkt + end + + -- handle a packet + ---@param packet mgmt_frame|capi_frame|nil + function public.handle_packet(packet) + if packet ~= nil then + local protocol = packet.scada_frame.protocol() + local r_port = packet.scada_frame.remote_port() + + if r_port == api_port then + -- check sequence number + if self.api.r_seq_num == nil then + self.api.r_seq_num = packet.scada_frame.seq_num() + elseif self.connected and self.api.r_seq_num >= packet.scada_frame.seq_num() then + log.warning("sequence out-of-order: last = " .. self.api.r_seq_num .. ", new = " .. packet.scada_frame.seq_num()) + return + else + self.api.r_seq_num = packet.scada_frame.seq_num() + end + + -- feed watchdog on valid sequence number + api_watchdog.feed() + + if protocol == PROTOCOL.COORD_API then + ---@cast packet capi_frame + elseif protocol == PROTOCOL.SCADA_MGMT then + ---@cast packet mgmt_frame + if packet.type == SCADA_MGMT_TYPE.ESTABLISH then + -- connection with coordinator established + if packet.length == 1 then + local est_ack = packet.data[1] + + if est_ack == ESTABLISH_ACK.ALLOW then + log.info("coordinator connection established") + self.establish_delay_counter = 0 + self.api.linked = true + elseif est_ack == ESTABLISH_ACK.DENY then + if self.api.last_est_ack ~= est_ack then + log.info("coordinator connection denied") + end + elseif est_ack == ESTABLISH_ACK.COLLISION then + if self.api.last_est_ack ~= est_ack then + log.info("coordinator connection denied due to collision") + end + elseif est_ack == ESTABLISH_ACK.BAD_VERSION then + if self.api.last_est_ack ~= est_ack then + log.info("coordinator comms version mismatch") + end + else + log.debug("coordinator SCADA_MGMT establish packet reply unsupported") + end + + self.api.last_est_ack = est_ack + else + log.debug("coordinator SCADA_MGMT establish packet length mismatch") + end + elseif self.api.linked then + if packet.type == SCADA_MGMT_TYPE.KEEP_ALIVE then + -- keep alive request received, echo back + if packet.length == 1 then + local timestamp = packet.data[1] + local trip_time = util.time() - timestamp + + if trip_time > 750 then + log.warning("pocket coordinator KEEP_ALIVE trip time > 750ms (" .. trip_time .. "ms)") + end + + -- log.debug("pocket coordinator RTT = " .. trip_time .. "ms") + + _send_api_keep_alive_ack(timestamp) + else + log.debug("coordinator SCADA keep alive packet length mismatch") + end + elseif packet.type == SCADA_MGMT_TYPE.CLOSE then + -- handle session close + api_watchdog.cancel() + self.api.linked = false + log.info("coordinator server connection closed by remote host") + else + log.debug("received unknown SCADA_MGMT packet type " .. packet.type .. " from coordinator") + end + else + log.debug("discarding coordinator non-link SCADA_MGMT packet before linked") + end + else + log.debug("illegal packet type " .. protocol .. " from coordinator", true) + end + elseif r_port == sv_port then + -- check sequence number + if self.sv.r_seq_num == nil then + self.sv.r_seq_num = packet.scada_frame.seq_num() + elseif self.connected and self.sv.r_seq_num >= packet.scada_frame.seq_num() then + log.warning("sequence out-of-order: last = " .. self.sv.r_seq_num .. ", new = " .. packet.scada_frame.seq_num()) + return + else + self.sv.r_seq_num = packet.scada_frame.seq_num() + end + + -- feed watchdog on valid sequence number + sv_watchdog.feed() + + -- handle packet + if protocol == PROTOCOL.SCADA_MGMT then + ---@cast packet mgmt_frame + if packet.type == SCADA_MGMT_TYPE.ESTABLISH then + -- connection with supervisor established + if packet.length == 1 then + local est_ack = packet.data[1] + + if est_ack == ESTABLISH_ACK.ALLOW then + log.info("supervisor connection established") + self.establish_delay_counter = 0 + self.sv.linked = true + elseif est_ack == ESTABLISH_ACK.DENY then + if self.sv.last_est_ack ~= est_ack then + log.info("supervisor connection denied") + end + elseif est_ack == ESTABLISH_ACK.COLLISION then + if self.sv.last_est_ack ~= est_ack then + log.info("supervisor connection denied due to collision") + end + elseif est_ack == ESTABLISH_ACK.BAD_VERSION then + if self.sv.last_est_ack ~= est_ack then + log.info("supervisor comms version mismatch") + end + else + log.debug("supervisor SCADA_MGMT establish packet reply unsupported") + end + + self.sv.last_est_ack = est_ack + else + log.debug("supervisor SCADA_MGMT establish packet length mismatch") + end + elseif self.sv.linked then + if packet.type == SCADA_MGMT_TYPE.KEEP_ALIVE then + -- keep alive request received, echo back + if packet.length == 1 then + local timestamp = packet.data[1] + local trip_time = util.time() - timestamp + + if trip_time > 750 then + log.warning("pocket supervisor KEEP_ALIVE trip time > 750ms (" .. trip_time .. "ms)") + end + + -- log.debug("pocket supervisor RTT = " .. trip_time .. "ms") + + _send_sv_keep_alive_ack(timestamp) + else + log.debug("supervisor SCADA keep alive packet length mismatch") + end + elseif packet.type == SCADA_MGMT_TYPE.CLOSE then + -- handle session close + sv_watchdog.cancel() + self.sv.linked = false + log.info("supervisor server connection closed by remote host") + else + log.debug("received unknown SCADA_MGMT packet type " .. packet.type .. " from supervisor") + end + else + log.debug("discarding supervisor non-link SCADA_MGMT packet before linked") + end + else + log.debug("illegal packet type " .. protocol .. " from supervisor", true) + end + else + log.debug("received packet from unconfigured channel " .. r_port, true) + end + end + end + + -- check if we are still linked with the supervisor + ---@nodiscard + function public.is_sv_linked() return self.sv.linked end + + -- check if we are still linked with the coordinator + ---@nodiscard + function public.is_api_linked() return self.api.linked end + + return public +end + + return pocket diff --git a/pocket/startup.lua b/pocket/startup.lua index 90837d3..3bd8069 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -16,11 +16,9 @@ local config = require("pocket.config") local pocket = require("pocket.pocket") local renderer = require("pocket.renderer") -local POCKET_VERSION = "alpha-v0.1.1" +local POCKET_VERSION = "alpha-v0.2.0" --- local print = util.print local println = util.println --- local print_ts = util.print_ts local println_ts = util.println_ts ---------------------------------------- @@ -72,19 +70,25 @@ local function main() local modem = ppm.get_wireless_modem() if modem == nil then println("startup> wireless modem not found: please craft the pocket computer with a wireless modem") - log.fatal("no wireless modem on startup") + log.fatal("startup> no wireless modem on startup") return end - -- create connection watchdog - local conn_watchdog = util.new_watchdog(config.COMMS_TIMEOUT) - conn_watchdog.cancel() - log.debug("startup> conn watchdog created") + -- create connection watchdogs + local conn_wd = { + sv = util.new_watchdog(config.COMMS_TIMEOUT), + api = util.new_watchdog(config.COMMS_TIMEOUT) + } + + conn_wd.sv.cancel() + conn_wd.api.cancel() + + log.debug("startup> conn watchdogs created") -- start comms, open all channels - -- local pocket_comms = pocket.comms(POCKET_VERSION, modem, config.SCADA_SV_PORT, config.SCADA_API_PORT, - -- config.LISTEN_PORT, config.TRUSTED_RANGE, conn_watchdog) - -- log.debug("startup> comms init") + local pocket_comms = pocket.comms(POCKET_VERSION, modem, config.SCADA_SV_PORT, config.SCADA_API_PORT, + config.LISTEN_PORT, config.TRUSTED_RANGE, conn_wd.sv, conn_wd.api) + log.debug("startup> comms init") -- base loop clock (2Hz, 10 ticks) local MAIN_CLOCK = 0.5 @@ -98,7 +102,7 @@ local function main() if not ui_ok then renderer.close_ui() println_ts(util.c("UI error: ", message)) - log.error(util.c("GUI crashed with error ", message)) + log.error(util.c("startup> GUI crashed with error ", message)) else -- start clock loop_clock.start() @@ -109,8 +113,9 @@ local function main() ---------------------------------------- if ui_ok then - -- start connection watchdog - conn_watchdog.feed() + -- start connection watchdogs + conn_wd.sv.feed() + conn_wd.api.feed() log.debug("startup> conn watchdog started") end @@ -122,30 +127,37 @@ local function main() if event == "timer" then if loop_clock.is_clock(param1) then -- main loop tick - loop_clock.start() - elseif conn_watchdog.is_timer(param1) then - -- supervisor watchdog timeout - log.info("server timeout") - -- pocket_comms.close() + -- relink if necessary + pocket_comms.link_update() + + loop_clock.start() + elseif conn_wd.sv.is_timer(param1) then + -- supervisor watchdog timeout + log.info("supervisor server timeout") + pocket_comms.close_sv() + elseif conn_wd.api.is_timer(param1) then + -- coordinator watchdog timeout + log.info("coordinator api server timeout") + pocket_comms.close_api() else -- a non-clock/main watchdog timer event - -- notify timer callback dispatcher tcallbackdsp.handle(param1) end elseif event == "modem_message" then -- got a packet - -- local packet = pocket_comms.parse_packet(param1, param2, param3, param4, param5) - -- pocket_comms.handle_packet(packet) + local packet = pocket_comms.parse_packet(param1, param2, param3, param4, param5) + pocket_comms.handle_packet(packet) - -- -- check if it was a disconnect - -- if not pocket_comms.is_linked() then - -- log_comms("supervisor closed connection") - - -- -- close connection - -- pocket_comms.close() - -- end + -- check if it was a disconnect + if not pocket_comms.is_sv_linked() then + log.info("supervisor closed connection") + pocket_comms.close_sv() + elseif not pocket_comms.is_api_linked() then + log.info("coordinator api closed connection") + pocket_comms.close_api() + end elseif event == "mouse_click" then -- handle a monitor touch event renderer.handle_mouse(core.events.touch(param1, param2, param3)) @@ -153,9 +165,9 @@ local function main() -- check for termination request if event == "terminate" or ppm.should_terminate() then - log.info("terminate requested, closing connections...") - -- pocket_comms.close() - log.info("supervisor connection closed") + log.info("terminate requested, closing server connections...") + pocket_comms.close() + log.info("connections closed") break end end diff --git a/scada-common/comms.lua b/scada-common/comms.lua index 497c3b3..b266a1a 100644 --- a/scada-common/comms.lua +++ b/scada-common/comms.lua @@ -2,7 +2,7 @@ -- Communications -- -local log = require("scada-common.log") +local log = require("scada-common.log") ---@class comms local comms = {} @@ -74,7 +74,8 @@ local DEVICE_TYPE = { PLC = 0, -- PLC device type for establish RTU = 1, -- RTU device type for establish SV = 2, -- supervisor device type for establish - CRDN = 3 -- coordinator device type for establish + CRDN = 3, -- coordinator device type for establish + PKT = 4 -- pocket device type for establish } ---@enum PLC_AUTO_ACK From 14dc8149252030dae1c829598746dbdc06b66aa1 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Mon, 17 Apr 2023 00:22:47 +0000 Subject: [PATCH 27/51] #201 removed redundant close handling --- pocket/startup.lua | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/pocket/startup.lua b/pocket/startup.lua index 3bd8069..37a94e9 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -16,7 +16,7 @@ local config = require("pocket.config") local pocket = require("pocket.pocket") local renderer = require("pocket.renderer") -local POCKET_VERSION = "alpha-v0.2.0" +local POCKET_VERSION = "alpha-v0.2.1" local println = util.println local println_ts = util.println_ts @@ -149,15 +149,6 @@ local function main() -- got a packet local packet = pocket_comms.parse_packet(param1, param2, param3, param4, param5) pocket_comms.handle_packet(packet) - - -- check if it was a disconnect - if not pocket_comms.is_sv_linked() then - log.info("supervisor closed connection") - pocket_comms.close_sv() - elseif not pocket_comms.is_api_linked() then - log.info("coordinator api closed connection") - pocket_comms.close_api() - end elseif event == "mouse_click" then -- handle a monitor touch event renderer.handle_mouse(core.events.touch(param1, param2, param3)) From 93776a0421e7e1251538fa2d49453ac81d616e3c Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Mon, 17 Apr 2023 15:40:30 -0400 Subject: [PATCH 28/51] update luacheck args and copied lua extension configs to workspace --- .github/workflows/check.yml | 14 +++++++++----- .vscode/settings.json | 38 ++++++++++++++++++++----------------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index e0bcf50..4252af3 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -21,8 +21,12 @@ jobs: - name: Luacheck uses: lunarmodules/luacheck@v1.1.0 with: - # -a = disable warning for unused arguments - # -i 121 = Setting a read-only global variable. - # -u 512 = Loop can be executed at most once. - # -i 542 = An empty if branch. - args: . --no-max-line-length -a -i 121 512 542 --exclude-files ./lockbox/* ./*/config.lua --globals _HOST term fs peripheral rs bit parallel colors textutils shell settings window read periphemu http os + # Argument Explanations + # -a = Disable warning for unused arguments + # -i 121 = Setting a read-only global variable + # 512 = Loop can be executed at most once + # 542 = An empty if branch + # --no-max-line-length = Disable warnings for long line lengths + # --exclude-files ... = Exclude lockbox library (external) and config files + # --globals ... = Override all globals overridden in .vscode/settings.json AND 'os' since CraftOS 'os' differs from Lua's 'os' + args: . --no-max-line-length -a -i 121 512 542 --exclude-files ./lockbox/* ./*/config.lua --globals os _HOST bit colors fs http parllel periphemu peripheral read rs settings shell term textutils window diff --git a/.vscode/settings.json b/.vscode/settings.json index 732eb4a..75b7e0e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,22 +1,26 @@ { "Lua.diagnostics.globals": [ - "term", - "fs", - "peripheral", - "rs", - "bit", - "parallel", - "colors", - "textutils", - "shell", - "settings", - "window", - "read", - "periphemu", "_HOST", - "http" + "bit", + "colors", + "fs", + "http", + "parallel", + "periphemu", + "peripheral", + "read", + "rs", + "settings", + "shell", + "term", + "textutils", + "window" ], - "Lua.diagnostics.disable": [ - "duplicate-set-field" - ] + "Lua.diagnostics.severity": { + "unused-local": "Information", + "unused-vararg": "Information", + "unused-function": "Information", + "unused-label": "Information" + }, + "Lua.hint.setType": true } From 33c570075c7688484b3482ec6fd6f55fa6347da7 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Mon, 17 Apr 2023 19:48:03 -0400 Subject: [PATCH 29/51] supervisor code cleanup --- supervisor/session/coordinator.lua | 4 +++- supervisor/session/plc.lua | 4 +++- supervisor/session/rtu.lua | 3 ++- supervisor/session/svsessions.lua | 11 +++++------ supervisor/startup.lua | 6 +++--- supervisor/supervisor.lua | 1 + 6 files changed, 17 insertions(+), 12 deletions(-) diff --git a/supervisor/session/coordinator.lua b/supervisor/session/coordinator.lua index ad706e8..238765f 100644 --- a/supervisor/session/coordinator.lua +++ b/supervisor/session/coordinator.lua @@ -173,7 +173,7 @@ function coordinator.new_session(id, in_queue, out_queue, timeout, facility) end -- handle a packet - ---@param pkt crdn_frame + ---@param pkt mgmt_frame|crdn_frame local function _handle_packet(pkt) -- check sequence number if self.r_seq_num == nil then @@ -190,6 +190,7 @@ function coordinator.new_session(id, in_queue, out_queue, timeout, facility) -- process packet if pkt.scada_frame.protocol() == PROTOCOL.SCADA_MGMT then + ---@cast pkt mgmt_frame if pkt.type == SCADA_MGMT_TYPE.KEEP_ALIVE then -- keep alive reply if pkt.length == 2 then @@ -214,6 +215,7 @@ function coordinator.new_session(id, in_queue, out_queue, timeout, facility) log.debug(log_header .. "handler received unsupported SCADA_MGMT packet type " .. pkt.type) end elseif pkt.scada_frame.protocol() == PROTOCOL.SCADA_CRDN then + ---@cast pkt crdn_frame if pkt.type == SCADA_CRDN_TYPE.INITIAL_BUILDS then -- acknowledgement to coordinator receiving builds self.acks.builds = true diff --git a/supervisor/session/plc.lua b/supervisor/session/plc.lua index 40efd8c..fd0d0f8 100644 --- a/supervisor/session/plc.lua +++ b/supervisor/session/plc.lua @@ -279,7 +279,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) end -- handle a packet - ---@param pkt rplc_frame + ---@param pkt mgmt_frame|rplc_frame local function _handle_packet(pkt) -- check sequence number if self.r_seq_num == nil then @@ -293,6 +293,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) -- process packet if pkt.scada_frame.protocol() == PROTOCOL.RPLC then + ---@cast pkt rplc_frame -- check reactor ID if pkt.id ~= reactor_id then log.warning(log_header .. "RPLC packet with ID not matching reactor ID: reactor " .. reactor_id .. " != " .. pkt.id) @@ -469,6 +470,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) log.debug(log_header .. "handler received unsupported RPLC packet type " .. pkt.type) end elseif pkt.scada_frame.protocol() == PROTOCOL.SCADA_MGMT then + ---@cast pkt mgmt_frame if pkt.type == SCADA_MGMT_TYPE.KEEP_ALIVE then -- keep alive reply if pkt.length == 2 then diff --git a/supervisor/session/rtu.lua b/supervisor/session/rtu.lua index da5648c..9357c71 100644 --- a/supervisor/session/rtu.lua +++ b/supervisor/session/rtu.lua @@ -226,12 +226,13 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili -- process packet if pkt.scada_frame.protocol() == PROTOCOL.MODBUS_TCP then + ---@cast pkt modbus_frame if self.units[pkt.unit_id] ~= nil then local unit = self.units[pkt.unit_id] ---@type unit_session ----@diagnostic disable-next-line: param-type-mismatch unit.handle_packet(pkt) end elseif pkt.scada_frame.protocol() == PROTOCOL.SCADA_MGMT then + ---@cast pkt mgmt_frame -- handle management packet if pkt.type == SCADA_MGMT_TYPE.KEEP_ALIVE then -- keep alive reply diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index aa3506b..9ed462d 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -123,7 +123,7 @@ local function _iterate(sessions) end -- cleanly close a session ----@param session plc_session_struct|rtu_session_struct +---@param session plc_session_struct|rtu_session_struct|coord_session_struct local function _shutdown(session) session.open = false session.instance.close() @@ -143,10 +143,8 @@ end ---@param sessions table local function _close(sessions) for i = 1, #sessions do - local session = sessions[i] ---@type plc_session_struct|rtu_session_struct - if session.open then - _shutdown(session) - end + local session = sessions[i] ---@type plc_session_struct|rtu_session_struct|coord_session_struct + if session.open then _shutdown(session) end end end @@ -155,7 +153,7 @@ end ---@param timer_event number local function _check_watchdogs(sessions, timer_event) for i = 1, #sessions do - local session = sessions[i] ---@type plc_session_struct|rtu_session_struct + local session = sessions[i] ---@type plc_session_struct|rtu_session_struct|coord_session_struct if session.open then local triggered = session.instance.check_wd(timer_event) if triggered then @@ -172,6 +170,7 @@ end local function _free_closed(sessions) local f = function (session) return session.open end + ---@param session plc_session_struct|rtu_session_struct|coord_session_struct local on_delete = function (session) log.debug(util.c("free'ing closed ", session.s_type, " session ", session.instance.get_id(), " on remote port ", session.r_port)) diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 87bd902..68db989 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -9,12 +9,12 @@ local log = require("scada-common.log") local ppm = require("scada-common.ppm") local util = require("scada-common.util") -local svsessions = require("supervisor.session.svsessions") - local config = require("supervisor.config") local supervisor = require("supervisor.supervisor") -local SUPERVISOR_VERSION = "v0.14.4" +local svsessions = require("supervisor.session.svsessions") + +local SUPERVISOR_VERSION = "v0.14.5" local println = util.println local println_ts = util.println_ts diff --git a/supervisor/supervisor.lua b/supervisor/supervisor.lua index 937dac8..99226fb 100644 --- a/supervisor/supervisor.lua +++ b/supervisor/supervisor.lua @@ -22,6 +22,7 @@ local println = util.println ---@param dev_listen integer listening port for PLC/RTU devices ---@param coord_listen integer listening port for coordinator ---@param range integer trusted device connection range +---@diagnostic disable-next-line: unused-local function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen, coord_listen, range) local self = { last_est_acks = {} From 46607dd690a19953a5fccf1802d020a147d767b0 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Tue, 18 Apr 2023 15:28:46 +0000 Subject: [PATCH 30/51] #208 indicate emergency coolant control on PLC front panel --- .devcontainer/devcontainer.json | 3 +-- reactor-plc/databus.lua | 4 +++- reactor-plc/panel/front_panel.lua | 23 +++++++++++++++++++++++ reactor-plc/panel/style.lua | 2 +- reactor-plc/plc.lua | 2 +- reactor-plc/startup.lua | 2 +- 6 files changed, 30 insertions(+), 6 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 9cdcab8..ed3acf3 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,8 +6,7 @@ "vscode": { "extensions": [ "sumneko.lua", - "jackmacwindows.vscode-computercraft", - "jackmacwindows.craftos-pc" + "jackmacwindows.vscode-computercraft" ] } } diff --git a/reactor-plc/databus.lua b/reactor-plc/databus.lua index eeb2260..beee265 100644 --- a/reactor-plc/databus.lua +++ b/reactor-plc/databus.lua @@ -76,7 +76,8 @@ end -- transmit RPS data across the bus ---@param tripped boolean RPS tripped ---@param status table RPS status -function databus.tx_rps(tripped, status) +---@param emer_cool_active boolean RPS activated the emergency coolant +function databus.tx_rps(tripped, status, emer_cool_active) dbus_iface.ps.publish("rps_scram", tripped) dbus_iface.ps.publish("rps_damage", status[1]) dbus_iface.ps.publish("rps_high_temp", status[2]) @@ -89,6 +90,7 @@ function databus.tx_rps(tripped, status) dbus_iface.ps.publish("rps_manual", status[9]) dbus_iface.ps.publish("rps_automatic", status[10]) dbus_iface.ps.publish("rps_sysfail", status[11]) + dbus_iface.ps.publish("emer_cool", emer_cool_active) end -- link a function to receive data from the bus diff --git a/reactor-plc/panel/front_panel.lua b/reactor-plc/panel/front_panel.lua index f875b5d..dee017b 100644 --- a/reactor-plc/panel/front_panel.lua +++ b/reactor-plc/panel/front_panel.lua @@ -4,6 +4,7 @@ local util = require("scada-common.util") +local config = require("reactor-plc.config") local databus = require("reactor-plc.databus") local style = require("reactor-plc.panel.style") @@ -35,6 +36,10 @@ local function init(monitor) local header = TextBox{parent=panel,y=1,text="REACTOR PLC - UNIT ?",alignment=TEXT_ALIGN.CENTER,height=1,fg_bg=style.header} databus.rx_field("unit_id", function (id) header.set_value(util.c("REACTOR PLC - UNIT ", id)) end) + -- + -- system indicators + -- + local system = Div{parent=panel,width=14,height=18,x=2,y=3} local init_ok = LED{parent=system,label="STATUS",colors=cpair(colors.green,colors.red)} @@ -67,6 +72,10 @@ local function init(monitor) databus.rx_field("routine__comms_rx", rt_cmrx.update) databus.rx_field("routine__spctl", rt_sctl.update) + -- + -- status & controls + -- + local status = Div{parent=panel,width=19,height=18,x=17,y=3} local active = LED{parent=status,x=2,width=12,label="RCT ACTIVE",colors=cpair(colors.green,colors.green_off)} @@ -83,6 +92,16 @@ local function init(monitor) databus.rx_field("reactor_active", active.update) databus.rx_field("rps_scram", scram.update) + -- only show emergency coolant LED if emergency coolant is configured for this device + if type(config.EMERGENCY_COOL) == "table" then + local emer_cool = LED{parent=status,x=9,width=14,label="EMER COOLANT",colors=cpair(colors.yellow,colors.yellow_off)} + databus.rx_field("emer_cool", emer_cool.update) + end + + -- + -- about footer + -- + local about = Rectangle{parent=panel,width=32,height=3,x=2,y=16,border=border(1,colors.ivory),thin=true,fg_bg=cpair(colors.black,colors.white)} local fw_v = TextBox{parent=about,x=2,y=1,text="FW: v00.00.00",alignment=TEXT_ALIGN.LEFT,height=1} local comms_v = TextBox{parent=about,x=17,y=1,text="NT: v00.00.00",alignment=TEXT_ALIGN.LEFT,height=1} @@ -90,6 +109,10 @@ local function init(monitor) databus.rx_field("version", function (version) fw_v.set_value(util.c("FW: ", version)) end) databus.rx_field("comms_version", function (version) comms_v.set_value(util.c("NT: v", version)) end) + -- + -- rps list + -- + local rps = Rectangle{parent=panel,width=16,height=16,x=36,y=3,border=border(1,colors.lightGray),thin=true,fg_bg=cpair(colors.black,colors.lightGray)} local rps_man = LED{parent=rps,label="MANUAL",colors=cpair(colors.red,colors.red_off)} local rps_auto = LED{parent=rps,label="AUTOMATIC",colors=cpair(colors.red,colors.red_off)} diff --git a/reactor-plc/panel/style.lua b/reactor-plc/panel/style.lua index 01b00c9..31039d4 100644 --- a/reactor-plc/panel/style.lua +++ b/reactor-plc/panel/style.lua @@ -22,7 +22,7 @@ style.header = cpair(colors.black, colors.lightGray) style.colors = { { c = colors.red, hex = 0xdf4949 }, -- RED ON { c = colors.orange, hex = 0xffb659 }, - { c = colors.yellow, hex = 0xf9fb53 }, + { c = colors.yellow, hex = 0xf9fb53 }, -- YELLOW ON { c = colors.lime, hex = 0x16665a }, -- GREEN OFF { c = colors.green, hex = 0x6be551 }, -- GREEN ON { c = colors.cyan, hex = 0x34bac8 }, diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index 2faefb5..304f3a6 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -381,7 +381,7 @@ function plc.rps_init(reactor, is_formed, emer_cool) _set_emer_cool(self.state[state_keys.low_coolant]) -- report RPS status - databus.tx_rps(self.tripped, self.state) + databus.tx_rps(self.tripped, self.state, self.emer_cool_active) return self.tripped, status, first_trip end diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 010c36e..ed56dec 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.1.5" +local R_PLC_VERSION = "v1.1.6" local println = util.println local println_ts = util.println_ts From 438ab55f4f2c5aabeb89cad97905ca5a3b183b09 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Tue, 18 Apr 2023 13:46:00 -0400 Subject: [PATCH 31/51] updated lua diagnostics config --- .vscode/settings.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 75b7e0e..3bf857e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -22,5 +22,8 @@ "unused-function": "Information", "unused-label": "Information" }, - "Lua.hint.setType": true + "Lua.hint.setType": true, + "Lua.diagnostics.disable": [ + "duplicate-set-field" + ] } From d295c2b3c3e7ccf61df60a9f628f0cd8f884b443 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Tue, 18 Apr 2023 13:47:06 -0400 Subject: [PATCH 32/51] #201 added pocket connecting screens --- pocket/coreio.lua | 35 ++++++++++++++++++ pocket/pocket.lua | 29 ++++++++++++--- pocket/renderer.lua | 3 -- pocket/startup.lua | 5 ++- pocket/ui/components/conn_waiting.lua | 8 ++--- pocket/ui/main.lua | 51 ++++++++++++++++++++------- 6 files changed, 105 insertions(+), 26 deletions(-) create mode 100644 pocket/coreio.lua diff --git a/pocket/coreio.lua b/pocket/coreio.lua new file mode 100644 index 0000000..6f43dfd --- /dev/null +++ b/pocket/coreio.lua @@ -0,0 +1,35 @@ +-- +-- Core I/O - Pocket Central I/O Management +-- + +local psil = require("scada-common.psil") + +local coreio = {} + +---@class pocket_core_io +local io = { + ps = psil.create() +} + +---@enum POCKET_LINK_STATE +local LINK_STATE = { + UNLINKED = 0, + SV_LINK_ONLY = 1, + API_LINK_ONLY = 2, + LINKED = 3 +} + +coreio.LINK_STATE = LINK_STATE + +-- get the core PSIL +function coreio.core_ps() + return io.ps +end + +-- set network link state +---@param state POCKET_LINK_STATE +function coreio.report_link_state(state) + io.ps.publish("link_state", state) +end + +return coreio diff --git a/pocket/pocket.lua b/pocket/pocket.lua index 11a8307..04feca3 100644 --- a/pocket/pocket.lua +++ b/pocket/pocket.lua @@ -1,6 +1,8 @@ -local comms = require("scada-common.comms") -local log = require("scada-common.log") -local util = require("scada-common.util") +local comms = require("scada-common.comms") +local log = require("scada-common.log") +local util = require("scada-common.util") + +local coreio = require("pocket.coreio") local PROTOCOL = comms.PROTOCOL local DEVICE_TYPE = comms.DEVICE_TYPE @@ -8,6 +10,8 @@ local ESTABLISH_ACK = comms.ESTABLISH_ACK local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE local CAPI_TYPE = comms.CAPI_TYPE +local LINK_STATE = coreio.LINK_STATE + local pocket = {} -- pocket coordinator + supervisor communications @@ -205,10 +209,13 @@ function pocket.comms(version, modem, local_port, sv_port, api_port, range, sv_w ---@param packet mgmt_frame|capi_frame|nil function public.handle_packet(packet) if packet ~= nil then - local protocol = packet.scada_frame.protocol() + local l_port = packet.scada_frame.local_port() local r_port = packet.scada_frame.remote_port() + local protocol = packet.scada_frame.protocol() - if r_port == api_port then + if l_port ~= local_port then + log.debug("received packet on unconfigured channel " .. l_port, true) + elseif r_port == api_port then -- check sequence number if self.api.r_seq_num == nil then self.api.r_seq_num = packet.scada_frame.seq_num() @@ -235,6 +242,12 @@ function pocket.comms(version, modem, local_port, sv_port, api_port, range, sv_w log.info("coordinator connection established") self.establish_delay_counter = 0 self.api.linked = true + + if self.sv.linked then + coreio.report_link_state(LINK_STATE.LINKED) + else + coreio.report_link_state(LINK_STATE.API_LINK_ONLY) + end elseif est_ack == ESTABLISH_ACK.DENY then if self.api.last_est_ack ~= est_ack then log.info("coordinator connection denied") @@ -312,6 +325,12 @@ function pocket.comms(version, modem, local_port, sv_port, api_port, range, sv_w log.info("supervisor connection established") self.establish_delay_counter = 0 self.sv.linked = true + + if self.api.linked then + coreio.report_link_state(LINK_STATE.LINKED) + else + coreio.report_link_state(LINK_STATE.SV_LINK_ONLY) + end elseif est_ack == ESTABLISH_ACK.DENY then if self.sv.last_est_ack ~= est_ack then log.info("supervisor connection denied") diff --git a/pocket/renderer.lua b/pocket/renderer.lua index d394acc..bd3f66e 100644 --- a/pocket/renderer.lua +++ b/pocket/renderer.lua @@ -2,9 +2,6 @@ -- Graphics Rendering Control -- -local log = require("scada-common.log") -local util = require("scada-common.util") - local main_view = require("pocket.ui.main") local style = require("pocket.ui.style") diff --git a/pocket/startup.lua b/pocket/startup.lua index 37a94e9..3ef9b8e 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -13,6 +13,7 @@ local util = require("scada-common.util") local core = require("graphics.core") local config = require("pocket.config") +local coreio = require("pocket.coreio") local pocket = require("pocket.pocket") local renderer = require("pocket.renderer") @@ -63,9 +64,11 @@ local function main() ppm.mount_all() ---------------------------------------- - -- setup communications + -- setup communications & clocks ---------------------------------------- + coreio.report_link_state(coreio.LINK_STATE.UNLINKED) + -- get the communications modem local modem = ppm.get_wireless_modem() if modem == nil then diff --git a/pocket/ui/components/conn_waiting.lua b/pocket/ui/components/conn_waiting.lua index d83d09e..bca56e9 100644 --- a/pocket/ui/components/conn_waiting.lua +++ b/pocket/ui/components/conn_waiting.lua @@ -25,11 +25,11 @@ local function init(parent, y, is_api) local waiting_x = math.floor(parent.width() / 2) - 1 if is_api then - TextBox{parent=root,text="Connecting to API",alignment=TEXT_ALIGN.CENTER,y=1,height=1,fg_bg=cpair(colors.white,style.root.bkg)} - WaitingAnim{parent=root,x=waiting_x,y=3,fg_bg=cpair(colors.blue,style.root.bkg)} + WaitingAnim{parent=root,x=waiting_x,y=1,fg_bg=cpair(colors.blue,style.root.bkg)} + TextBox{parent=root,text="Connecting to API",alignment=TEXT_ALIGN.CENTER,y=5,height=1,fg_bg=cpair(colors.white,style.root.bkg)} else - TextBox{parent=root,text="Connecting to Supervisor",alignment=TEXT_ALIGN.CENTER,y=1,height=1,fg_bg=cpair(colors.white,style.root.bkg)} - WaitingAnim{parent=root,x=waiting_x,y=3,fg_bg=cpair(colors.green,style.root.bkg)} + WaitingAnim{parent=root,x=waiting_x,y=1,fg_bg=cpair(colors.green,style.root.bkg)} + TextBox{parent=root,text="Connecting to Supervisor",alignment=TEXT_ALIGN.CENTER,y=5,height=1,fg_bg=cpair(colors.white,style.root.bkg)} end return root diff --git a/pocket/ui/main.lua b/pocket/ui/main.lua index 3360b9b..630991a 100644 --- a/pocket/ui/main.lua +++ b/pocket/ui/main.lua @@ -4,6 +4,8 @@ local util = require("scada-common.util") +local coreio = require("pocket.coreio") + local style = require("pocket.ui.style") local conn_waiting = require("pocket.ui.components.conn_waiting") @@ -38,10 +40,36 @@ local function init(monitor) local main = DisplayBox{window=monitor,fg_bg=style.root} -- window header message - local header = TextBox{parent=main,y=1,text="",alignment=TEXT_ALIGN.LEFT,height=1,fg_bg=style.header} + TextBox{parent=main,y=1,text="",alignment=TEXT_ALIGN.LEFT,height=1,fg_bg=style.header} - -- local api_wait = conn_waiting(main, 8, true) - -- local sv_wait = conn_waiting(main, 8, false) + -- + -- root panel panes (connection screens + main screen) + -- + + local root_pane_div = Div{parent=main,x=1,y=2} + + local conn_sv_wait = conn_waiting(root_pane_div, 6, false) + local conn_api_wait = conn_waiting(root_pane_div, 6, true) + local main_pane = Div{parent=main,x=1,y=2} + local root_panes = { conn_sv_wait, conn_api_wait, main_pane } + + local root_pane = MultiPane{parent=root_pane_div,x=1,y=1,panes=root_panes} + + coreio.core_ps().subscribe("link_state", function (state) + if state == coreio.LINK_STATE.UNLINKED or state == coreio.LINK_STATE.API_LINK_ONLY then + root_pane.set_value(1) + elseif state == coreio.LINK_STATE.SV_LINK_ONLY then + root_pane.set_value(2) + else + root_pane.set_value(3) + end + end) + + -- + -- main page panel panes & sidebar + -- + + local page_div = Div{parent=main_pane,x=4,y=2} local sidebar_tabs = { { @@ -66,19 +94,16 @@ local function init(monitor) } } - local mp_div = Div{parent=main,x=4,y=2} - - local pane_1 = home_page(mp_div) - local pane_2 = unit_page(mp_div) - local pane_3 = reactor_page(mp_div) - local pane_4 = boiler_page(mp_div) - local pane_5 = turbine_page(mp_div) - + local pane_1 = home_page(page_div) + local pane_2 = unit_page(page_div) + local pane_3 = reactor_page(page_div) + local pane_4 = boiler_page(page_div) + local pane_5 = turbine_page(page_div) local panes = { pane_1, pane_2, pane_3, pane_4, pane_5 } - local multipane = MultiPane{parent=mp_div,x=1,y=1,panes=panes} + local page_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes} - local sidebar = Sidebar{parent=main,x=1,y=2,tabs=sidebar_tabs,fg_bg=cpair(colors.white,colors.gray),callback=multipane.set_value} + Sidebar{parent=main_pane,x=1,y=2,tabs=sidebar_tabs,fg_bg=cpair(colors.white,colors.gray),callback=page_pane.set_value} return main end From 449e393b73e0bac3226d994fe3006ec7a5ad311c Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Tue, 18 Apr 2023 13:49:59 -0400 Subject: [PATCH 33/51] #201 supervisor pocket diagnostics session --- supervisor/config.lua | 1 + supervisor/session/plc.lua | 8 +- supervisor/session/pocket.lua | 222 ++++++++++++++++++++++++++++ supervisor/session/rtu.lua | 8 +- supervisor/session/rtu/redstone.lua | 2 + supervisor/session/svsessions.lua | 146 +++++++++--------- supervisor/startup.lua | 4 +- 7 files changed, 314 insertions(+), 77 deletions(-) create mode 100644 supervisor/session/pocket.lua diff --git a/supervisor/config.lua b/supervisor/config.lua index 47d530d..9fa3290 100644 --- a/supervisor/config.lua +++ b/supervisor/config.lua @@ -10,6 +10,7 @@ config.TRUSTED_RANGE = 0 config.PLC_TIMEOUT = 5 config.RTU_TIMEOUT = 5 config.CRD_TIMEOUT = 5 +config.PKT_TIMEOUT = 5 -- expected number of reactors config.NUM_REACTORS = 4 diff --git a/supervisor/session/plc.lua b/supervisor/session/plc.lua index fd0d0f8..b3e2be2 100644 --- a/supervisor/session/plc.lua +++ b/supervisor/session/plc.lua @@ -64,7 +64,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) connected = true, received_struct = false, received_status_cache = false, - plc_conn_watchdog = util.new_watchdog(timeout), + conn_watchdog = util.new_watchdog(timeout), last_rtt = 0, -- periodic messages periodics = { @@ -233,7 +233,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) -- mark this PLC session as closed, stop watchdog local function _close() - self.plc_conn_watchdog.cancel() + self.conn_watchdog.cancel() self.connected = false end @@ -301,7 +301,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) end -- feed watchdog - self.plc_conn_watchdog.feed() + self.conn_watchdog.feed() -- handle packet by type if pkt.type == RPLC_TYPE.STATUS then @@ -576,7 +576,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) -- check if a timer matches this session's watchdog ---@nodiscard function public.check_wd(timer) - return self.plc_conn_watchdog.is_timer(timer) and self.connected + return self.conn_watchdog.is_timer(timer) and self.connected end -- close the connection diff --git a/supervisor/session/pocket.lua b/supervisor/session/pocket.lua new file mode 100644 index 0000000..54017f5 --- /dev/null +++ b/supervisor/session/pocket.lua @@ -0,0 +1,222 @@ +local comms = require("scada-common.comms") +local log = require("scada-common.log") +local mqueue = require("scada-common.mqueue") +local util = require("scada-common.util") + +local pocket = {} + +local PROTOCOL = comms.PROTOCOL +local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE + +local println = util.println + +-- retry time constants in ms +-- local INITIAL_WAIT = 1500 +-- local RETRY_PERIOD = 1000 + +local POCKET_S_CMDS = { +} + +local POCKET_S_DATA = { +} + +pocket.POCKET_S_CMDS = POCKET_S_CMDS +pocket.POCKET_S_DATA = POCKET_S_DATA + +local PERIODICS = { + KEEP_ALIVE = 2000 +} + +-- pocket diagnostics session +---@nodiscard +---@param id integer session ID +---@param in_queue mqueue in message queue +---@param out_queue mqueue out message queue +---@param timeout number communications timeout +function pocket.new_session(id, in_queue, out_queue, timeout) + local log_header = "diag_session(" .. id .. "): " + + local self = { + -- connection properties + seq_num = 0, + r_seq_num = nil, + connected = true, + conn_watchdog = util.new_watchdog(timeout), + last_rtt = 0, + -- periodic messages + periodics = { + keep_alive = 0 + }, + -- when to next retry one of these requests + retry_times = { + }, + -- command acknowledgements + acks = { + }, + -- session database + ---@class diag_db + sDB = { + } + } + + ---@class diag_session + local public = {} + + -- mark this diagnostics session as closed, stop watchdog + local function _close() + self.conn_watchdog.cancel() + self.connected = false + end + + -- send a SCADA management packet + ---@param msg_type SCADA_MGMT_TYPE + ---@param msg table + local function _send_mgmt(msg_type, msg) + local s_pkt = comms.scada_packet() + local m_pkt = comms.mgmt_packet() + + m_pkt.make(msg_type, msg) + s_pkt.make(self.seq_num, PROTOCOL.SCADA_MGMT, m_pkt.raw_sendable()) + + out_queue.push_packet(s_pkt) + self.seq_num = self.seq_num + 1 + end + + -- handle a packet + ---@param pkt mgmt_frame + local function _handle_packet(pkt) + -- check sequence number + if self.r_seq_num == nil then + self.r_seq_num = pkt.scada_frame.seq_num() + elseif self.r_seq_num >= pkt.scada_frame.seq_num() then + log.warning(log_header .. "sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num()) + return + else + self.r_seq_num = pkt.scada_frame.seq_num() + end + + -- process packet + if pkt.scada_frame.protocol() == PROTOCOL.SCADA_MGMT then + ---@cast pkt mgmt_frame + if pkt.type == SCADA_MGMT_TYPE.KEEP_ALIVE then + -- keep alive reply + if pkt.length == 2 then + local srv_start = pkt.data[1] + -- local diag_send = pkt.data[2] + local srv_now = util.time() + self.last_rtt = srv_now - srv_start + + if self.last_rtt > 750 then + log.warning(log_header .. "DIAG KEEP_ALIVE round trip time > 750ms (" .. self.last_rtt .. "ms)") + end + + -- log.debug(log_header .. "DIAG RTT = " .. self.last_rtt .. "ms") + -- log.debug(log_header .. "DIAG TT = " .. (srv_now - diag_send) .. "ms") + else + log.debug(log_header .. "SCADA keep alive packet length mismatch") + end + elseif pkt.type == SCADA_MGMT_TYPE.CLOSE then + -- close the session + _close() + else + log.debug(log_header .. "handler received unsupported SCADA_MGMT packet type " .. pkt.type) + end + end + end + + -- PUBLIC FUNCTIONS -- + + -- get the session ID + ---@nodiscard + function public.get_id() return id end + + -- get the session database + ---@nodiscard + function public.get_db() return self.sDB end + + -- check if a timer matches this session's watchdog + ---@nodiscard + function public.check_wd(timer) + return self.conn_watchdog.is_timer(timer) and self.connected + end + + -- close the connection + function public.close() + _close() + _send_mgmt(SCADA_MGMT_TYPE.CLOSE, {}) + println("connection to pocket diag session " .. id .. " closed by server") + log.info(log_header .. "session closed by server") + end + + -- iterate the session + ---@nodiscard + ---@return boolean connected + function public.iterate() + if self.connected then + ------------------ + -- handle queue -- + ------------------ + + local handle_start = util.time() + + while in_queue.ready() and self.connected do + -- get a new message to process + local message = in_queue.pop() + + if message ~= nil then + if message.qtype == mqueue.TYPE.PACKET then + -- handle a packet + _handle_packet(message.message) + elseif message.qtype == mqueue.TYPE.COMMAND then + -- handle instruction + elseif message.qtype == mqueue.TYPE.DATA then + -- instruction with body + end + end + + -- max 100ms spent processing queue + if util.time() - handle_start > 100 then + log.warning(log_header .. "exceeded 100ms queue process limit") + break + end + end + + -- exit if connection was closed + if not self.connected then + println("connection to pocket diag session " .. id .. " closed by remote host") + log.info(log_header .. "session closed by remote host") + return self.connected + end + + ---------------------- + -- update periodics -- + ---------------------- + + local elapsed = util.time() - self.periodics.last_update + + local periodics = self.periodics + + -- keep alive + + periodics.keep_alive = periodics.keep_alive + elapsed + if periodics.keep_alive >= PERIODICS.KEEP_ALIVE then + _send_mgmt(SCADA_MGMT_TYPE.KEEP_ALIVE, { util.time() }) + periodics.keep_alive = 0 + end + + self.periodics.last_update = util.time() + + --------------------- + -- attempt retries -- + --------------------- + + -- local rtimes = self.retry_times + end + + return self.connected + end + + return public +end + +return pocket diff --git a/supervisor/session/rtu.lua b/supervisor/session/rtu.lua index 9357c71..7da723c 100644 --- a/supervisor/session/rtu.lua +++ b/supervisor/session/rtu.lua @@ -47,7 +47,7 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili seq_num = 0, r_seq_num = nil, connected = true, - rtu_conn_watchdog = util.new_watchdog(timeout), + conn_watchdog = util.new_watchdog(timeout), last_rtt = 0, -- periodic messages periodics = { @@ -174,7 +174,7 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili -- mark this RTU session as closed, stop watchdog local function _close() - self.rtu_conn_watchdog.cancel() + self.conn_watchdog.cancel() self.connected = false -- mark all RTU unit sessions as closed so the reactor unit knows @@ -222,7 +222,7 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili end -- feed watchdog - self.rtu_conn_watchdog.feed() + self.conn_watchdog.feed() -- process packet if pkt.scada_frame.protocol() == PROTOCOL.MODBUS_TCP then @@ -286,7 +286,7 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili ---@nodiscard ---@param timer number function public.check_wd(timer) - return self.rtu_conn_watchdog.is_timer(timer) and self.connected + return self.conn_watchdog.is_timer(timer) and self.connected end -- close the connection diff --git a/supervisor/session/rtu/redstone.lua b/supervisor/session/rtu/redstone.lua index 65831d6..bc7b81d 100644 --- a/supervisor/session/rtu/redstone.lua +++ b/supervisor/session/rtu/redstone.lua @@ -121,6 +121,7 @@ function redstone.new(session_id, unit_id, advert, out_queue) ---@nodiscard read = function () return rsio.digital_is_active(port, self.phy_io.digital_in[port].phy) end, ---@param active boolean +---@diagnostic disable-next-line: unused-local write = function (active) end } @@ -155,6 +156,7 @@ function redstone.new(session_id, unit_id, advert, out_queue) ---@return integer read = function () return self.phy_io.analog_in[port].phy end, ---@param value integer +---@diagnostic disable-next-line: unused-local write = function (value) end } diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index 9ed462d..1bf2d59 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -9,6 +9,7 @@ local svqtypes = require("supervisor.session.svqtypes") local coordinator = require("supervisor.session.coordinator") local plc = require("supervisor.session.plc") +local pocket = require("supervisor.session.pocket") local rtu = require("supervisor.session.rtu") -- Supervisor Sessions Handler @@ -22,29 +23,28 @@ local CRD_S_DATA = coordinator.CRD_S_DATA local svsessions = {} local SESSION_TYPE = { - RTU_SESSION = 0, - PLC_SESSION = 1, - COORD_SESSION = 2 + RTU_SESSION = 0, -- RTU gateway + PLC_SESSION = 1, -- reactor PLC + COORD_SESSION = 2, -- coordinator + DIAG_SESSION = 3 -- pocket diagnostics } svsessions.SESSION_TYPE = SESSION_TYPE local self = { - modem = nil, + modem = nil, ---@type table|nil num_reactors = 0, - facility = nil, ---@type facility - rtu_sessions = {}, - plc_sessions = {}, - coord_sessions = {}, - next_rtu_id = 0, - next_plc_id = 0, - next_coord_id = 0 + facility = nil, ---@type facility|nil + sessions = { rtu = {}, plc = {}, coord = {}, diag = {} }, + next_ids = { rtu = 0, plc = 0, coord = 0, diag = 0 } } +---@alias sv_session_structs plc_session_struct|rtu_session_struct|coord_session_struct|diag_session_struct + -- PRIVATE FUNCTIONS -- -- handle a session output queue ----@param session plc_session_struct|rtu_session_struct|coord_session_struct +---@param session sv_session_structs local function _sv_handle_outq(session) -- record handler start time local handle_start = util.time() @@ -112,7 +112,7 @@ end ---@param sessions table local function _iterate(sessions) for i = 1, #sessions do - local session = sessions[i] ---@type plc_session_struct|rtu_session_struct|coord_session_struct + local session = sessions[i] ---@type sv_session_structs if session.open and session.instance.iterate() then _sv_handle_outq(session) @@ -123,7 +123,7 @@ local function _iterate(sessions) end -- cleanly close a session ----@param session plc_session_struct|rtu_session_struct|coord_session_struct +---@param session sv_session_structs local function _shutdown(session) session.open = false session.instance.close() @@ -143,7 +143,7 @@ end ---@param sessions table local function _close(sessions) for i = 1, #sessions do - local session = sessions[i] ---@type plc_session_struct|rtu_session_struct|coord_session_struct + local session = sessions[i] ---@type sv_session_structs if session.open then _shutdown(session) end end end @@ -153,7 +153,7 @@ end ---@param timer_event number local function _check_watchdogs(sessions, timer_event) for i = 1, #sessions do - local session = sessions[i] ---@type plc_session_struct|rtu_session_struct|coord_session_struct + local session = sessions[i] ---@type sv_session_structs if session.open then local triggered = session.instance.check_wd(timer_event) if triggered then @@ -170,7 +170,7 @@ end local function _free_closed(sessions) local f = function (session) return session.open end - ---@param session plc_session_struct|rtu_session_struct|coord_session_struct + ---@param session sv_session_structs local on_delete = function (session) log.debug(util.c("free'ing closed ", session.s_type, " session ", session.instance.get_id(), " on remote port ", session.r_port)) @@ -183,7 +183,7 @@ end ---@nodiscard ---@param list table ---@param port integer ----@return plc_session_struct|rtu_session_struct|coord_session_struct|nil +---@return sv_session_structs|nil local function _find_session(list, port) for i = 1, #list do if list[i].r_port == port then return list[i] end @@ -215,7 +215,7 @@ end ---@return rtu_session_struct|nil function svsessions.find_rtu_session(remote_port) -- check RTU sessions - local session = _find_session(self.rtu_sessions, remote_port) + local session = _find_session(self.sessions.rtu, remote_port) ---@cast session rtu_session_struct return session end @@ -226,7 +226,7 @@ end ---@return plc_session_struct|nil function svsessions.find_plc_session(remote_port) -- check PLC sessions - local session = _find_session(self.plc_sessions, remote_port) + local session = _find_session(self.sessions.plc, remote_port) ---@cast session plc_session_struct return session end @@ -237,10 +237,10 @@ end ---@return plc_session_struct|rtu_session_struct|nil function svsessions.find_device_session(remote_port) -- check RTU sessions - local session = _find_session(self.rtu_sessions, remote_port) + local session = _find_session(self.sessions.rtu, remote_port) -- check PLC sessions - if session == nil then session = _find_session(self.plc_sessions, remote_port) end + if session == nil then session = _find_session(self.sessions.plc, remote_port) end ---@cast session plc_session_struct|rtu_session_struct|nil return session @@ -253,7 +253,7 @@ end ---@return coord_session_struct|nil function svsessions.find_coord_session(remote_port) -- check coordinator sessions - local session = _find_session(self.coord_sessions, remote_port) + local session = _find_session(self.sessions.coord, remote_port) ---@cast session coord_session_struct return session end @@ -262,7 +262,7 @@ end ---@nodiscard ---@return coord_session_struct|nil function svsessions.get_coord_session() - return self.coord_sessions[1] + return self.sessions.coord[1] end -- get a session by reactor ID @@ -272,9 +272,9 @@ end function svsessions.get_reactor_session(reactor) local session = nil - for i = 1, #self.plc_sessions do - if self.plc_sessions[i].reactor == reactor then - session = self.plc_sessions[i] + for i = 1, #self.sessions.plc do + if self.sessions.plc[i].reactor == reactor then + session = self.sessions.plc[i] end end @@ -303,15 +303,15 @@ function svsessions.establish_plc_session(local_port, remote_port, for_reactor, instance = nil ---@type plc_session } - plc_s.instance = plc.new_session(self.next_plc_id, for_reactor, plc_s.in_queue, plc_s.out_queue, config.PLC_TIMEOUT) - table.insert(self.plc_sessions, plc_s) + plc_s.instance = plc.new_session(self.next_ids.plc, for_reactor, plc_s.in_queue, plc_s.out_queue, config.PLC_TIMEOUT) + table.insert(self.sessions.plc, plc_s) local units = self.facility.get_units() units[for_reactor].link_plc_session(plc_s) - log.debug(util.c("established new PLC session to ", remote_port, " with ID ", self.next_plc_id, " for reactor ", for_reactor)) + log.debug(util.c("established new PLC session to ", remote_port, " with ID ", self.next_ids.plc, " for reactor ", for_reactor)) - self.next_plc_id = self.next_plc_id + 1 + self.next_ids.plc = self.next_ids.plc + 1 -- success return plc_s.instance.get_id() @@ -341,12 +341,12 @@ function svsessions.establish_rtu_session(local_port, remote_port, advertisement instance = nil ---@type rtu_session } - rtu_s.instance = rtu.new_session(self.next_rtu_id, rtu_s.in_queue, rtu_s.out_queue, config.RTU_TIMEOUT, advertisement, self.facility) - table.insert(self.rtu_sessions, rtu_s) + rtu_s.instance = rtu.new_session(self.next_ids.rtu, rtu_s.in_queue, rtu_s.out_queue, config.RTU_TIMEOUT, advertisement, self.facility) + table.insert(self.sessions.rtu, rtu_s) - log.debug("established new RTU session to " .. remote_port .. " with ID " .. self.next_rtu_id) + log.debug("established new RTU session to " .. remote_port .. " with ID " .. self.next_ids.rtu) - self.next_rtu_id = self.next_rtu_id + 1 + self.next_ids.rtu = self.next_ids.rtu + 1 -- success return rtu_s.instance.get_id() @@ -372,12 +372,12 @@ function svsessions.establish_coord_session(local_port, remote_port, version) instance = nil ---@type coord_session } - coord_s.instance = coordinator.new_session(self.next_coord_id, coord_s.in_queue, coord_s.out_queue, config.CRD_TIMEOUT, self.facility) - table.insert(self.coord_sessions, coord_s) + coord_s.instance = coordinator.new_session(self.next_ids.coord, coord_s.in_queue, coord_s.out_queue, config.CRD_TIMEOUT, self.facility) + table.insert(self.sessions.coord, coord_s) - log.debug("established new coordinator session to " .. remote_port .. " with ID " .. self.next_coord_id) + log.debug("established new coordinator session to " .. remote_port .. " with ID " .. self.next_ids.coord) - self.next_coord_id = self.next_coord_id + 1 + self.next_ids.coord = self.next_ids.coord + 1 -- success return coord_s.instance.get_id() @@ -387,32 +387,49 @@ function svsessions.establish_coord_session(local_port, remote_port, version) end end +-- establish a new pocket diagnostics session +---@nodiscard +---@param local_port integer +---@param remote_port integer +---@param version string +---@return integer|false session_id +function svsessions.establish_diag_session(local_port, remote_port, version) + ---@class diag_session_struct + local diag_s = { + s_type = "pkt", + open = true, + version = version, + l_port = local_port, + r_port = remote_port, + in_queue = mqueue.new(), + out_queue = mqueue.new(), + instance = nil ---@type diag_session + } + + diag_s.instance = pocket.new_session(self.next_ids.diag, diag_s.in_queue, diag_s.out_queue, config.PKT_TIMEOUT) + table.insert(self.sessions.diag, diag_s) + + log.debug("established new pocket diagnostics session to " .. remote_port .. " with ID " .. self.next_ids.diag) + + self.next_ids.diag = self.next_ids.diag + 1 + + -- success + return diag_s.instance.get_id() +end + -- attempt to identify which session's watchdog timer fired ---@param timer_event number function svsessions.check_all_watchdogs(timer_event) - -- check RTU session watchdogs - _check_watchdogs(self.rtu_sessions, timer_event) - - -- check PLC session watchdogs - _check_watchdogs(self.plc_sessions, timer_event) - - -- check coordinator session watchdogs - _check_watchdogs(self.coord_sessions, timer_event) + for _, list in pairs(self.sessions) do _check_watchdogs(list, timer_event) end end --- iterate all sessions +-- iterate all sessions, and update facility/unit data & process control logic function svsessions.iterate_all() - -- iterate RTU sessions - _iterate(self.rtu_sessions) - - -- iterate PLC sessions - _iterate(self.plc_sessions) - - -- iterate coordinator sessions - _iterate(self.coord_sessions) + -- iterate sessions + for _, list in pairs(self.sessions) do _iterate(list) end -- report RTU sessions to facility - self.facility.report_rtus(self.rtu_sessions) + self.facility.report_rtus(self.sessions.rtu) -- iterate facility self.facility.update() @@ -423,22 +440,15 @@ end -- delete all closed sessions function svsessions.free_all_closed() - -- free closed RTU sessions - _free_closed(self.rtu_sessions) - - -- free closed PLC sessions - _free_closed(self.plc_sessions) - - -- free closed coordinator sessions - _free_closed(self.coord_sessions) + for _, list in pairs(self.sessions) do _free_closed(list) end end -- close all open connections function svsessions.close_all() -- close sessions - _close(self.rtu_sessions) - _close(self.plc_sessions) - _close(self.coord_sessions) + for _, list in pairs(self.sessions) do + _close(list) + end -- free sessions svsessions.free_all_closed() diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 68db989..fd80180 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -14,7 +14,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.14.5" +local SUPERVISOR_VERSION = "v0.15.0" local println = util.println local println_ts = util.println_ts @@ -34,6 +34,8 @@ cfv.assert_type_num(config.RTU_TIMEOUT) cfv.assert_min(config.RTU_TIMEOUT, 2) cfv.assert_type_num(config.CRD_TIMEOUT) cfv.assert_min(config.CRD_TIMEOUT, 2) +cfv.assert_type_num(config.PKT_TIMEOUT) +cfv.assert_min(config.PKT_TIMEOUT, 2) cfv.assert_type_int(config.NUM_REACTORS) cfv.assert_type_table(config.REACTOR_COOLING) cfv.assert_type_str(config.LOG_PATH) From b48c9563540636f411dd88313f7ccc7ff42e3c46 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Tue, 18 Apr 2023 13:55:18 -0400 Subject: [PATCH 34/51] #201 coordinator apisessions for pocket access --- coordinator/apisessions.lua | 22 --- coordinator/config.lua | 3 +- coordinator/coordinator.lua | 80 ++++++++- coordinator/iocontrol.lua | 35 ++-- coordinator/session/api.lua | 247 ++++++++++++++++++++++++++++ coordinator/session/apisessions.lua | 174 ++++++++++++++++++++ coordinator/startup.lua | 10 +- 7 files changed, 525 insertions(+), 46 deletions(-) delete mode 100644 coordinator/apisessions.lua create mode 100644 coordinator/session/api.lua create mode 100644 coordinator/session/apisessions.lua diff --git a/coordinator/apisessions.lua b/coordinator/apisessions.lua deleted file mode 100644 index 8646837..0000000 --- a/coordinator/apisessions.lua +++ /dev/null @@ -1,22 +0,0 @@ -local apisessions = {} - ----@param packet capi_frame ----@diagnostic disable-next-line: unused-local -function apisessions.handle_packet(packet) -end - --- attempt to identify which session's watchdog timer fired ----@param timer_event number ----@diagnostic disable-next-line: unused-local -function apisessions.check_all_watchdogs(timer_event) -end - --- delete all closed sessions -function apisessions.free_all_closed() -end - --- close all open connections -function apisessions.close_all() -end - -return apisessions diff --git a/coordinator/config.lua b/coordinator/config.lua index 052bba4..b3eab5f 100644 --- a/coordinator/config.lua +++ b/coordinator/config.lua @@ -9,7 +9,8 @@ config.SCADA_API_LISTEN = 16200 -- max trusted modem message distance (0 to disable check) config.TRUSTED_RANGE = 0 -- time in seconds (>= 2) before assuming a remote device is no longer active -config.COMMS_TIMEOUT = 5 +config.SV_TIMEOUT = 5 +config.API_TIMEOUT = 5 -- expected number of reactor units, used only to require that number of unit monitors config.NUM_UNITS = 4 diff --git a/coordinator/coordinator.lua b/coordinator/coordinator.lua index d8d43a2..c1777a9 100644 --- a/coordinator/coordinator.lua +++ b/coordinator/coordinator.lua @@ -3,10 +3,11 @@ local log = require("scada-common.log") local ppm = require("scada-common.ppm") local util = require("scada-common.util") -local apisessions = require("coordinator.apisessions") local iocontrol = require("coordinator.iocontrol") local process = require("coordinator.process") +local apisessions = require("coordinator.session.apisessions") + local dialog = require("coordinator.ui.dialog") local print = util.print @@ -224,7 +225,8 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range sv_r_seq_num = nil, sv_config_err = false, connected = false, - last_est_ack = ESTABLISH_ACK.ALLOW + last_est_ack = ESTABLISH_ACK.ALLOW, + last_api_est_acks = {} } comms.set_trusted_range(range) @@ -262,6 +264,19 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range self.sv_seq_num = self.sv_seq_num + 1 end + -- send an API establish request response + ---@param dest integer + ---@param msg table + local function _send_api_establish_ack(seq_id, dest, msg) + local s_pkt = comms.scada_packet() + local m_pkt = comms.mgmt_packet() + + m_pkt.make(SCADA_MGMT_TYPE.ESTABLISH, msg) + s_pkt.make(seq_id, PROTOCOL.SCADA_MGMT, m_pkt.raw_sendable()) + + modem.transmit(dest, api_listen, s_pkt.raw_sendable()) + end + -- attempt connection establishment local function _send_establish() _send_sv(PROTOCOL.SCADA_MGMT, SCADA_MGMT_TYPE.ESTABLISH, { comms.version, version, DEVICE_TYPE.CRDN }) @@ -416,13 +431,70 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range ---@param packet mgmt_frame|crdn_frame|capi_frame|nil function public.handle_packet(packet) if packet ~= nil then - local protocol = packet.scada_frame.protocol() local l_port = packet.scada_frame.local_port() + local r_port = packet.scada_frame.remote_port() + local protocol = packet.scada_frame.protocol() if l_port == api_listen then if protocol == PROTOCOL.COORD_API then ---@cast packet capi_frame - apisessions.handle_packet(packet) + -- look for an associated session + local session = apisessions.find_session(r_port) + + -- API packet + if session ~= nil then + -- pass the packet onto the session handler + session.in_queue.push_packet(packet) + else + -- any other packet should be session related, discard it + log.debug("discarding COORD_API packet without a known session") + end + elseif protocol == PROTOCOL.SCADA_MGMT then + ---@cast packet mgmt_frame + -- look for an associated session + local session = apisessions.find_session(r_port) + + -- SCADA management packet + if session ~= nil then + -- pass the packet onto the session handler + session.in_queue.push_packet(packet) + elseif packet.type == SCADA_MGMT_TYPE.ESTABLISH then + -- establish a new session + local next_seq_id = packet.scada_frame.seq_num() + 1 + + -- validate packet and continue + if packet.length == 3 and type(packet.data[1]) == "string" and type(packet.data[2]) == "string" then + local comms_v = packet.data[1] + local firmware_v = packet.data[2] + local dev_type = packet.data[3] + + if comms_v ~= comms.version then + if self.last_api_est_acks[r_port] ~= ESTABLISH_ACK.BAD_VERSION then + log.info(util.c("dropping API establish packet with incorrect comms version v", comms_v, " (expected v", comms.version, ")")) + self.last_api_est_acks[r_port] = ESTABLISH_ACK.BAD_VERSION + end + + _send_api_establish_ack(next_seq_id, r_port, { ESTABLISH_ACK.BAD_VERSION }) + elseif dev_type == DEVICE_TYPE.PKT then + -- pocket linking request + local id = apisessions.establish_session(l_port, r_port, firmware_v) + println(util.c("API: pocket (", firmware_v, ") [:", r_port, "] connected with session ID ", id)) + coordinator.log_comms(util.c("API: pocket (", firmware_v, ") [:", r_port, "] connected with session ID ", id)) + + _send_api_establish_ack(next_seq_id, r_port, { ESTABLISH_ACK.ALLOW }) + self.last_api_est_acks[r_port] = ESTABLISH_ACK.ALLOW + else + log.debug(util.c("illegal establish packet for device ", dev_type, " on API listening channel")) + _send_api_establish_ack(next_seq_id, r_port, { ESTABLISH_ACK.DENY }) + end + else + log.debug("invalid establish packet (on API listening channel)") + _send_api_establish_ack(next_seq_id, r_port, { ESTABLISH_ACK.DENY }) + end + else + -- any other packet should be session related, discard it + log.debug(util.c(r_port, "->", l_port, ": discarding SCADA_MGMT packet without a known session")) + end else log.debug("illegal packet type " .. protocol .. " on api listening channel", true) end diff --git a/coordinator/iocontrol.lua b/coordinator/iocontrol.lua index ac45a2f..e26546d 100644 --- a/coordinator/iocontrol.lua +++ b/coordinator/iocontrol.lua @@ -18,6 +18,11 @@ local iocontrol = {} ---@class ioctl local io = {} +-- placeholder acknowledge function for type hinting +---@param success boolean +---@diagnostic disable-next-line: unused-local +local function __generic_ack(success) end + -- initialize the coordinator IO controller ---@param conf facility_conf configuration ---@param comms coord_comms comms reference @@ -45,11 +50,11 @@ function iocontrol.init(conf, comms) radiation = types.new_zero_radiation_reading(), - save_cfg_ack = function (success) end, ---@param success boolean - start_ack = function (success) end, ---@param success boolean - stop_ack = function (success) end, ---@param success boolean - scram_ack = function (success) end, ---@param success boolean - ack_alarms_ack = function (success) end, ---@param success boolean + save_cfg_ack = __generic_ack, + start_ack = __generic_ack, + stop_ack = __generic_ack, + scram_ack = __generic_ack, + ack_alarms_ack = __generic_ack, ps = psil.create(), @@ -74,7 +79,6 @@ function iocontrol.init(conf, comms) ---@class ioctl_unit local entry = { - ---@type integer unit_id = i, num_boilers = 0, @@ -85,7 +89,8 @@ function iocontrol.init(conf, comms) waste_control = 0, radiation = types.new_zero_radiation_reading(), - a_group = 0, -- auto control group + -- auto control group + a_group = 0, start = function () process.start(i) end, scram = function () process.scram(i) end, @@ -96,12 +101,12 @@ function iocontrol.init(conf, comms) set_group = function (grp) process.set_group(i, grp) end, ---@param grp integer|0 group ID or 0 - start_ack = function (success) end, ---@param success boolean - scram_ack = function (success) end, ---@param success boolean - reset_rps_ack = function (success) end, ---@param success boolean - ack_alarms_ack = function (success) end, ---@param success boolean - set_burn_ack = function (success) end, ---@param success boolean - set_waste_ack = function (success) end, ---@param success boolean + start_ack = __generic_ack, + scram_ack = __generic_ack, + reset_rps_ack = __generic_ack, + ack_alarms_ack = __generic_ack, + set_burn_ack = __generic_ack, + set_waste_ack = __generic_ack, alarm_callbacks = { c_breach = { ack = function () ack(1) end, reset = function () reset(1) end }, @@ -134,10 +139,10 @@ function iocontrol.init(conf, comms) ALARM_STATE.INACTIVE -- turbine trip }, - annunciator = {}, ---@type annunciator + annunciator = {}, ---@type annunciator unit_ps = psil.create(), - reactor_data = {}, ---@type reactor_db + reactor_data = {}, ---@type reactor_db boiler_ps_tbl = {}, boiler_data_tbl = {}, diff --git a/coordinator/session/api.lua b/coordinator/session/api.lua new file mode 100644 index 0000000..e062295 --- /dev/null +++ b/coordinator/session/api.lua @@ -0,0 +1,247 @@ +local comms = require("scada-common.comms") +local log = require("scada-common.log") +local mqueue = require("scada-common.mqueue") +local util = require("scada-common.util") + +local api = {} + +local PROTOCOL = comms.PROTOCOL +-- local CAPI_TYPE = comms.CAPI_TYPE +local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE + +local println = util.println + +-- retry time constants in ms +-- local INITIAL_WAIT = 1500 +-- local RETRY_PERIOD = 1000 + +local API_S_CMDS = { +} + +local API_S_DATA = { +} + +api.API_S_CMDS = API_S_CMDS +api.API_S_DATA = API_S_DATA + +local PERIODICS = { + KEEP_ALIVE = 2000 +} + +-- pocket API session +---@nodiscard +---@param id integer session ID +---@param in_queue mqueue in message queue +---@param out_queue mqueue out message queue +---@param timeout number communications timeout +function api.new_session(id, in_queue, out_queue, timeout) + local log_header = "api_session(" .. id .. "): " + + local self = { + -- connection properties + seq_num = 0, + r_seq_num = nil, + connected = true, + conn_watchdog = util.new_watchdog(timeout), + last_rtt = 0, + -- periodic messages + periodics = { + keep_alive = 0 + }, + -- when to next retry one of these requests + retry_times = { + }, + -- command acknowledgements + acks = { + }, + -- session database + ---@class api_db + sDB = { + } + } + + ---@class api_session + local public = {} + + -- mark this API session as closed, stop watchdog + local function _close() + self.conn_watchdog.cancel() + self.connected = false + end + + -- send a CAPI packet + ---@param msg_type CAPI_TYPE + ---@param msg table + local function _send(msg_type, msg) + local s_pkt = comms.scada_packet() + local c_pkt = comms.capi_packet() + + c_pkt.make(msg_type, msg) + s_pkt.make(self.seq_num, PROTOCOL.COORD_API, c_pkt.raw_sendable()) + + out_queue.push_packet(s_pkt) + self.seq_num = self.seq_num + 1 + end + + -- send a SCADA management packet + ---@param msg_type SCADA_MGMT_TYPE + ---@param msg table + local function _send_mgmt(msg_type, msg) + local s_pkt = comms.scada_packet() + local m_pkt = comms.mgmt_packet() + + m_pkt.make(msg_type, msg) + s_pkt.make(self.seq_num, PROTOCOL.SCADA_MGMT, m_pkt.raw_sendable()) + + out_queue.push_packet(s_pkt) + self.seq_num = self.seq_num + 1 + end + + -- handle a packet + ---@param pkt mgmt_frame|capi_frame + local function _handle_packet(pkt) + -- check sequence number + if self.r_seq_num == nil then + self.r_seq_num = pkt.scada_frame.seq_num() + elseif self.r_seq_num >= pkt.scada_frame.seq_num() then + log.warning(log_header .. "sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num()) + return + else + self.r_seq_num = pkt.scada_frame.seq_num() + end + + -- process packet + if pkt.scada_frame.protocol() == PROTOCOL.COORD_API then + ---@cast pkt capi_frame + -- feed watchdog + self.conn_watchdog.feed() + + -- handle packet by type + if pkt.type == nil then + else + log.debug(log_header .. "handler received unsupported CAPI packet type " .. pkt.type) + end + elseif pkt.scada_frame.protocol() == PROTOCOL.SCADA_MGMT then + ---@cast pkt mgmt_frame + if pkt.type == SCADA_MGMT_TYPE.KEEP_ALIVE then + -- keep alive reply + if pkt.length == 2 then + local srv_start = pkt.data[1] + -- local api_send = pkt.data[2] + local srv_now = util.time() + self.last_rtt = srv_now - srv_start + + if self.last_rtt > 750 then + log.warning(log_header .. "API KEEP_ALIVE round trip time > 750ms (" .. self.last_rtt .. "ms)") + end + + -- log.debug(log_header .. "API RTT = " .. self.last_rtt .. "ms") + -- log.debug(log_header .. "API TT = " .. (srv_now - api_send) .. "ms") + else + log.debug(log_header .. "SCADA keep alive packet length mismatch") + end + elseif pkt.type == SCADA_MGMT_TYPE.CLOSE then + -- close the session + _close() + else + log.debug(log_header .. "handler received unsupported SCADA_MGMT packet type " .. pkt.type) + end + end + end + + -- PUBLIC FUNCTIONS -- + + -- get the session ID + ---@nodiscard + function public.get_id() return id end + + -- get the session database + ---@nodiscard + function public.get_db() return self.sDB end + + -- check if a timer matches this session's watchdog + ---@nodiscard + function public.check_wd(timer) + return self.conn_watchdog.is_timer(timer) and self.connected + end + + -- close the connection + function public.close() + _close() + _send_mgmt(SCADA_MGMT_TYPE.CLOSE, {}) + println("connection to API session " .. id .. " closed by server") + log.info(log_header .. "session closed by server") + end + + -- iterate the session + ---@nodiscard + ---@return boolean connected + function public.iterate() + if self.connected then + ------------------ + -- handle queue -- + ------------------ + + local handle_start = util.time() + + while in_queue.ready() and self.connected do + -- get a new message to process + local message = in_queue.pop() + + if message ~= nil then + if message.qtype == mqueue.TYPE.PACKET then + -- handle a packet + _handle_packet(message.message) + elseif message.qtype == mqueue.TYPE.COMMAND then + -- handle instruction + elseif message.qtype == mqueue.TYPE.DATA then + -- instruction with body + end + end + + -- max 100ms spent processing queue + if util.time() - handle_start > 100 then + log.warning(log_header .. "exceeded 100ms queue process limit") + break + end + end + + -- exit if connection was closed + if not self.connected then + println("connection to API session " .. id .. " closed by remote host") + log.info(log_header .. "session closed by remote host") + return self.connected + end + + ---------------------- + -- update periodics -- + ---------------------- + + local elapsed = util.time() - self.periodics.last_update + + local periodics = self.periodics + + -- keep alive + + periodics.keep_alive = periodics.keep_alive + elapsed + if periodics.keep_alive >= PERIODICS.KEEP_ALIVE then + _send_mgmt(SCADA_MGMT_TYPE.KEEP_ALIVE, { util.time() }) + periodics.keep_alive = 0 + end + + self.periodics.last_update = util.time() + + --------------------- + -- attempt retries -- + --------------------- + + -- local rtimes = self.retry_times + end + + return self.connected + end + + return public +end + +return api diff --git a/coordinator/session/apisessions.lua b/coordinator/session/apisessions.lua new file mode 100644 index 0000000..c6d5a20 --- /dev/null +++ b/coordinator/session/apisessions.lua @@ -0,0 +1,174 @@ + +local log = require("scada-common.log") +local mqueue = require("scada-common.mqueue") +local util = require("scada-common.util") + +local config = require("coordinator.config") + +local api = require("coordinator.session.api") + +local apisessions = {} + +local self = { + modem = nil, + next_id = 0, + sessions = {} +} + +-- PRIVATE FUNCTIONS -- + +-- handle a session output queue +---@param session api_session_struct +local function _api_handle_outq(session) + -- record handler start time + local handle_start = util.time() + + -- process output queue + while session.out_queue.ready() do + -- get a new message to process + local msg = session.out_queue.pop() + + if msg ~= nil then + if msg.qtype == mqueue.TYPE.PACKET then + -- handle a packet to be sent + self.modem.transmit(session.r_port, session.l_port, msg.message.raw_sendable()) + elseif msg.qtype == mqueue.TYPE.COMMAND then + -- handle instruction/notification + elseif msg.qtype == mqueue.TYPE.DATA then + -- instruction/notification with body + end + end + + -- max 100ms spent processing queue + if util.time() - handle_start > 100 then + log.warning("API out queue handler exceeded 100ms queue process limit") + log.warning(util.c("offending session: port ", session.r_port)) + break + end + end +end + +-- cleanly close a session +---@param session api_session_struct +local function _shutdown(session) + session.open = false + session.instance.close() + + -- send packets in out queue (namely the close packet) + while session.out_queue.ready() do + local msg = session.out_queue.pop() + if msg ~= nil and msg.qtype == mqueue.TYPE.PACKET then + self.modem.transmit(session.r_port, session.l_port, msg.message.raw_sendable()) + end + end + + log.debug(util.c("closed API session ", session.instance.get_id(), " on remote port ", session.r_port)) +end + +-- PUBLIC FUNCTIONS -- + +-- initialize apisessions +---@param modem table +function apisessions.init(modem) + self.modem = modem +end + +-- re-link the modem +---@param modem table +function apisessions.relink_modem(modem) + self.modem = modem +end + +-- find a session by remote port +---@nodiscard +---@param port integer +---@return api_session_struct|nil +function apisessions.find_session(port) + for i = 1, #self.sessions do + if self.sessions[i].r_port == port then return self.sessions[i] end + end + return nil +end + +-- establish a new API session +---@nodiscard +---@param local_port integer +---@param remote_port integer +---@param version string +---@return integer session_id +function apisessions.establish_session(local_port, remote_port, version) + ---@class api_session_struct + local api_s = { + open = true, + version = version, + l_port = local_port, + r_port = remote_port, + in_queue = mqueue.new(), + out_queue = mqueue.new(), + instance = nil ---@type api_session + } + + api_s.instance = api.new_session(self.next_id, api_s.in_queue, api_s.out_queue, config.API_TIMEOUT) + table.insert(self.sessions, api_s) + + log.debug(util.c("established new API session to ", remote_port, " with ID ", self.next_id)) + + self.next_id = self.next_id + 1 + + -- success + return api_s.instance.get_id() +end + +-- attempt to identify which session's watchdog timer fired +---@param timer_event number +function apisessions.check_all_watchdogs(timer_event) + for i = 1, #self.sessions do + local session = self.sessions[i] ---@type api_session_struct + if session.open then + local triggered = session.instance.check_wd(timer_event) + if triggered then + log.debug(util.c("watchdog closing API session ", session.instance.get_id(), + " on remote port ", session.r_port, "...")) + _shutdown(session) + end + end + end +end + +-- iterate all the API sessions +function apisessions.iterate_all() + for i = 1, #self.sessions do + local session = self.sessions[i] ---@type api_session_struct + + if session.open and session.instance.iterate() then + _api_handle_outq(session) + else + session.open = false + end + end +end + +-- delete all closed sessions +function apisessions.free_all_closed() + local f = function (session) return session.open end + + ---@param session api_session_struct + local on_delete = function (session) + log.debug(util.c("free'ing closed API session ", session.instance.get_id(), + " on remote port ", session.r_port)) + end + + util.filter_table(self.sessions, f, on_delete) +end + +-- close all open connections +function apisessions.close_all() + for i = 1, #self.sessions do + local session = self.sessions[i] ---@type api_session_struct + if session.open then _shutdown(session) end + end + + apisessions.free_all_closed() +end + +return apisessions diff --git a/coordinator/startup.lua b/coordinator/startup.lua index d59e528..71f6f07 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -19,7 +19,7 @@ local iocontrol = require("coordinator.iocontrol") local renderer = require("coordinator.renderer") local sounder = require("coordinator.sounder") -local COORDINATOR_VERSION = "v0.12.6" +local COORDINATOR_VERSION = "v0.13.0" local println = util.println local println_ts = util.println_ts @@ -40,8 +40,10 @@ cfv.assert_port(config.SCADA_SV_PORT) cfv.assert_port(config.SCADA_SV_LISTEN) cfv.assert_port(config.SCADA_API_LISTEN) cfv.assert_type_int(config.TRUSTED_RANGE) -cfv.assert_type_num(config.COMMS_TIMEOUT) -cfv.assert_min(config.COMMS_TIMEOUT, 2) +cfv.assert_type_num(config.SV_TIMEOUT) +cfv.assert_min(config.SV_TIMEOUT, 2) +cfv.assert_type_num(config.API_TIMEOUT) +cfv.assert_min(config.API_TIMEOUT, 2) cfv.assert_type_int(config.NUM_UNITS) cfv.assert_type_num(config.SOUNDER_VOLUME) cfv.assert_type_bool(config.TIME_24_HOUR) @@ -140,7 +142,7 @@ local function main() end -- create connection watchdog - local conn_watchdog = util.new_watchdog(config.COMMS_TIMEOUT) + local conn_watchdog = util.new_watchdog(config.SV_TIMEOUT) conn_watchdog.cancel() log.debug("startup> conn watchdog created") From fee54db43e659a26f7b1a81f24e5e65d3c35e274 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Tue, 18 Apr 2023 22:01:35 +0000 Subject: [PATCH 35/51] #203 removed log message on failed structure send, lowered some other log levels to debug --- reactor-plc/plc.lua | 12 +++++------- reactor-plc/startup.lua | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index 304f3a6..96dc446 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -640,8 +640,6 @@ function plc.comms(id, version, modem, local_port, server_port, range, reactor, if not reactor.__p_is_faulted() then _send(RPLC_TYPE.MEK_STRUCT, mek_data) self.resend_build = false - else - log.error("failed to send structure: PPM fault") end end @@ -761,7 +759,7 @@ function plc.comms(id, version, modem, local_port, server_port, range, reactor, pkt = mgmt_pkt.get() end else - log.error("illegal packet type " .. s_pkt.protocol(), true) + log.debug("illegal packet type " .. s_pkt.protocol(), true) end end @@ -925,7 +923,7 @@ function plc.comms(id, version, modem, local_port, server_port, range, reactor, log.debug("RPLC set automatic burn rate packet length mismatch or non-numeric burn rate") end else - log.warning("received unknown RPLC packet type " .. packet.type) + log.debug("received unknown RPLC packet type " .. packet.type) end else log.debug("discarding RPLC packet before linked") @@ -947,7 +945,7 @@ function plc.comms(id, version, modem, local_port, server_port, range, reactor, log.debug("re-sent initial status data") elseif est_ack == ESTABLISH_ACK.DENY then println_ts("received unsolicited link denial, unlinking") - log.info("unsolicited establish request denied") + log.warning("unsolicited establish request denied") elseif est_ack == ESTABLISH_ACK.COLLISION then println_ts("received unsolicited link collision, unlinking") log.warning("unsolicited establish request collision") @@ -956,7 +954,7 @@ function plc.comms(id, version, modem, local_port, server_port, range, reactor, log.warning("unsolicited establish request version mismatch") else println_ts("invalid unsolicited link response") - log.error("unsolicited unknown establish request response") + log.debug("unsolicited unknown establish request response") end self.linked = est_ack == ESTABLISH_ACK.ALLOW @@ -992,7 +990,7 @@ function plc.comms(id, version, modem, local_port, server_port, range, reactor, println_ts("server connection closed by remote host") log.warning("server connection closed by remote host") else - log.warning("received unsupported SCADA_MGMT packet type " .. packet.type) + log.debug("received unsupported SCADA_MGMT packet type " .. packet.type) end elseif packet.type == SCADA_MGMT_TYPE.ESTABLISH then -- link request confirmation diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index ed56dec..1eb4120 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.1.6" +local R_PLC_VERSION = "v1.1.7" local println = util.println local println_ts = util.println_ts From 2371a7513016f8e02637b559ee7e6e939dccf848 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Wed, 19 Apr 2023 13:30:17 +0000 Subject: [PATCH 36/51] #214 log level cleanup --- coordinator/coordinator.lua | 8 ++++---- coordinator/startup.lua | 2 +- reactor-plc/plc.lua | 6 +++++- reactor-plc/startup.lua | 2 +- rtu/rtu.lua | 6 +++--- rtu/startup.lua | 2 +- supervisor/session/coordinator.lua | 2 +- supervisor/session/plc.lua | 8 ++++---- supervisor/startup.lua | 2 +- supervisor/supervisor.lua | 2 +- 10 files changed, 22 insertions(+), 18 deletions(-) diff --git a/coordinator/coordinator.lua b/coordinator/coordinator.lua index d8d43a2..f12d586 100644 --- a/coordinator/coordinator.lua +++ b/coordinator/coordinator.lua @@ -515,7 +515,7 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range elseif packet.type == SCADA_CRDN_TYPE.UNIT_STATUSES then -- update statuses if not iocontrol.update_unit_statuses(packet.data) then - log.error("received invalid UNIT_STATUSES packet") + log.debug("received invalid UNIT_STATUSES packet") end elseif packet.type == SCADA_CRDN_TYPE.UNIT_CMD then -- unit command acknowledgement @@ -551,7 +551,7 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range log.debug("SCADA_CRDN unit command ack packet length mismatch") end else - log.warning("received unknown SCADA_CRDN packet type " .. packet.type) + log.debug("received unknown SCADA_CRDN packet type " .. packet.type) end else log.debug("discarding SCADA_CRDN packet before linked") @@ -606,11 +606,11 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range end elseif est_ack == ESTABLISH_ACK.COLLISION then if self.last_est_ack ~= est_ack then - log.info("supervisor connection denied due to collision") + log.warning("supervisor connection denied due to collision") end elseif est_ack == ESTABLISH_ACK.BAD_VERSION then if self.last_est_ack ~= est_ack then - log.info("supervisor comms version mismatch") + log.warning("supervisor comms version mismatch") end else log.debug("SCADA_MGMT establish packet reply (len = 1) unsupported") diff --git a/coordinator/startup.lua b/coordinator/startup.lua index d59e528..7ebd49e 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -19,7 +19,7 @@ local iocontrol = require("coordinator.iocontrol") local renderer = require("coordinator.renderer") local sounder = require("coordinator.sounder") -local COORDINATOR_VERSION = "v0.12.6" +local COORDINATOR_VERSION = "v0.12.7" local println = util.println local println_ts = util.println_ts diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index 96dc446..39b2fb1 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -774,8 +774,10 @@ function plc.comms(id, version, modem, local_port, server_port, range, reactor, -- print a log message to the terminal as long as the UI isn't running local function println_ts(message) if not plc_state.fp_ok then util.println_ts(message) end end + local l_port = packet.scada_frame.local_port() + -- handle packets now that we have prints setup - if packet.scada_frame.local_port() == local_port then + if l_port == local_port then -- check sequence number if self.r_seq_num == nil then self.r_seq_num = packet.scada_frame.seq_num() @@ -1040,6 +1042,8 @@ function plc.comms(id, version, modem, local_port, server_port, range, reactor, -- should be unreachable assuming packet is from parse_packet() log.error("illegal packet type " .. protocol, true) end + else + log.debug("received packet on unconfigured channel " .. l_port, true) end end diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 1eb4120..17be32a 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.1.7" +local R_PLC_VERSION = "v1.1.8" local println = util.println local println_ts = util.println_ts diff --git a/rtu/rtu.lua b/rtu/rtu.lua index b8dee99..2690f90 100644 --- a/rtu/rtu.lua +++ b/rtu/rtu.lua @@ -313,7 +313,7 @@ function rtu.comms(version, modem, local_port, server_port, range, conn_watchdog pkt = mgmt_pkt.get() end else - log.error("illegal packet type " .. s_pkt.protocol(), true) + log.debug("illegal packet type " .. s_pkt.protocol(), true) end end @@ -379,7 +379,7 @@ function rtu.comms(version, modem, local_port, server_port, range, conn_watchdog else -- unit ID out of range? reply = modbus.reply__gw_unavailable(packet) - log.error("received MODBUS packet for non-existent unit") + log.debug("received MODBUS packet for non-existent unit") end public.send_modbus(reply) @@ -447,7 +447,7 @@ function rtu.comms(version, modem, local_port, server_port, range, conn_watchdog public.send_advertisement(units) else -- not supported - log.warning("received unsupported SCADA_MGMT message type " .. packet.type) + log.debug("received unsupported SCADA_MGMT message type " .. packet.type) end else log.debug("discarding non-link SCADA_MGMT packet before linked") diff --git a/rtu/startup.lua b/rtu/startup.lua index 2ebbd8d..10fc24e 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -25,7 +25,7 @@ local sna_rtu = require("rtu.dev.sna_rtu") local sps_rtu = require("rtu.dev.sps_rtu") local turbinev_rtu = require("rtu.dev.turbinev_rtu") -local RTU_VERSION = "v0.13.3" +local RTU_VERSION = "v0.13.4" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE diff --git a/supervisor/session/coordinator.lua b/supervisor/session/coordinator.lua index ad706e8..77ea5eb 100644 --- a/supervisor/session/coordinator.lua +++ b/supervisor/session/coordinator.lua @@ -410,7 +410,7 @@ function coordinator.new_session(id, in_queue, out_queue, timeout, facility) _send(SCADA_CRDN_TYPE.FAC_BUILDS, { facility.get_build(cmd.val.type == RTU_UNIT_TYPE.IMATRIX) }) end else - log.warning(log_header .. "unsupported data command received in in_queue (this is a bug)") + log.error(log_header .. "unsupported data command received in in_queue (this is a bug)", true) end end end diff --git a/supervisor/session/plc.lua b/supervisor/session/plc.lua index 40efd8c..656e95b 100644 --- a/supervisor/session/plc.lua +++ b/supervisor/session/plc.lua @@ -273,7 +273,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) if pkt.length == 1 then return pkt.data[1] else - log.warning(log_header .. "RPLC ACK length mismatch") + log.debug(log_header .. "RPLC ACK length mismatch") return nil end end @@ -295,7 +295,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) if pkt.scada_frame.protocol() == PROTOCOL.RPLC then -- check reactor ID if pkt.id ~= reactor_id then - log.warning(log_header .. "RPLC packet with ID not matching reactor ID: reactor " .. reactor_id .. " != " .. pkt.id) + log.warning(log_header .. "discarding RPLC packet with ID not matching reactor ID: reactor " .. reactor_id .. " != " .. pkt.id) return end @@ -633,7 +633,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) _send(RPLC_TYPE.RPS_AUTO_RESET, {}) end else - log.warning(log_header .. "unsupported command received in in_queue (this is a bug)") + log.error(log_header .. "unsupported command received in in_queue (this is a bug)", true) end elseif message.qtype == mqueue.TYPE.DATA then -- instruction with body @@ -680,7 +680,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) end end else - log.warning(log_header .. "unsupported data command received in in_queue (this is a bug)") + log.error(log_header .. "unsupported data command received in in_queue (this is a bug)", true) end end end diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 87bd902..a731b42 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -14,7 +14,7 @@ local svsessions = require("supervisor.session.svsessions") local config = require("supervisor.config") local supervisor = require("supervisor.supervisor") -local SUPERVISOR_VERSION = "v0.14.4" +local SUPERVISOR_VERSION = "v0.14.5" local println = util.println local println_ts = util.println_ts diff --git a/supervisor/supervisor.lua b/supervisor/supervisor.lua index 937dac8..1d25ed6 100644 --- a/supervisor/supervisor.lua +++ b/supervisor/supervisor.lua @@ -327,7 +327,7 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen log.debug("illegal packet type " .. protocol .. " on coordinator listening channel") end else - log.warning("received packet on unconfigured channel " .. l_port) + log.debug("received packet on unconfigured channel " .. l_port, true) end end end From 7929318096ba8bee6cc26e52dc72155c17b2b074 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 19 Apr 2023 20:35:42 -0400 Subject: [PATCH 37/51] #201 functional pocket comms with supervisor and coordinator, adjusted some UI element positioning, bugfixes with apisessions and svsessions --- coordinator/config.lua | 2 +- coordinator/coordinator.lua | 3 ++ coordinator/session/api.lua | 4 +++ coordinator/startup.lua | 14 +++++--- pocket/pocket.lua | 5 +++ pocket/startup.lua | 6 ++-- pocket/ui/components/conn_waiting.lua | 13 ++++--- pocket/ui/main.lua | 4 +-- supervisor/config.lua | 4 +-- supervisor/session/pocket.lua | 4 +++ supervisor/session/svsessions.lua | 17 +++++---- supervisor/startup.lua | 6 ++-- supervisor/supervisor.lua | 51 ++++++++++++++++----------- 13 files changed, 84 insertions(+), 49 deletions(-) diff --git a/coordinator/config.lua b/coordinator/config.lua index b3eab5f..8e12c53 100644 --- a/coordinator/config.lua +++ b/coordinator/config.lua @@ -3,7 +3,7 @@ local config = {} -- port of the SCADA supervisor config.SCADA_SV_PORT = 16100 -- port to listen to incoming packets from supervisor -config.SCADA_SV_LISTEN = 16101 +config.SCADA_SV_CTL_LISTEN = 16101 -- listen port for SCADA coordinator API access config.SCADA_API_LISTEN = 16200 -- max trusted modem message distance (0 to disable check) diff --git a/coordinator/coordinator.lua b/coordinator/coordinator.lua index c1777a9..ef36971 100644 --- a/coordinator/coordinator.lua +++ b/coordinator/coordinator.lua @@ -242,6 +242,9 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range _conf_channels() + -- link modem to apisessions + apisessions.init(modem) + -- send a packet to the supervisor ---@param msg_type SCADA_MGMT_TYPE|SCADA_CRDN_TYPE ---@param msg table diff --git a/coordinator/session/api.lua b/coordinator/session/api.lua index e062295..69df834 100644 --- a/coordinator/session/api.lua +++ b/coordinator/session/api.lua @@ -46,6 +46,7 @@ function api.new_session(id, in_queue, out_queue, timeout) last_rtt = 0, -- periodic messages periodics = { + last_update = 0, keep_alive = 0 }, -- when to next retry one of these requests @@ -110,6 +111,9 @@ function api.new_session(id, in_queue, out_queue, timeout) self.r_seq_num = pkt.scada_frame.seq_num() end + -- feed watchdog + self.conn_watchdog.feed() + -- process packet if pkt.scada_frame.protocol() == PROTOCOL.COORD_API then ---@cast pkt capi_frame diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 71f6f07..7ce1485 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -12,14 +12,15 @@ local util = require("scada-common.util") local core = require("graphics.core") -local apisessions = require("coordinator.apisessions") local config = require("coordinator.config") local coordinator = require("coordinator.coordinator") local iocontrol = require("coordinator.iocontrol") local renderer = require("coordinator.renderer") local sounder = require("coordinator.sounder") -local COORDINATOR_VERSION = "v0.13.0" +local apisessions = require("coordinator.session.apisessions") + +local COORDINATOR_VERSION = "v0.13.1" local println = util.println local println_ts = util.println_ts @@ -37,7 +38,7 @@ local log_comms_connecting = coordinator.log_comms_connecting local cfv = util.new_validator() cfv.assert_port(config.SCADA_SV_PORT) -cfv.assert_port(config.SCADA_SV_LISTEN) +cfv.assert_port(config.SCADA_SV_CTL_LISTEN) cfv.assert_port(config.SCADA_API_LISTEN) cfv.assert_type_int(config.TRUSTED_RANGE) cfv.assert_type_num(config.SV_TIMEOUT) @@ -147,7 +148,7 @@ local function main() log.debug("startup> conn watchdog created") -- start comms, open all channels - local coord_comms = coordinator.comms(COORDINATOR_VERSION, modem, config.SCADA_SV_PORT, config.SCADA_SV_LISTEN, + local coord_comms = coordinator.comms(COORDINATOR_VERSION, modem, config.SCADA_SV_PORT, config.SCADA_SV_CTL_LISTEN, config.SCADA_API_LISTEN, config.TRUSTED_RANGE, conn_watchdog) log.debug("startup> comms init") log_comms("comms initialized") @@ -300,6 +301,9 @@ local function main() if loop_clock.is_clock(param1) then -- main loop tick + -- iterate sessions + apisessions.iterate_all() + -- free any closed sessions apisessions.free_all_closed() @@ -326,7 +330,7 @@ local function main() else -- a non-clock/main watchdog timer event - --check API watchdogs + -- check API watchdogs apisessions.check_all_watchdogs(param1) -- notify timer callback dispatcher diff --git a/pocket/pocket.lua b/pocket/pocket.lua index 04feca3..be0c622 100644 --- a/pocket/pocket.lua +++ b/pocket/pocket.lua @@ -152,6 +152,8 @@ function pocket.comms(version, modem, local_port, sv_port, api_port, range, sv_w -- attempt to re-link if any of the dependent links aren't active function public.link_update() if not self.sv.linked then + coreio.report_link_state(util.trinary(self.api.linked, LINK_STATE.API_LINK_ONLY, LINK_STATE.UNLINKED)) + if self.establish_delay_counter <= 0 then _send_sv_establish() self.establish_delay_counter = 4 @@ -159,6 +161,8 @@ function pocket.comms(version, modem, local_port, sv_port, api_port, range, sv_w self.establish_delay_counter = self.establish_delay_counter - 1 end elseif not self.api.linked then + coreio.report_link_state(LINK_STATE.SV_LINK_ONLY) + if self.establish_delay_counter <= 0 then _send_api_establish() self.establish_delay_counter = 4 @@ -167,6 +171,7 @@ function pocket.comms(version, modem, local_port, sv_port, api_port, range, sv_w end else -- linked, all good! + coreio.report_link_state(LINK_STATE.LINKED) end end diff --git a/pocket/startup.lua b/pocket/startup.lua index 3ef9b8e..b57756c 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -17,7 +17,7 @@ local coreio = require("pocket.coreio") local pocket = require("pocket.pocket") local renderer = require("pocket.renderer") -local POCKET_VERSION = "alpha-v0.2.1" +local POCKET_VERSION = "alpha-v0.2.2" local println = util.println local println_ts = util.println_ts @@ -89,8 +89,8 @@ local function main() log.debug("startup> conn watchdogs created") -- start comms, open all channels - local pocket_comms = pocket.comms(POCKET_VERSION, modem, config.SCADA_SV_PORT, config.SCADA_API_PORT, - config.LISTEN_PORT, config.TRUSTED_RANGE, conn_wd.sv, conn_wd.api) + local pocket_comms = pocket.comms(POCKET_VERSION, modem, config.LISTEN_PORT, config.SCADA_SV_PORT, + config.SCADA_API_PORT, config.TRUSTED_RANGE, conn_wd.sv, conn_wd.api) log.debug("startup> comms init") -- base loop clock (2Hz, 10 ticks) diff --git a/pocket/ui/components/conn_waiting.lua b/pocket/ui/components/conn_waiting.lua index bca56e9..cd08652 100644 --- a/pocket/ui/components/conn_waiting.lua +++ b/pocket/ui/components/conn_waiting.lua @@ -19,17 +19,20 @@ local cpair = core.graphics.cpair ---@param parent graphics_element parent ---@param y integer y offset local function init(parent, y, is_api) + -- root div + local root = Div{parent=parent,x=1,y=1} + -- bounding box div - local root = Div{parent=parent,x=1,y=y,height=5} + local box = Div{parent=root,x=1,y=y,height=5} local waiting_x = math.floor(parent.width() / 2) - 1 if is_api then - WaitingAnim{parent=root,x=waiting_x,y=1,fg_bg=cpair(colors.blue,style.root.bkg)} - TextBox{parent=root,text="Connecting to API",alignment=TEXT_ALIGN.CENTER,y=5,height=1,fg_bg=cpair(colors.white,style.root.bkg)} + WaitingAnim{parent=box,x=waiting_x,y=1,fg_bg=cpair(colors.blue,style.root.bkg)} + TextBox{parent=box,text="Connecting to API",alignment=TEXT_ALIGN.CENTER,y=5,height=1,fg_bg=cpair(colors.white,style.root.bkg)} else - WaitingAnim{parent=root,x=waiting_x,y=1,fg_bg=cpair(colors.green,style.root.bkg)} - TextBox{parent=root,text="Connecting to Supervisor",alignment=TEXT_ALIGN.CENTER,y=5,height=1,fg_bg=cpair(colors.white,style.root.bkg)} + WaitingAnim{parent=box,x=waiting_x,y=1,fg_bg=cpair(colors.green,style.root.bkg)} + TextBox{parent=box,text="Connecting to Supervisor",alignment=TEXT_ALIGN.CENTER,y=5,height=1,fg_bg=cpair(colors.white,style.root.bkg)} end return root diff --git a/pocket/ui/main.lua b/pocket/ui/main.lua index 630991a..820867c 100644 --- a/pocket/ui/main.lua +++ b/pocket/ui/main.lua @@ -69,7 +69,7 @@ local function init(monitor) -- main page panel panes & sidebar -- - local page_div = Div{parent=main_pane,x=4,y=2} + local page_div = Div{parent=main_pane,x=4,y=1} local sidebar_tabs = { { @@ -103,7 +103,7 @@ local function init(monitor) local page_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes} - Sidebar{parent=main_pane,x=1,y=2,tabs=sidebar_tabs,fg_bg=cpair(colors.white,colors.gray),callback=page_pane.set_value} + Sidebar{parent=main_pane,x=1,y=1,tabs=sidebar_tabs,fg_bg=cpair(colors.white,colors.gray),callback=page_pane.set_value} return main end diff --git a/supervisor/config.lua b/supervisor/config.lua index 9fa3290..0aa26d8 100644 --- a/supervisor/config.lua +++ b/supervisor/config.lua @@ -2,8 +2,8 @@ local config = {} -- scada network listen for PLC's and RTU's config.SCADA_DEV_LISTEN = 16000 --- listen port for SCADA supervisor access by coordinators -config.SCADA_SV_LISTEN = 16100 +-- listen port for SCADA supervisor access +config.SCADA_SV_CTL_LISTEN = 16100 -- max trusted modem message distance (0 to disable check) config.TRUSTED_RANGE = 0 -- time in seconds (>= 2) before assuming a remote device is no longer active diff --git a/supervisor/session/pocket.lua b/supervisor/session/pocket.lua index 54017f5..e760512 100644 --- a/supervisor/session/pocket.lua +++ b/supervisor/session/pocket.lua @@ -45,6 +45,7 @@ function pocket.new_session(id, in_queue, out_queue, timeout) last_rtt = 0, -- periodic messages periodics = { + last_update = 0, keep_alive = 0 }, -- when to next retry one of these requests @@ -95,6 +96,9 @@ function pocket.new_session(id, in_queue, out_queue, timeout) self.r_seq_num = pkt.scada_frame.seq_num() end + -- feed watchdog + self.conn_watchdog.feed() + -- process packet if pkt.scada_frame.protocol() == PROTOCOL.SCADA_MGMT then ---@cast pkt mgmt_frame diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index 1bf2d59..8ad3366 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -216,7 +216,7 @@ end function svsessions.find_rtu_session(remote_port) -- check RTU sessions local session = _find_session(self.sessions.rtu, remote_port) - ---@cast session rtu_session_struct + ---@cast session rtu_session_struct|nil return session end @@ -227,7 +227,7 @@ end function svsessions.find_plc_session(remote_port) -- check PLC sessions local session = _find_session(self.sessions.plc, remote_port) - ---@cast session plc_session_struct + ---@cast session plc_session_struct|nil return session end @@ -246,15 +246,18 @@ function svsessions.find_device_session(remote_port) return session end --- find a coordinator session by the remote port
--- only one coordinator is allowed, but this is kept to be consistent with all other session tables +-- find a coordinator or diagnostic access session by the remote port ---@nodiscard ---@param remote_port integer ----@return coord_session_struct|nil -function svsessions.find_coord_session(remote_port) +---@return coord_session_struct|diag_session_struct|nil +function svsessions.find_svctl_session(remote_port) -- check coordinator sessions local session = _find_session(self.sessions.coord, remote_port) - ---@cast session coord_session_struct + + -- check diagnostic sessions + if session == nil then session = _find_session(self.sessions.diag, remote_port) end + ---@cast session coord_session_struct|diag_session_struct|nil + return session end diff --git a/supervisor/startup.lua b/supervisor/startup.lua index fd80180..bc11f4f 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -14,7 +14,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.15.0" +local SUPERVISOR_VERSION = "v0.15.1" local println = util.println local println_ts = util.println_ts @@ -26,7 +26,7 @@ local println_ts = util.println_ts local cfv = util.new_validator() cfv.assert_port(config.SCADA_DEV_LISTEN) -cfv.assert_port(config.SCADA_SV_LISTEN) +cfv.assert_port(config.SCADA_SV_CTL_LISTEN) cfv.assert_type_int(config.TRUSTED_RANGE) cfv.assert_type_num(config.PLC_TIMEOUT) cfv.assert_min(config.PLC_TIMEOUT, 2) @@ -91,7 +91,7 @@ local function main() -- start comms, open all channels local superv_comms = supervisor.comms(SUPERVISOR_VERSION, config.NUM_REACTORS, config.REACTOR_COOLING, modem, - config.SCADA_DEV_LISTEN, config.SCADA_SV_LISTEN, config.TRUSTED_RANGE) + config.SCADA_DEV_LISTEN, config.SCADA_SV_CTL_LISTEN, config.TRUSTED_RANGE) -- base loop clock (6.67Hz, 3 ticks) local MAIN_CLOCK = 0.15 diff --git a/supervisor/supervisor.lua b/supervisor/supervisor.lua index 99226fb..817275c 100644 --- a/supervisor/supervisor.lua +++ b/supervisor/supervisor.lua @@ -20,10 +20,10 @@ local println = util.println ---@param cooling_conf table cooling configuration table ---@param modem table modem device ---@param dev_listen integer listening port for PLC/RTU devices ----@param coord_listen integer listening port for coordinator +---@param svctl_listen integer listening port for supervisor access ---@param range integer trusted device connection range ---@diagnostic disable-next-line: unused-local -function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen, coord_listen, range) +function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen, svctl_listen, range) local self = { last_est_acks = {} } @@ -36,7 +36,7 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen local function _conf_channels() modem.closeAll() modem.open(dev_listen) - modem.open(coord_listen) + modem.open(svctl_listen) end _conf_channels() @@ -57,18 +57,18 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen modem.transmit(dest, dev_listen, s_pkt.raw_sendable()) end - -- send coordinator connection establish response + -- send supervisor control access connection establish response ---@param seq_id integer ---@param dest integer ---@param msg table - local function _send_crdn_establish(seq_id, dest, msg) + local function _send_svctl_establish(seq_id, dest, msg) local s_pkt = comms.scada_packet() local c_pkt = comms.mgmt_packet() c_pkt.make(SCADA_MGMT_TYPE.ESTABLISH, msg) s_pkt.make(seq_id, PROTOCOL.SCADA_MGMT, c_pkt.raw_sendable()) - modem.transmit(dest, coord_listen, s_pkt.raw_sendable()) + modem.transmit(dest, svctl_listen, s_pkt.raw_sendable()) end -- PUBLIC FUNCTIONS -- @@ -251,9 +251,9 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen log.debug("illegal packet type " .. protocol .. " on device listening channel") end -- coordinator listening channel - elseif l_port == coord_listen then + elseif l_port == svctl_listen then -- look for an associated session - local session = svsessions.find_coord_session(r_port) + local session = svsessions.find_svctl_session(r_port) if protocol == PROTOCOL.SCADA_MGMT then ---@cast packet mgmt_frame @@ -277,12 +277,9 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen self.last_est_acks[r_port] = ESTABLISH_ACK.BAD_VERSION end - _send_crdn_establish(next_seq_id, r_port, { ESTABLISH_ACK.BAD_VERSION }) - elseif dev_type ~= DEVICE_TYPE.CRDN then - log.debug(util.c("illegal establish packet for device ", dev_type, " on CRDN listening channel")) - _send_crdn_establish(next_seq_id, r_port, { ESTABLISH_ACK.DENY }) - else - -- this is an attempt to establish a new session + _send_svctl_establish(next_seq_id, r_port, { ESTABLISH_ACK.BAD_VERSION }) + elseif dev_type == DEVICE_TYPE.CRDN then + -- this is an attempt to establish a new coordinator session local s_id = svsessions.establish_coord_session(l_port, r_port, firmware_v) if s_id ~= false then @@ -292,23 +289,35 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen table.insert(config, cooling_conf[i].TURBINES) end - println(util.c("CRD (",firmware_v, ") [:", r_port, "] \xbb connected")) - log.info(util.c("CRDN_ESTABLISH: coordinator (",firmware_v, ") [:", r_port, "] connected with session ID ", s_id)) + println(util.c("CRD (", firmware_v, ") [:", r_port, "] \xbb connected")) + log.info(util.c("SVCTL_ESTABLISH: coordinator (", firmware_v, ") [:", r_port, "] connected with session ID ", s_id)) - _send_crdn_establish(next_seq_id, r_port, { ESTABLISH_ACK.ALLOW, config }) + _send_svctl_establish(next_seq_id, r_port, { ESTABLISH_ACK.ALLOW, config }) self.last_est_acks[r_port] = ESTABLISH_ACK.ALLOW else if self.last_est_acks[r_port] ~= ESTABLISH_ACK.COLLISION then - log.info("CRDN_ESTABLISH: denied new coordinator due to already being connected to another coordinator") + log.info("SVCTL_ESTABLISH: denied new coordinator due to already being connected to another coordinator") self.last_est_acks[r_port] = ESTABLISH_ACK.COLLISION end - _send_crdn_establish(next_seq_id, r_port, { ESTABLISH_ACK.COLLISION }) + _send_svctl_establish(next_seq_id, r_port, { ESTABLISH_ACK.COLLISION }) end + elseif dev_type == DEVICE_TYPE.PKT then + -- this is an attempt to establish a new pocket diagnostic session + local s_id = svsessions.establish_diag_session(l_port, r_port, firmware_v) + + println(util.c("PKT (", firmware_v, ") [:", r_port, "] \xbb connected")) + log.info(util.c("SVCTL_ESTABLISH: pocket (", firmware_v, ") [:", r_port, "] connected with session ID ", s_id)) + + _send_svctl_establish(next_seq_id, r_port, { ESTABLISH_ACK.ALLOW }) + self.last_est_acks[r_port] = ESTABLISH_ACK.ALLOW + else + log.debug(util.c("illegal establish packet for device ", dev_type, " on SVCTL listening channel")) + _send_svctl_establish(next_seq_id, r_port, { ESTABLISH_ACK.DENY }) end else - log.debug("CRDN_ESTABLISH: establish packet length mismatch") - _send_crdn_establish(next_seq_id, r_port, { ESTABLISH_ACK.DENY }) + log.debug("SVCTL_ESTABLISH: establish packet length mismatch") + _send_svctl_establish(next_seq_id, r_port, { ESTABLISH_ACK.DENY }) end else -- any other packet should be session related, discard it From ccdc31ed8720f7d591e38327c7e0b5b8e939e828 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 19 Apr 2023 20:40:09 -0400 Subject: [PATCH 38/51] fixed typo in check workflow --- .github/workflows/check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 4252af3..da24e11 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -29,4 +29,4 @@ jobs: # --no-max-line-length = Disable warnings for long line lengths # --exclude-files ... = Exclude lockbox library (external) and config files # --globals ... = Override all globals overridden in .vscode/settings.json AND 'os' since CraftOS 'os' differs from Lua's 'os' - args: . --no-max-line-length -a -i 121 512 542 --exclude-files ./lockbox/* ./*/config.lua --globals os _HOST bit colors fs http parllel periphemu peripheral read rs settings shell term textutils window + args: . --no-max-line-length -a -i 121 512 542 --exclude-files ./lockbox/* ./*/config.lua --globals os _HOST bit colors fs http parallel periphemu peripheral read rs settings shell term textutils window From eca303e289f42aea421e3abaf5a15a1bfd6ec3d1 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 19 Apr 2023 21:21:19 -0400 Subject: [PATCH 39/51] #208 ui cleanup for indicating emergency coolant status --- reactor-plc/panel/front_panel.lua | 16 ++++++++-------- reactor-plc/startup.lua | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/reactor-plc/panel/front_panel.lua b/reactor-plc/panel/front_panel.lua index dee017b..9d1a051 100644 --- a/reactor-plc/panel/front_panel.lua +++ b/reactor-plc/panel/front_panel.lua @@ -80,11 +80,17 @@ local function init(monitor) local active = LED{parent=status,x=2,width=12,label="RCT ACTIVE",colors=cpair(colors.green,colors.green_off)} - local status_trip_rct = Rectangle{parent=status,width=20,height=3,x=1,y=2,border=border(1,colors.lightGray,true),even_inner=true,fg_bg=cpair(colors.black,colors.ivory)} + -- only show emergency coolant LED if emergency coolant is configured for this device + if type(config.EMERGENCY_COOL) == "table" then + local emer_cool = LED{parent=status,x=2,width=14,label="EMER COOLANT",colors=cpair(colors.yellow,colors.yellow_off)} + databus.rx_field("emer_cool", emer_cool.update) + end + + local status_trip_rct = Rectangle{parent=status,width=20,height=3,x=1,border=border(1,colors.lightGray,true),even_inner=true,fg_bg=cpair(colors.black,colors.ivory)} local status_trip = Div{parent=status_trip_rct,width=18,height=1,fg_bg=cpair(colors.black,colors.lightGray)} local scram = LED{parent=status_trip,width=10,label="RPS TRIP",colors=cpair(colors.red,colors.red_off),flash=true,period=flasher.PERIOD.BLINK_250_MS} - local controls_rct = Rectangle{parent=status,width=17,height=3,x=1,y=5,border=border(1,colors.white,true),even_inner=true,fg_bg=cpair(colors.black,colors.ivory)} + local controls_rct = Rectangle{parent=status,width=17,height=3,x=1,border=border(1,colors.white,true),even_inner=true,fg_bg=cpair(colors.black,colors.ivory)} local controls = Div{parent=controls_rct,width=15,height=1,fg_bg=cpair(colors.black,colors.white)} PushButton{parent=controls,x=1,y=1,min_width=7,text="SCRAM",callback=databus.rps_scram,fg_bg=cpair(colors.black,colors.red),active_fg_bg=cpair(colors.black,colors.red_off)} PushButton{parent=controls,x=9,y=1,min_width=7,text="RESET",callback=databus.rps_reset,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=cpair(colors.black,colors.yellow_off)} @@ -92,12 +98,6 @@ local function init(monitor) databus.rx_field("reactor_active", active.update) databus.rx_field("rps_scram", scram.update) - -- only show emergency coolant LED if emergency coolant is configured for this device - if type(config.EMERGENCY_COOL) == "table" then - local emer_cool = LED{parent=status,x=9,width=14,label="EMER COOLANT",colors=cpair(colors.yellow,colors.yellow_off)} - databus.rx_field("emer_cool", emer_cool.update) - end - -- -- about footer -- diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 17be32a..eb2d6e8 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.1.8" +local R_PLC_VERSION = "v1.1.9" local println = util.println local println_ts = util.println_ts From a614b97d025ed35cc25456ef1472317fd289c21f Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 19 Apr 2023 21:26:54 -0400 Subject: [PATCH 40/51] cleanup to pass checks --- .vscode/settings.json | 2 +- coordinator/session/api.lua | 16 ++++++++-------- graphics/element.lua | 4 ++++ pocket/pocket.lua | 18 +++++++++--------- pocket/ui/components/boiler_page.lua | 4 ++-- pocket/ui/components/home_page.lua | 4 ++-- pocket/ui/components/reactor_page.lua | 4 ++-- pocket/ui/components/turbine_page.lua | 4 ++-- pocket/ui/components/unit_page.lua | 4 ++-- pocket/ui/main.lua | 7 ------- 10 files changed, 32 insertions(+), 35 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 3bf857e..673ad4e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,7 +19,7 @@ "Lua.diagnostics.severity": { "unused-local": "Information", "unused-vararg": "Information", - "unused-function": "Information", + "unused-function": "Warning", "unused-label": "Information" }, "Lua.hint.setType": true, diff --git a/coordinator/session/api.lua b/coordinator/session/api.lua index 69df834..2db28fd 100644 --- a/coordinator/session/api.lua +++ b/coordinator/session/api.lua @@ -73,16 +73,16 @@ function api.new_session(id, in_queue, out_queue, timeout) -- send a CAPI packet ---@param msg_type CAPI_TYPE ---@param msg table - local function _send(msg_type, msg) - local s_pkt = comms.scada_packet() - local c_pkt = comms.capi_packet() + -- local function _send(msg_type, msg) + -- local s_pkt = comms.scada_packet() + -- local c_pkt = comms.capi_packet() - c_pkt.make(msg_type, msg) - s_pkt.make(self.seq_num, PROTOCOL.COORD_API, c_pkt.raw_sendable()) + -- c_pkt.make(msg_type, msg) + -- s_pkt.make(self.seq_num, PROTOCOL.COORD_API, c_pkt.raw_sendable()) - out_queue.push_packet(s_pkt) - self.seq_num = self.seq_num + 1 - end + -- out_queue.push_packet(s_pkt) + -- self.seq_num = self.seq_num + 1 + -- end -- send a SCADA management packet ---@param msg_type SCADA_MGMT_TYPE diff --git a/graphics/element.lua b/graphics/element.lua index 77012fd..92b2f49 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -168,6 +168,8 @@ function element.new(args) self.bounds.y2 = self.position.y + f.h - 1 end +---@diagnostic disable: unused-local, unused-vararg + -- handle a mouse event ---@param event mouse_interaction mouse interaction event function protected.handle_mouse(event) @@ -222,6 +224,8 @@ function element.new(args) function protected.resize(...) end +---@diagnostic enable: unused-local, unused-vararg + -- start animations function protected.start_anim() end diff --git a/pocket/pocket.lua b/pocket/pocket.lua index be0c622..97ad87a 100644 --- a/pocket/pocket.lua +++ b/pocket/pocket.lua @@ -8,7 +8,7 @@ local PROTOCOL = comms.PROTOCOL local DEVICE_TYPE = comms.DEVICE_TYPE local ESTABLISH_ACK = comms.ESTABLISH_ACK local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE -local CAPI_TYPE = comms.CAPI_TYPE +-- local CAPI_TYPE = comms.CAPI_TYPE local LINK_STATE = coreio.LINK_STATE @@ -84,16 +84,16 @@ function pocket.comms(version, modem, local_port, sv_port, api_port, range, sv_w -- send a packet to the coordinator API ---@param msg_type CAPI_TYPE ---@param msg table - local function _send_api(msg_type, msg) - local s_pkt = comms.scada_packet() - local pkt = comms.capi_packet() + -- local function _send_api(msg_type, msg) + -- local s_pkt = comms.scada_packet() + -- local pkt = comms.capi_packet() - pkt.make(msg_type, msg) - s_pkt.make(self.api.seq_num, PROTOCOL.COORD_API, pkt.raw_sendable()) + -- pkt.make(msg_type, msg) + -- s_pkt.make(self.api.seq_num, PROTOCOL.COORD_API, pkt.raw_sendable()) - modem.transmit(api_port, local_port, s_pkt.raw_sendable()) - self.api.seq_num = self.api.seq_num + 1 - end + -- modem.transmit(api_port, local_port, s_pkt.raw_sendable()) + -- self.api.seq_num = self.api.seq_num + 1 + -- end -- attempt supervisor connection establishment local function _send_sv_establish() diff --git a/pocket/ui/components/boiler_page.lua b/pocket/ui/components/boiler_page.lua index 204896a..fd0eca1 100644 --- a/pocket/ui/components/boiler_page.lua +++ b/pocket/ui/components/boiler_page.lua @@ -1,11 +1,11 @@ -local style = require("pocket.ui.style") +-- local style = require("pocket.ui.style") local core = require("graphics.core") local Div = require("graphics.elements.div") local TextBox = require("graphics.elements.textbox") -local cpair = core.graphics.cpair +-- local cpair = core.graphics.cpair local TEXT_ALIGN = core.graphics.TEXT_ALIGN diff --git a/pocket/ui/components/home_page.lua b/pocket/ui/components/home_page.lua index 6715f19..5287cac 100644 --- a/pocket/ui/components/home_page.lua +++ b/pocket/ui/components/home_page.lua @@ -1,11 +1,11 @@ -local style = require("pocket.ui.style") +-- local style = require("pocket.ui.style") local core = require("graphics.core") local Div = require("graphics.elements.div") local TextBox = require("graphics.elements.textbox") -local cpair = core.graphics.cpair +-- local cpair = core.graphics.cpair local TEXT_ALIGN = core.graphics.TEXT_ALIGN diff --git a/pocket/ui/components/reactor_page.lua b/pocket/ui/components/reactor_page.lua index 4775d81..50b1939 100644 --- a/pocket/ui/components/reactor_page.lua +++ b/pocket/ui/components/reactor_page.lua @@ -1,11 +1,11 @@ -local style = require("pocket.ui.style") +-- local style = require("pocket.ui.style") local core = require("graphics.core") local Div = require("graphics.elements.div") local TextBox = require("graphics.elements.textbox") -local cpair = core.graphics.cpair +-- local cpair = core.graphics.cpair local TEXT_ALIGN = core.graphics.TEXT_ALIGN diff --git a/pocket/ui/components/turbine_page.lua b/pocket/ui/components/turbine_page.lua index 9c060cc..9fd7af5 100644 --- a/pocket/ui/components/turbine_page.lua +++ b/pocket/ui/components/turbine_page.lua @@ -1,11 +1,11 @@ -local style = require("pocket.ui.style") +-- local style = require("pocket.ui.style") local core = require("graphics.core") local Div = require("graphics.elements.div") local TextBox = require("graphics.elements.textbox") -local cpair = core.graphics.cpair +-- local cpair = core.graphics.cpair local TEXT_ALIGN = core.graphics.TEXT_ALIGN diff --git a/pocket/ui/components/unit_page.lua b/pocket/ui/components/unit_page.lua index 60c91b1..2e24df3 100644 --- a/pocket/ui/components/unit_page.lua +++ b/pocket/ui/components/unit_page.lua @@ -1,11 +1,11 @@ -local style = require("pocket.ui.style") +-- local style = require("pocket.ui.style") local core = require("graphics.core") local Div = require("graphics.elements.div") local TextBox = require("graphics.elements.textbox") -local cpair = core.graphics.cpair +-- local cpair = core.graphics.cpair local TEXT_ALIGN = core.graphics.TEXT_ALIGN diff --git a/pocket/ui/main.lua b/pocket/ui/main.lua index 820867c..d8202a7 100644 --- a/pocket/ui/main.lua +++ b/pocket/ui/main.lua @@ -2,8 +2,6 @@ -- Pocket GUI Root -- -local util = require("scada-common.util") - local coreio = require("pocket.coreio") local style = require("pocket.ui.style") @@ -18,18 +16,13 @@ local turbine_page = require("pocket.ui.components.turbine_page") local core = require("graphics.core") -local ColorMap = require("graphics.elements.colormap") local DisplayBox = require("graphics.elements.displaybox") local Div = require("graphics.elements.div") local MultiPane = require("graphics.elements.multipane") local TextBox = require("graphics.elements.textbox") -local PushButton = require("graphics.elements.controls.push_button") -local SwitchButton = require("graphics.elements.controls.switch_button") local Sidebar = require("graphics.elements.controls.sidebar") -local DataIndicator = require("graphics.elements.indicators.data") - local TEXT_ALIGN = core.graphics.TEXT_ALIGN local cpair = core.graphics.cpair From a843c8eb79d73d97c8cea63188d2c6b9277088a9 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 19 Apr 2023 23:00:27 -0400 Subject: [PATCH 41/51] fixes and cleanup --- coordinator/coordinator.lua | 1 + coordinator/session/api.lua | 8 ++++---- coordinator/startup.lua | 2 +- pocket/renderer.lua | 2 +- reactor-plc/startup.lua | 2 +- rtu/startup.lua | 2 +- scada-common/comms.lua | 2 +- supervisor/startup.lua | 2 +- 8 files changed, 11 insertions(+), 10 deletions(-) diff --git a/coordinator/coordinator.lua b/coordinator/coordinator.lua index 94c1ec1..b13134a 100644 --- a/coordinator/coordinator.lua +++ b/coordinator/coordinator.lua @@ -300,6 +300,7 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range ---@param new_modem table function public.reconnect_modem(new_modem) modem = new_modem + apisessions.relink_modem(new_modem) _conf_channels() end diff --git a/coordinator/session/api.lua b/coordinator/session/api.lua index 2db28fd..7ed5a07 100644 --- a/coordinator/session/api.lua +++ b/coordinator/session/api.lua @@ -1,7 +1,7 @@ -local comms = require("scada-common.comms") -local log = require("scada-common.log") -local mqueue = require("scada-common.mqueue") -local util = require("scada-common.util") +local comms = require("scada-common.comms") +local log = require("scada-common.log") +local mqueue = require("scada-common.mqueue") +local util = require("scada-common.util") local api = {} diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 7c369d6..f232587 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -20,7 +20,7 @@ local sounder = require("coordinator.sounder") local apisessions = require("coordinator.session.apisessions") -local COORDINATOR_VERSION = "v0.13.2" +local COORDINATOR_VERSION = "v0.13.3" local println = util.println local println_ts = util.println_ts diff --git a/pocket/renderer.lua b/pocket/renderer.lua index bd3f66e..4be1ec6 100644 --- a/pocket/renderer.lua +++ b/pocket/renderer.lua @@ -13,7 +13,7 @@ local ui = { view = nil } --- start the coordinator GUI +-- start the pocket GUI function renderer.start_ui() if ui.view == nil then -- reset screen diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 17be32a..624b78b 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.1.8" +local R_PLC_VERSION = "v1.1.10" local println = util.println local println_ts = util.println_ts diff --git a/rtu/startup.lua b/rtu/startup.lua index 10fc24e..4551a24 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -25,7 +25,7 @@ local sna_rtu = require("rtu.dev.sna_rtu") local sps_rtu = require("rtu.dev.sps_rtu") local turbinev_rtu = require("rtu.dev.turbinev_rtu") -local RTU_VERSION = "v0.13.4" +local RTU_VERSION = "v0.13.5" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE diff --git a/scada-common/comms.lua b/scada-common/comms.lua index b266a1a..fb54101 100644 --- a/scada-common/comms.lua +++ b/scada-common/comms.lua @@ -11,7 +11,7 @@ local insert = table.insert local max_distance = nil -comms.version = "1.4.0" +comms.version = "1.4.1" ---@enum PROTOCOL local PROTOCOL = { diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 21d7e2c..c111794 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -14,7 +14,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.15.2" +local SUPERVISOR_VERSION = "v0.15.3" local println = util.println local println_ts = util.println_ts From d143015cc7da2e4ee932bc21db9320796a161af2 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 20 Apr 2023 20:40:28 -0400 Subject: [PATCH 42/51] #183 RTU front panel --- coordinator/startup.lua | 2 +- graphics/element.lua | 10 +- graphics/elements/indicators/led.lua | 8 +- graphics/elements/indicators/ledpair.lua | 8 +- graphics/elements/indicators/ledrgb.lua | 8 +- imgen.py | 4 +- install_manifest.json | 2 +- pocket/startup.lua | 2 +- reactor-plc/startup.lua | 2 +- rtu/databus.lua | 75 ++++++++++++++ rtu/panel/front_panel.lua | 123 +++++++++++++++++++++++ rtu/panel/style.lua | 41 ++++++++ rtu/renderer.lua | 81 +++++++++++++++ rtu/rtu.lua | 21 ++-- rtu/startup.lua | 44 +++++++- rtu/threads.lua | 85 +++++++++++++--- 16 files changed, 471 insertions(+), 45 deletions(-) create mode 100644 rtu/databus.lua create mode 100644 rtu/panel/front_panel.lua create mode 100644 rtu/panel/style.lua create mode 100644 rtu/renderer.lua diff --git a/coordinator/startup.lua b/coordinator/startup.lua index f232587..e2c7efe 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -20,7 +20,7 @@ local sounder = require("coordinator.sounder") local apisessions = require("coordinator.session.apisessions") -local COORDINATOR_VERSION = "v0.13.3" +local COORDINATOR_VERSION = "v0.13.4" local println = util.println local println_ts = util.println_ts diff --git a/graphics/element.lua b/graphics/element.lua index 92b2f49..2265888 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -451,19 +451,13 @@ function element.new(args) function public.show() protected.window.setVisible(true) protected.start_anim() - - for i = 1, #self.children do - self.children[i].show() - end + for _, child in pairs(self.children) do child.show() end end -- hide the element function public.hide() protected.stop_anim() - for i = 1, #self.children do - self.children[i].hide() - end - + for _, child in pairs(self.children) do child.hide() end protected.window.setVisible(false) end diff --git a/graphics/elements/indicators/led.lua b/graphics/elements/indicators/led.lua index 7905848..dd2264e 100644 --- a/graphics/elements/indicators/led.lua +++ b/graphics/elements/indicators/led.lua @@ -33,7 +33,7 @@ local function indicator_led(args) args.height = 1 -- determine width - args.width = math.max(args.min_label_width or 1, string.len(args.label)) + 2 + args.width = math.max(args.min_label_width or 0, string.len(args.label)) + 2 -- flasher state local flash_on = true @@ -89,8 +89,10 @@ local function indicator_led(args) -- write label and initial indicator light e.on_update(false) - e.window.setCursorPos(3, 1) - e.window.write(args.label) + if string.len(args.label) > 0 then + e.window.setCursorPos(3, 1) + e.window.write(args.label) + end return e.get() end diff --git a/graphics/elements/indicators/ledpair.lua b/graphics/elements/indicators/ledpair.lua index aaf94ec..727d4cd 100644 --- a/graphics/elements/indicators/ledpair.lua +++ b/graphics/elements/indicators/ledpair.lua @@ -37,7 +37,7 @@ local function indicator_led_pair(args) args.height = 1 -- determine width - args.width = math.max(args.min_label_width or 1, string.len(args.label)) + 2 + args.width = math.max(args.min_label_width or 0, string.len(args.label)) + 2 -- flasher state local flash_on = true @@ -103,8 +103,10 @@ local function indicator_led_pair(args) -- write label and initial indicator light e.on_update(1) - e.window.setCursorPos(3, 1) - e.window.write(args.label) + if string.len(args.label) > 0 then + e.window.setCursorPos(3, 1) + e.window.write(args.label) + end return e.get() end diff --git a/graphics/elements/indicators/ledrgb.lua b/graphics/elements/indicators/ledrgb.lua index e779785..266e0ab 100644 --- a/graphics/elements/indicators/ledrgb.lua +++ b/graphics/elements/indicators/ledrgb.lua @@ -24,7 +24,7 @@ local function indicator_led_rgb(args) args.height = 1 -- determine width - args.width = math.max(args.min_label_width or 1, string.len(args.label)) + 2 + args.width = math.max(args.min_label_width or 0, string.len(args.label)) + 2 -- create new graphics element base object local e = element.new(args) @@ -48,8 +48,10 @@ local function indicator_led_rgb(args) -- write label and initial indicator light e.on_update(1) - e.window.setCursorPos(3, 1) - e.window.write(args.label) + if string.len(args.label) > 0 then + e.window.setCursorPos(3, 1) + e.window.write(args.label) + end return e.get() end diff --git a/imgen.py b/imgen.py index 92d82db..9a1e194 100644 --- a/imgen.py +++ b/imgen.py @@ -70,7 +70,7 @@ def make_manifest(size): }, "depends" : { "reactor-plc" : [ "system", "common", "graphics" ], - "rtu" : [ "system", "common" ], + "rtu" : [ "system", "common", "graphics" ], "supervisor" : [ "system", "common" ], "coordinator" : [ "system", "common", "graphics" ], "pocket" : [ "system", "common", "graphics" ] @@ -108,7 +108,7 @@ f = open("install_manifest.json", "w") json.dump(final_manifest, f) f.close() -if sys.argv[1] == "shields": +if len(sys.argv) > 1 and sys.argv[1] == "shields": # write all the JSON files for shields.io for key, version in final_manifest["versions"].items(): f = open("./shields/" + key + ".json", "w") diff --git a/install_manifest.json b/install_manifest.json index b762a3e..c724f5b 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.0", "reactor-plc": "v1.1.5", "rtu": "v0.13.3", "supervisor": "v0.14.4", "coordinator": "v0.12.6", "pocket": "alpha-v0.0.0"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/threads.lua", "rtu/rtu.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/apisessions.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/unit_waiting.lua", "coordinator/ui/components/turbine.lua"], "pocket": ["pocket/config.lua", "pocket/startup.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 4909, "system": 1991, "common": 90041, "graphics": 111156, "lockbox": 100797, "reactor-plc": 94599, "rtu": 86149, "supervisor": 273852, "coordinator": 180746, "pocket": 347}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.1.11", "rtu": "v1.0.0", "supervisor": "v0.15.3", "coordinator": "v0.13.4", "pocket": "alpha-v0.2.3"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/api.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/turbine_page.lua", "pocket/ui/components/reactor_page.lua", "pocket/ui/components/home_page.lua", "pocket/ui/components/unit_page.lua", "pocket/ui/components/boiler_page.lua", "pocket/ui/components/conn_waiting.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5467, "system": 1991, "common": 90336, "graphics": 115781, "lockbox": 100797, "reactor-plc": 95220, "rtu": 102446, "supervisor": 282665, "coordinator": 196044, "pocket": 35993}} \ No newline at end of file diff --git a/pocket/startup.lua b/pocket/startup.lua index b57756c..63ba41e 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -17,7 +17,7 @@ local coreio = require("pocket.coreio") local pocket = require("pocket.pocket") local renderer = require("pocket.renderer") -local POCKET_VERSION = "alpha-v0.2.2" +local POCKET_VERSION = "alpha-v0.2.3" local println = util.println local println_ts = util.println_ts diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 624b78b..cb35f5e 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.1.10" +local R_PLC_VERSION = "v1.1.11" local println = util.println local println_ts = util.println_ts diff --git a/rtu/databus.lua b/rtu/databus.lua new file mode 100644 index 0000000..8ef720e --- /dev/null +++ b/rtu/databus.lua @@ -0,0 +1,75 @@ +-- +-- Data Bus - Central Communication Linking for RTU Front Panel +-- + +local psil = require("scada-common.psil") +local util = require("scada-common.util") + +local databus = {} + +local dbus_iface = { + ps = psil.create() +} + +---@enum RTU_UNIT_HW_STATE +local RTU_UNIT_HW_STATE = { + OFFLINE = 1, + FAULTED = 2, + UNFORMED = 3, + OK = 4 +} + +databus.RTU_UNIT_HW_STATE = RTU_UNIT_HW_STATE + +-- call to toggle heartbeat signal +function databus.heartbeat() dbus_iface.ps.toggle("heartbeat") end + +-- transmit firmware versions across the bus +---@param rtu_v string RTU version +---@param comms_v string comms version +function databus.tx_versions(rtu_v, comms_v) + dbus_iface.ps.publish("version", rtu_v) + dbus_iface.ps.publish("comms_version", comms_v) +end + +-- transmit hardware status for modem connection state +---@param has_modem boolean +function databus.tx_hw_modem(has_modem) + dbus_iface.ps.publish("has_modem", has_modem) +end + +-- transmit unit hardware type across the bus +---@param uid integer unit ID +---@param type RTU_UNIT_TYPE +function databus.tx_unit_hw_type(uid, type) + dbus_iface.ps.publish("unit_type_" .. uid, type) +end + +-- transmit unit hardware status across the bus +---@param uid integer unit ID +---@param status RTU_UNIT_HW_STATE +function databus.tx_unit_hw_status(uid, status) + dbus_iface.ps.publish("unit_hw_" .. uid, status) +end + +-- transmit thread (routine) statuses +---@param thread string thread name +---@param ok boolean thread state +function databus.tx_rt_status(thread, ok) + dbus_iface.ps.publish(util.c("routine__", thread), ok) +end + +-- transmit supervisor link state across the bus +---@param state integer +function databus.tx_link_state(state) + dbus_iface.ps.publish("link_state", state) +end + +-- link a function to receive data from the bus +---@param field string field name +---@param func function function to link +function databus.rx_field(field, func) + dbus_iface.ps.subscribe(field, func) +end + +return databus diff --git a/rtu/panel/front_panel.lua b/rtu/panel/front_panel.lua new file mode 100644 index 0000000..9bde6c7 --- /dev/null +++ b/rtu/panel/front_panel.lua @@ -0,0 +1,123 @@ +-- +-- Main SCADA Coordinator GUI +-- + +local util = require("scada-common.util") + +local databus = require("rtu.databus") + +local style = require("rtu.panel.style") + +local core = require("graphics.core") + +local Div = require("graphics.elements.div") +local TextBox = require("graphics.elements.textbox") + +local LED = require("graphics.elements.indicators.led") +local RGBLED = require("graphics.elements.indicators.ledrgb") + +local TEXT_ALIGN = core.graphics.TEXT_ALIGN + +local cpair = core.graphics.cpair + +local UNIT_TYPE_LABELS = { + "UNKNOWN", + "REDSTONE", + "BOILER", + "TURBINE", + "IND MATRIX", + "SPS", + "SNA", + "ENV DETECTOR" +} + + +-- create new main view +---@param panel table main displaybox +---@param units table unit list +local function init(panel, units) + TextBox{parent=panel,y=1,text="RTU GATEWAY",alignment=TEXT_ALIGN.CENTER,height=1,fg_bg=style.header} + + -- + -- system indicators + -- + + local system = Div{parent=panel,width=14,height=18,x=2,y=3} + + local on = LED{parent=system,label="POWER",colors=cpair(colors.green,colors.red)} + local heartbeat = LED{parent=system,label="HEARTBEAT",colors=cpair(colors.green,colors.green_off)} + on.update(true) + system.line_break() + + databus.rx_field("heartbeat", heartbeat.update) + + local modem = LED{parent=system,label="MODEM",colors=cpair(colors.green,colors.green_off)} + local network = RGBLED{parent=system,label="NETWORK",colors={colors.green,colors.red,colors.orange,colors.yellow,colors.gray}} + network.update(5) + system.line_break() + + databus.rx_field("has_modem", modem.update) + databus.rx_field("link_state", network.update) + + local rt_main = LED{parent=system,label="RT MAIN",colors=cpair(colors.green,colors.green_off)} + local rt_comm = LED{parent=system,label="RT COMMS",colors=cpair(colors.green,colors.green_off)} + system.line_break() + + databus.rx_field("routine__main", rt_main.update) + databus.rx_field("routine__comms", rt_comm.update) + + -- + -- about label + -- + + local about = Div{parent=panel,width=15,height=3,x=1,y=18,fg_bg=cpair(colors.lightGray,colors.ivory)} + local fw_v = TextBox{parent=about,x=1,y=1,text="FW: v00.00.00",alignment=TEXT_ALIGN.LEFT,height=1} + local comms_v = TextBox{parent=about,x=1,y=2,text="NT: v00.00.00",alignment=TEXT_ALIGN.LEFT,height=1} + + databus.rx_field("version", function (version) fw_v.set_value(util.c("FW: ", version)) end) + databus.rx_field("comms_version", function (version) comms_v.set_value(util.c("NT: v", version)) end) + + -- + -- unit status list + -- + + local threads = Div{parent=panel,width=8,height=18,x=17,y=3} + + -- display up to 16 units + local list_length = math.min(#units, 16) + + -- show routine statuses + for i = 1, list_length do + TextBox{parent=threads,x=1,y=i,text=util.sprintf("%02d",i),height=1} + local rt_unit = LED{parent=threads,x=4,y=i,label="RT",colors=cpair(colors.green,colors.green_off)} + databus.rx_field("routine__unit_" .. i, rt_unit.update) + end + + local unit_hw_statuses = Div{parent=panel,height=18,x=25,y=3} + + -- show hardware statuses + for i = 1, list_length do + local unit = units[i] ---@type rtu_unit_registry_entry + + -- hardware status + local unit_hw = RGBLED{parent=unit_hw_statuses,y=i,label="",colors={colors.red,colors.orange,colors.yellow,colors.green}} + + databus.rx_field("unit_hw_" .. i, unit_hw.update) + + -- unit name identifier (type + index) + local name = util.c(UNIT_TYPE_LABELS[unit.type + 1], " ", unit.index) + local name_box = TextBox{parent=unit_hw_statuses,y=i,x=3,text=name,height=1} + + databus.rx_field("unit_type_" .. i, function (t) + name_box.set_value(util.c(UNIT_TYPE_LABELS[t + 1], " ", unit.index)) + end) + + -- assignment (unit # or facility) + local for_unit = util.trinary(unit.reactor == 0, "\x1a FACIL ", "\x1a UNIT " .. unit.reactor) + TextBox{parent=unit_hw_statuses,y=i,x=19,text=for_unit,height=1,fg_bg=cpair(colors.lightGray,colors.ivory)} + end + + return panel +end + +return init diff --git a/rtu/panel/style.lua b/rtu/panel/style.lua new file mode 100644 index 0000000..31039d4 --- /dev/null +++ b/rtu/panel/style.lua @@ -0,0 +1,41 @@ +-- +-- Graphics Style Options +-- + +local core = require("graphics.core") + +local style = {} + +local cpair = core.graphics.cpair + +-- GLOBAL -- + +-- remap global colors +colors.ivory = colors.pink +colors.red_off = colors.brown +colors.yellow_off = colors.magenta +colors.green_off = colors.lime + +style.root = cpair(colors.black, colors.ivory) +style.header = cpair(colors.black, colors.lightGray) + +style.colors = { + { c = colors.red, hex = 0xdf4949 }, -- RED ON + { c = colors.orange, hex = 0xffb659 }, + { c = colors.yellow, hex = 0xf9fb53 }, -- YELLOW ON + { c = colors.lime, hex = 0x16665a }, -- GREEN OFF + { c = colors.green, hex = 0x6be551 }, -- GREEN ON + { c = colors.cyan, hex = 0x34bac8 }, + { c = colors.lightBlue, hex = 0x6cc0f2 }, + { c = colors.blue, hex = 0x0096ff }, + { c = colors.purple, hex = 0xb156ee }, + { c = colors.pink, hex = 0xdcd9ca }, -- IVORY + { c = colors.magenta, hex = 0x85862c }, -- YELLOW OFF + -- { c = colors.white, hex = 0xdcd9ca }, + { c = colors.lightGray, hex = 0xb1b8b3 }, + { c = colors.gray, hex = 0x575757 }, + -- { c = colors.black, hex = 0x191919 }, + { c = colors.brown, hex = 0x672223 } -- RED OFF +} + +return style diff --git a/rtu/renderer.lua b/rtu/renderer.lua new file mode 100644 index 0000000..0ac1d58 --- /dev/null +++ b/rtu/renderer.lua @@ -0,0 +1,81 @@ +-- +-- Graphics Rendering Control +-- + +local panel_view = require("rtu.panel.front_panel") +local style = require("rtu.panel.style") + +local flasher = require("graphics.flasher") + +local DisplayBox = require("graphics.elements.displaybox") + +local renderer = {} + +local ui = { + display = nil +} + +-- start the UI +---@param units table RTU units +function renderer.start_ui(units) + if ui.display == nil then + -- reset terminal + term.setTextColor(colors.white) + term.setBackgroundColor(colors.black) + term.clear() + term.setCursorPos(1, 1) + + -- set overridden colors + for i = 1, #style.colors do + term.setPaletteColor(style.colors[i].c, style.colors[i].hex) + end + + -- start flasher callback task + flasher.run() + + -- init front panel view + ui.display = DisplayBox{window=term.current(),fg_bg=style.root} + panel_view(ui.display, units) + end +end + +-- close out the UI +function renderer.close_ui() + -- stop blinking indicators + flasher.clear() + + if ui.display ~= nil then + -- hide to stop animation callbacks + ui.display.hide() + end + + -- clear root UI elements + ui.display = nil + + -- restore colors + for i = 1, #style.colors do + local r, g, b = term.nativePaletteColor(style.colors[i].c) + term.setPaletteColor(style.colors[i].c, r, g, b) + end + + -- reset terminal + term.setTextColor(colors.white) + term.setBackgroundColor(colors.black) + term.clear() + term.setCursorPos(1, 1) +end + +-- is the UI ready? +---@nodiscard +---@return boolean ready +function renderer.ui_ready() return ui.display ~= nil end + +-- handle a mouse event +---@param event mouse_interaction +function renderer.handle_mouse(event) + if ui.display ~= nil then + ui.display.handle_mouse(event) + end +end + +return renderer diff --git a/rtu/rtu.lua b/rtu/rtu.lua index 2690f90..689d7c4 100644 --- a/rtu/rtu.lua +++ b/rtu/rtu.lua @@ -1,10 +1,11 @@ -local comms = require("scada-common.comms") -local ppm = require("scada-common.ppm") -local log = require("scada-common.log") -local types = require("scada-common.types") -local util = require("scada-common.util") +local comms = require("scada-common.comms") +local ppm = require("scada-common.ppm") +local log = require("scada-common.log") +local types = require("scada-common.types") +local util = require("scada-common.util") -local modbus = require("rtu.modbus") +local databus = require("rtu.databus") +local modbus = require("rtu.modbus") local rtu = {} @@ -14,8 +15,6 @@ local ESTABLISH_ACK = comms.ESTABLISH_ACK local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE -local println_ts = util.println_ts - -- create a new RTU unit ---@nodiscard function rtu.init_unit() @@ -325,6 +324,9 @@ function rtu.comms(version, modem, local_port, server_port, range, conn_watchdog ---@param units table RTU units ---@param rtu_state rtu_state function public.handle_packet(packet, units, rtu_state) + -- print a log message to the terminal as long as the UI isn't running + local function println_ts(message) if not rtu_state.fp_ok then util.println_ts(message) end end + if packet.scada_frame.local_port() == local_port then -- check sequence number if self.r_seq_num == nil then @@ -416,6 +418,9 @@ function rtu.comms(version, modem, local_port, server_port, range, conn_watchdog end self.last_est_ack = est_ack + + -- report link state + databus.tx_link_state(est_ack + 1) else log.debug("SCADA_MGMT establish packet length mismatch") end diff --git a/rtu/startup.lua b/rtu/startup.lua index 4551a24..d3c4971 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -4,6 +4,7 @@ require("/initenv").init_env() +local comms = require("scada-common.comms") local crash = require("scada-common.crash") local log = require("scada-common.log") local mqueue = require("scada-common.mqueue") @@ -13,7 +14,9 @@ local types = require("scada-common.types") local util = require("scada-common.util") local config = require("rtu.config") +local databus = require("rtu.databus") local modbus = require("rtu.modbus") +local renderer = require("rtu.renderer") local rtu = require("rtu.rtu") local threads = require("rtu.threads") @@ -25,9 +28,10 @@ local sna_rtu = require("rtu.dev.sna_rtu") local sps_rtu = require("rtu.dev.sps_rtu") local turbinev_rtu = require("rtu.dev.turbinev_rtu") -local RTU_VERSION = "v0.13.5" +local RTU_VERSION = "v1.0.0" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE +local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE local println = util.println local println_ts = util.println_ts @@ -71,6 +75,9 @@ local function main() -- startup ---------------------------------------- + -- record firmware versions and ID + databus.tx_versions(RTU_VERSION, comms.version) + -- mount connected devices ppm.mount_all() @@ -79,6 +86,7 @@ local function main() -- RTU system state flags ---@class rtu_state rtu_state = { + fp_ok = false, linked = false, shutdown = false }, @@ -111,6 +119,8 @@ local function main() return end + databus.tx_hw_modem(true) + ---------------------------------------- -- interpret config and init units ---------------------------------------- @@ -250,6 +260,8 @@ local function main() log.info(util.c("configure> initialized RTU unit #", #units, ": redstone_io (redstone) [1] for ", for_message)) unit.uid = #units + + databus.tx_unit_hw_status(unit.uid, RTU_UNIT_HW_STATE.OK) end end @@ -409,6 +421,20 @@ local function main() log.info(util.c("configure> initialized RTU unit #", #units, ": ", name, " (", types.rtu_type_to_string(rtu_type), ") [", index, "] for ", for_message)) rtu_unit.uid = #units + + -- report hardware status + if rtu_unit.type == RTU_UNIT_TYPE.VIRTUAL then + databus.tx_unit_hw_status(rtu_unit.uid, RTU_UNIT_HW_STATE.OFFLINE) + else + if rtu_unit.is_multiblock then + databus.tx_unit_hw_status(rtu_unit.uid, util.trinary(rtu_unit.formed == true, RTU_UNIT_HW_STATE.OK, RTU_UNIT_HW_STATE.UNFORMED)) + elseif faulted then + databus.tx_unit_hw_status(rtu_unit.uid, RTU_UNIT_HW_STATE.FAULTED) + else + databus.tx_unit_hw_status(rtu_unit.uid, RTU_UNIT_HW_STATE.OK) + end + end + end -- we made it through all that trusting-user-to-write-a-config-file chaos @@ -419,9 +445,23 @@ local function main() -- start system ---------------------------------------- + local rtu_state = __shared_memory.rtu_state + log.debug("boot> running configure()") if configure() then + -- start UI + local message + rtu_state.fp_ok, message = pcall(renderer.start_ui, units) + + if not rtu_state.fp_ok then + renderer.close_ui() + println_ts(util.c("UI error: ", message)) + println("init> running without front panel") + log.error(util.c("GUI crashed with error ", message)) + log.info("init> running in headless mode without front panel") + end + -- start connection watchdog smem_sys.conn_watchdog = util.new_watchdog(config.COMMS_TIMEOUT) log.debug("startup> conn watchdog started") @@ -451,6 +491,8 @@ local function main() println("configuration failed, exiting...") end + renderer.close_ui() + println_ts("exited") log.info("exited") end diff --git a/rtu/threads.lua b/rtu/threads.lua index 7b2a6fa..9dac9f1 100644 --- a/rtu/threads.lua +++ b/rtu/threads.lua @@ -4,6 +4,10 @@ local ppm = require("scada-common.ppm") local types = require("scada-common.types") local util = require("scada-common.util") +local databus = require("rtu.databus") +local modbus = require("rtu.modbus") +local renderer = require("rtu.renderer") + local boilerv_rtu = require("rtu.dev.boilerv_rtu") local envd_rtu = require("rtu.dev.envd_rtu") local imatrix_rtu = require("rtu.dev.imatrix_rtu") @@ -11,13 +15,12 @@ local sna_rtu = require("rtu.dev.sna_rtu") local sps_rtu = require("rtu.dev.sps_rtu") local turbinev_rtu = require("rtu.dev.turbinev_rtu") -local modbus = require("rtu.modbus") +local core = require("graphics.core") local threads = {} local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE - -local println_ts = util.println_ts +local UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE local MAIN_CLOCK = 2 -- (2Hz, 40 ticks) local COMMS_SLEEP = 100 -- (100ms, 2 ticks) @@ -26,11 +29,15 @@ local COMMS_SLEEP = 100 -- (100ms, 2 ticks) ---@nodiscard ---@param smem rtu_shared_memory function threads.thread__main(smem) + -- print a log message to the terminal as long as the UI isn't running + local function println_ts(message) if not smem.rtu_state.fp_ok then util.println_ts(message) end end + ---@class parallel_thread local public = {} -- execute thread function public.exec() + databus.tx_rt_status("main", true) log.debug("main thread start") -- main loop clock @@ -54,6 +61,9 @@ function threads.thread__main(smem) local event, param1, param2, param3, param4, param5 = util.pull_event() if event == "timer" and loop_clock.is_clock(param1) then + -- blink heartbeat indicator + databus.heartbeat() + -- start next clock timer loop_clock.start() @@ -82,6 +92,8 @@ function threads.thread__main(smem) if device == rtu_dev.modem then println_ts("wireless modem disconnected!") log.warning("comms modem disconnected!") + + databus.tx_hw_modem(false) else log.warning("non-comms modem disconnected") end @@ -91,10 +103,11 @@ function threads.thread__main(smem) if units[i].device == device then -- we are going to let the PPM prevent crashes -- return fault flags/codes to MODBUS queries - local unit = units[i] + local unit = units[i] ---@type rtu_unit_registry_entry local type_name = types.rtu_type_to_string(unit.type) println_ts(util.c("lost the ", type_name, " on interface ", unit.name)) log.warning(util.c("lost the ", type_name, " unit peripheral on interface ", unit.name)) + databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.OFFLINE) break end end @@ -113,6 +126,8 @@ function threads.thread__main(smem) println_ts("wireless modem reconnected.") log.info("comms modem reconnected") + + databus.tx_hw_modem(true) else log.info("wired modem reconnected") end @@ -153,34 +168,49 @@ function threads.thread__main(smem) resend_advert = false log.error(util.c("virtual device '", unit.name, "' cannot init to an unknown type (", type, ")")) end + + databus.tx_unit_hw_type(unit.uid, unit.type) end if unit.type == RTU_UNIT_TYPE.BOILER_VALVE then unit.rtu = boilerv_rtu.new(device) -- if not formed, indexing the multiblock functions would have resulted in a PPM fault unit.formed = util.trinary(device.__p_is_faulted(), false, nil) + databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.UNFORMED) elseif unit.type == RTU_UNIT_TYPE.TURBINE_VALVE then unit.rtu = turbinev_rtu.new(device) -- if not formed, indexing the multiblock functions would have resulted in a PPM fault unit.formed = util.trinary(device.__p_is_faulted(), false, nil) + databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.UNFORMED) elseif unit.type == RTU_UNIT_TYPE.IMATRIX then unit.rtu = imatrix_rtu.new(device) -- if not formed, indexing the multiblock functions would have resulted in a PPM fault unit.formed = util.trinary(device.__p_is_faulted(), false, nil) + databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.UNFORMED) elseif unit.type == RTU_UNIT_TYPE.SPS then unit.rtu = sps_rtu.new(device) -- if not formed, indexing the multiblock functions would have resulted in a PPM fault unit.formed = util.trinary(device.__p_is_faulted(), false, nil) + databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.UNFORMED) elseif unit.type == RTU_UNIT_TYPE.SNA then unit.rtu = sna_rtu.new(device) + databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.OK) elseif unit.type == RTU_UNIT_TYPE.ENV_DETECTOR then unit.rtu = envd_rtu.new(device) + databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.OK) else log.error(util.c("failed to identify reconnected RTU unit type (", unit.name, ")"), true) end - if unit.is_multiblock and (unit.formed == false) then - log.info(util.c("assuming ", unit.name, " is not formed due to PPM faults while initializing")) + if unit.is_multiblock then + if (unit.formed == false) then + log.info(util.c("assuming ", unit.name, " is not formed due to PPM faults while initializing")) + databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.UNFORMED) + end + elseif device.__p_is_faulted() then + databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.FAULTED) + else + databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.OK) end unit.modbus_io = modbus.new(unit.rtu, true) @@ -193,12 +223,15 @@ function threads.thread__main(smem) if resend_advert then rtu_comms.send_advertisement(units) else - rtu_comms.send_remounted(unit.uid) + rtu_comms.send_remounted(unit.uid) end end end end end + elseif event == "mouse_click" then + -- handle a monitor touch event + renderer.handle_mouse(core.events.click(param1, param2, param3)) end -- check for termination request @@ -220,6 +253,8 @@ function threads.thread__main(smem) log.fatal(util.strval(result)) end + databus.tx_rt_status("main", false) + if not rtu_state.shutdown then log.info("main thread restarting in 5 seconds...") util.psleep(5) @@ -239,6 +274,7 @@ function threads.thread__comms(smem) -- execute thread function public.exec() + databus.tx_rt_status("comms", true) log.debug("comms thread start") -- load in from shared memory @@ -294,6 +330,8 @@ function threads.thread__comms(smem) log.fatal(util.strval(result)) end + databus.tx_rt_status("comms", false) + if not rtu_state.shutdown then log.info("comms thread restarting in 5 seconds...") util.psleep(5) @@ -314,7 +352,8 @@ function threads.thread__unit_comms(smem, unit) -- execute thread function public.exec() - log.debug(util.c("rtu unit thread start -> ", types.rtu_type_to_string(unit.type), "(", unit.name, ")")) + databus.tx_rt_status("unit_" .. unit.uid, true) + log.debug(util.c("rtu unit thread start -> ", types.rtu_type_to_string(unit.type), " (", unit.name, ")")) -- load in from shared memory local rtu_state = smem.rtu_state @@ -348,6 +387,13 @@ function threads.thread__unit_comms(smem, unit) -- received a packet local _, reply = unit.modbus_io.handle_packet(msg.message) rtu_comms.send_modbus(reply) + + -- check if there was a problem and update the hardware state if so + local frame = reply.get() + if unit.formed and (bit.band(frame.func_code, types.MODBUS_FCODE.ERROR_FLAG) ~= 0) and + (frame.data[1] == types.MODBUS_EXCODE.SERVER_DEVICE_FAIL) then + databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.FAULTED) + end end end @@ -361,7 +407,14 @@ function threads.thread__unit_comms(smem, unit) last_f_check = util.time_ms() - if unit.formed == nil then unit.formed = is_formed end + if unit.formed == nil then + unit.formed = is_formed + if is_formed then databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.OK) end + end + + if not unit.formed then + databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.UNFORMED) + end if (not unit.formed) and is_formed then -- newly re-formed @@ -400,21 +453,25 @@ function threads.thread__unit_comms(smem, unit) unit.formed = device.isFormed() unit.modbus_io = modbus.new(unit.rtu, true) else - log.error("illegal remount of non-multiblock RTU attempted for " .. short_name, true) + log.error("illegal remount of non-multiblock RTU or type change attempted for " .. short_name, true) end if unit.formed and faulted then -- something is still wrong = can't mark as formed yet unit.formed = false + log.info(util.c("assuming ", unit.name, " is not formed due to PPM faults while initializing")) + databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.UNFORMED) else rtu_comms.send_remounted(unit.uid) + databus.tx_unit_hw_status(unit.uid, UNIT_HW_STATE.OK) end + + local type_name = types.rtu_type_to_string(unit.type) + log.info(util.c("reconnected the ", type_name, " on interface ", unit.name)) else -- fully lost the peripheral now :( log.error(util.c(unit.name, " lost (failed reconnect)")) end - - log.info(util.c("reconnected the ", unit.type, " on interface ", unit.name)) else log.error("failed to get interface of previously connected RTU unit " .. detail_name, true) end @@ -444,8 +501,10 @@ function threads.thread__unit_comms(smem, unit) log.fatal(util.strval(result)) end + databus.tx_rt_status("unit_" .. unit.uid, false) + if not rtu_state.shutdown then - log.info(util.c("rtu unit thread ", types.rtu_type_to_string(unit.type), "(", unit.name, " restarting in 5 seconds...")) + log.info(util.c("rtu unit thread ", types.rtu_type_to_string(unit.type), " (", unit.name, ") restarting in 5 seconds...")) util.psleep(5) end end From e9788abde7702abf2159f2058c659d51809e9551 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 20 Apr 2023 20:47:14 -0400 Subject: [PATCH 43/51] #219 fixed PLC renderer crash handling --- install_manifest.json | 2 +- reactor-plc/panel/front_panel.lua | 7 ++----- reactor-plc/plc.lua | 3 ++- reactor-plc/renderer.lua | 23 ++++++++++++++--------- reactor-plc/startup.lua | 2 +- 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/install_manifest.json b/install_manifest.json index c724f5b..2b5aec3 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.1.11", "rtu": "v1.0.0", "supervisor": "v0.15.3", "coordinator": "v0.13.4", "pocket": "alpha-v0.2.3"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/api.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/turbine_page.lua", "pocket/ui/components/reactor_page.lua", "pocket/ui/components/home_page.lua", "pocket/ui/components/unit_page.lua", "pocket/ui/components/boiler_page.lua", "pocket/ui/components/conn_waiting.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5467, "system": 1991, "common": 90336, "graphics": 115781, "lockbox": 100797, "reactor-plc": 95220, "rtu": 102446, "supervisor": 282665, "coordinator": 196044, "pocket": 35993}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.1.12", "rtu": "v1.0.0", "supervisor": "v0.15.3", "coordinator": "v0.13.4", "pocket": "alpha-v0.2.3"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/api.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/turbine_page.lua", "pocket/ui/components/reactor_page.lua", "pocket/ui/components/home_page.lua", "pocket/ui/components/unit_page.lua", "pocket/ui/components/boiler_page.lua", "pocket/ui/components/conn_waiting.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5467, "system": 1991, "common": 90336, "graphics": 115781, "lockbox": 100797, "reactor-plc": 95220, "rtu": 102446, "supervisor": 282665, "coordinator": 196044, "pocket": 35993}} \ No newline at end of file diff --git a/reactor-plc/panel/front_panel.lua b/reactor-plc/panel/front_panel.lua index 9d1a051..fed7e02 100644 --- a/reactor-plc/panel/front_panel.lua +++ b/reactor-plc/panel/front_panel.lua @@ -12,7 +12,6 @@ local style = require("reactor-plc.panel.style") local core = require("graphics.core") local flasher = require("graphics.flasher") -local DisplayBox = require("graphics.elements.displaybox") local Div = require("graphics.elements.div") local Rectangle = require("graphics.elements.rectangle") local TextBox = require("graphics.elements.textbox") @@ -29,10 +28,8 @@ local cpair = core.graphics.cpair local border = core.graphics.border -- create new main view ----@param monitor table main viewscreen -local function init(monitor) - local panel = DisplayBox{window=monitor,fg_bg=style.root} - +---@param panel table main displaybox +local function init(panel) local header = TextBox{parent=panel,y=1,text="REACTOR PLC - UNIT ?",alignment=TEXT_ALIGN.CENTER,height=1,fg_bg=style.header} databus.rx_field("unit_id", function (id) header.set_value(util.c("REACTOR PLC - UNIT ", id)) end) diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index 39b2fb1..d89e86f 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -1,12 +1,13 @@ local comms = require("scada-common.comms") local const = require("scada-common.constants") -local databus = require("reactor-plc.databus") local log = require("scada-common.log") local ppm = require("scada-common.ppm") local rsio = require("scada-common.rsio") local types = require("scada-common.types") local util = require("scada-common.util") +local databus = require("reactor-plc.databus") + local plc = {} local RPS_TRIP_CAUSE = types.RPS_TRIP_CAUSE diff --git a/reactor-plc/renderer.lua b/reactor-plc/renderer.lua index ad2bcc0..87b7ffa 100644 --- a/reactor-plc/renderer.lua +++ b/reactor-plc/renderer.lua @@ -2,20 +2,22 @@ -- Graphics Rendering Control -- -local style = require("reactor-plc.panel.style") local panel_view = require("reactor-plc.panel.front_panel") +local style = require("reactor-plc.panel.style") local flasher = require("graphics.flasher") +local DisplayBox = require("graphics.elements.displaybox") + local renderer = {} local ui = { - view = nil + display = nil } -- start the UI function renderer.start_ui() - if ui.view == nil then + if ui.display == nil then -- reset terminal term.setTextColor(colors.white) term.setBackgroundColor(colors.black) @@ -31,7 +33,8 @@ function renderer.start_ui() flasher.run() -- init front panel view - ui.view = panel_view(term.current()) + ui.display = DisplayBox{window=term.current(),fg_bg=style.root} + panel_view(ui.display) end end @@ -40,13 +43,13 @@ function renderer.close_ui() -- stop blinking indicators flasher.clear() - if ui.view ~= nil then + if ui.display ~= nil then -- hide to stop animation callbacks - ui.view.hide() + ui.display.hide() end -- clear root UI elements - ui.view = nil + ui.display = nil -- restore colors for i = 1, #style.colors do @@ -64,12 +67,14 @@ end -- is the UI ready? ---@nodiscard ---@return boolean ready -function renderer.ui_ready() return ui.view ~= nil end +function renderer.ui_ready() return ui.display ~= nil end -- handle a mouse event ---@param event mouse_interaction function renderer.handle_mouse(event) - ui.view.handle_mouse(event) + if ui.display ~= nil then + ui.display.handle_mouse(event) + end end return renderer diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index cb35f5e..ddb62bb 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.1.11" +local R_PLC_VERSION = "v1.1.12" local println = util.println local println_ts = util.println_ts From 5db517cedcf3fc8973422979fd59e84645c3d752 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 20 Apr 2023 21:00:10 -0400 Subject: [PATCH 44/51] #217 close log files on exit (including crash) --- coordinator/startup.lua | 4 ++- install_manifest.json | 2 +- reactor-plc/startup.lua | 4 +-- rtu/startup.lua | 4 +-- scada-common/crash.lua | 1 + scada-common/log.lua | 63 +++++++++++++++++++++++++---------------- supervisor/startup.lua | 4 +-- 7 files changed, 49 insertions(+), 33 deletions(-) diff --git a/coordinator/startup.lua b/coordinator/startup.lua index e2c7efe..9018547 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -20,7 +20,7 @@ local sounder = require("coordinator.sounder") local apisessions = require("coordinator.session.apisessions") -local COORDINATOR_VERSION = "v0.13.4" +local COORDINATOR_VERSION = "v0.13.5" local println = util.println local println_ts = util.println_ts @@ -389,4 +389,6 @@ if not xpcall(main, crash.handler) then pcall(renderer.close_ui) pcall(sounder.stop) crash.exit() +else + log.close() end diff --git a/install_manifest.json b/install_manifest.json index 2b5aec3..a53675f 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.1.12", "rtu": "v1.0.0", "supervisor": "v0.15.3", "coordinator": "v0.13.4", "pocket": "alpha-v0.2.3"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/api.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/turbine_page.lua", "pocket/ui/components/reactor_page.lua", "pocket/ui/components/home_page.lua", "pocket/ui/components/unit_page.lua", "pocket/ui/components/boiler_page.lua", "pocket/ui/components/conn_waiting.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5467, "system": 1991, "common": 90336, "graphics": 115781, "lockbox": 100797, "reactor-plc": 95220, "rtu": 102446, "supervisor": 282665, "coordinator": 196044, "pocket": 35993}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.1.13", "rtu": "v1.0.1", "supervisor": "v0.15.4", "coordinator": "v0.13.5", "pocket": "alpha-v0.2.3"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/api.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/turbine_page.lua", "pocket/ui/components/reactor_page.lua", "pocket/ui/components/home_page.lua", "pocket/ui/components/unit_page.lua", "pocket/ui/components/boiler_page.lua", "pocket/ui/components/conn_waiting.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5467, "system": 1991, "common": 90337, "graphics": 115781, "lockbox": 100797, "reactor-plc": 95237, "rtu": 100040, "supervisor": 282682, "coordinator": 196065, "pocket": 35993}} \ No newline at end of file diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index ddb62bb..ead6580 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.1.12" +local R_PLC_VERSION = "v1.1.13" local println = util.println local println_ts = util.println_ts @@ -264,4 +264,4 @@ local function main() log.info("exited") end -if not xpcall(main, crash.handler) then crash.exit() end +if not xpcall(main, crash.handler) then crash.exit() else log.close() end diff --git a/rtu/startup.lua b/rtu/startup.lua index d3c4971..6821eab 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -28,7 +28,7 @@ local sna_rtu = require("rtu.dev.sna_rtu") local sps_rtu = require("rtu.dev.sps_rtu") local turbinev_rtu = require("rtu.dev.turbinev_rtu") -local RTU_VERSION = "v1.0.0" +local RTU_VERSION = "v1.0.1" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE @@ -497,4 +497,4 @@ local function main() log.info("exited") end -if not xpcall(main, crash.handler) then crash.exit() end +if not xpcall(main, crash.handler) then crash.exit() else log.close() end diff --git a/scada-common/crash.lua b/scada-common/crash.lua index 66bfda1..8d02728 100644 --- a/scada-common/crash.lua +++ b/scada-common/crash.lua @@ -39,6 +39,7 @@ end -- final error print on failed xpcall, app exits here function crash.exit() + log.close() util.println("fatal error occured in main application:") error(err, 0) end diff --git a/scada-common/log.lua b/scada-common/log.lua index 424bf55..40baef2 100644 --- a/scada-common/log.lua +++ b/scada-common/log.lua @@ -16,7 +16,7 @@ local MODE = { log.MODE = MODE -- whether to log debug messages or not -local LOG_DEBUG = false +local LOG_DEBUG = true local log_sys = { path = "/log.txt", @@ -28,30 +28,9 @@ local log_sys = { ---@type function local free_space = fs.getFreeSpace --- initialize logger ----@param path string file path ----@param write_mode MODE ----@param dmesg_redirect? table terminal/window to direct dmesg to -function log.init(path, write_mode, dmesg_redirect) - log_sys.path = path - log_sys.mode = write_mode - - if log_sys.mode == MODE.APPEND then - log_sys.file = fs.open(path, "a") - else - log_sys.file = fs.open(path, "w") - end - - if dmesg_redirect then - log_sys.dmesg_out = dmesg_redirect - else - log_sys.dmesg_out = term.current() - end -end - --- direct dmesg output to a monitor/window ----@param window table window or terminal reference -function log.direct_dmesg(window) log_sys.dmesg_out = window end +----------------------- +-- PRIVATE FUNCTIONS -- +----------------------- -- private log write function ---@param msg string @@ -93,6 +72,40 @@ local function _log(msg) end end +---------------------- +-- PUBLIC FUNCTIONS -- +---------------------- + +-- initialize logger +---@param path string file path +---@param write_mode MODE +---@param dmesg_redirect? table terminal/window to direct dmesg to +function log.init(path, write_mode, dmesg_redirect) + log_sys.path = path + log_sys.mode = write_mode + + if log_sys.mode == MODE.APPEND then + log_sys.file = fs.open(path, "a") + else + log_sys.file = fs.open(path, "w") + end + + if dmesg_redirect then + log_sys.dmesg_out = dmesg_redirect + else + log_sys.dmesg_out = term.current() + end +end + +-- close the log file handle +function log.close() + log_sys.file.close() +end + +-- direct dmesg output to a monitor/window +---@param window table window or terminal reference +function log.direct_dmesg(window) log_sys.dmesg_out = window end + -- dmesg style logging for boot because I like linux-y things ---@param msg string message ---@param tag? string log tag diff --git a/supervisor/startup.lua b/supervisor/startup.lua index c111794..397674a 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -14,7 +14,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.15.3" +local SUPERVISOR_VERSION = "v0.15.4" local println = util.println local println_ts = util.println_ts @@ -169,4 +169,4 @@ local function main() log.info("exited") end -if not xpcall(main, crash.handler) then crash.exit() end +if not xpcall(main, crash.handler) then crash.exit() else log.close() end From 4c8723eb329edadfbbb9e9803477c8e8a19e6811 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 20 Apr 2023 21:01:41 -0400 Subject: [PATCH 45/51] #217 close log file on pocket too --- install_manifest.json | 2 +- pocket/startup.lua | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/install_manifest.json b/install_manifest.json index a53675f..05b8989 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.1.13", "rtu": "v1.0.1", "supervisor": "v0.15.4", "coordinator": "v0.13.5", "pocket": "alpha-v0.2.3"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/api.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/turbine_page.lua", "pocket/ui/components/reactor_page.lua", "pocket/ui/components/home_page.lua", "pocket/ui/components/unit_page.lua", "pocket/ui/components/boiler_page.lua", "pocket/ui/components/conn_waiting.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5467, "system": 1991, "common": 90337, "graphics": 115781, "lockbox": 100797, "reactor-plc": 95237, "rtu": 100040, "supervisor": 282682, "coordinator": 196065, "pocket": 35993}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.1.13", "rtu": "v1.0.1", "supervisor": "v0.15.4", "coordinator": "v0.13.5", "pocket": "alpha-v0.2.4"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/api.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/turbine_page.lua", "pocket/ui/components/reactor_page.lua", "pocket/ui/components/home_page.lua", "pocket/ui/components/unit_page.lua", "pocket/ui/components/boiler_page.lua", "pocket/ui/components/conn_waiting.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5467, "system": 1991, "common": 90337, "graphics": 115781, "lockbox": 100797, "reactor-plc": 95237, "rtu": 100040, "supervisor": 282682, "coordinator": 196065, "pocket": 36014}} \ No newline at end of file diff --git a/pocket/startup.lua b/pocket/startup.lua index 63ba41e..0109033 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -17,7 +17,7 @@ local coreio = require("pocket.coreio") local pocket = require("pocket.pocket") local renderer = require("pocket.renderer") -local POCKET_VERSION = "alpha-v0.2.3" +local POCKET_VERSION = "alpha-v0.2.4" local println = util.println local println_ts = util.println_ts @@ -175,4 +175,6 @@ end if not xpcall(main, crash.handler) then pcall(renderer.close_ui) crash.exit() +else + log.close() end From 419ca2e6ef73e1178b4d7f9e1fcb78ed919444b6 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 20 Apr 2023 21:19:16 -0400 Subject: [PATCH 46/51] #220 close ui on crash --- install_manifest.json | 2 +- reactor-plc/startup.lua | 9 +++++++-- rtu/startup.lua | 9 +++++++-- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/install_manifest.json b/install_manifest.json index 05b8989..0bae10d 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.1.13", "rtu": "v1.0.1", "supervisor": "v0.15.4", "coordinator": "v0.13.5", "pocket": "alpha-v0.2.4"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/api.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/turbine_page.lua", "pocket/ui/components/reactor_page.lua", "pocket/ui/components/home_page.lua", "pocket/ui/components/unit_page.lua", "pocket/ui/components/boiler_page.lua", "pocket/ui/components/conn_waiting.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5467, "system": 1991, "common": 90337, "graphics": 115781, "lockbox": 100797, "reactor-plc": 95237, "rtu": 100040, "supervisor": 282682, "coordinator": 196065, "pocket": 36014}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.1.14", "rtu": "v1.0.2", "supervisor": "v0.15.4", "coordinator": "v0.13.5", "pocket": "alpha-v0.2.4"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/api.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/turbine_page.lua", "pocket/ui/components/reactor_page.lua", "pocket/ui/components/home_page.lua", "pocket/ui/components/unit_page.lua", "pocket/ui/components/boiler_page.lua", "pocket/ui/components/conn_waiting.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5467, "system": 1991, "common": 90337, "graphics": 115781, "lockbox": 100797, "reactor-plc": 95274, "rtu": 100077, "supervisor": 282682, "coordinator": 196065, "pocket": 36014}} \ No newline at end of file diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index ead6580..4670694 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.1.13" +local R_PLC_VERSION = "v1.1.14" local println = util.println local println_ts = util.println_ts @@ -264,4 +264,9 @@ local function main() log.info("exited") end -if not xpcall(main, crash.handler) then crash.exit() else log.close() end +if not xpcall(main, crash.handler) then + pcall(renderer.close_ui) + crash.exit() +else + log.close() +end diff --git a/rtu/startup.lua b/rtu/startup.lua index 6821eab..c1b4d60 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -28,7 +28,7 @@ local sna_rtu = require("rtu.dev.sna_rtu") local sps_rtu = require("rtu.dev.sps_rtu") local turbinev_rtu = require("rtu.dev.turbinev_rtu") -local RTU_VERSION = "v1.0.1" +local RTU_VERSION = "v1.0.2" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE @@ -497,4 +497,9 @@ local function main() log.info("exited") end -if not xpcall(main, crash.handler) then crash.exit() else log.close() end +if not xpcall(main, crash.handler) then + pcall(renderer.close_ui) + crash.exit() +else + log.close() +end From 706fb5ea740daedf83465f1884d3dd8175355145 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Fri, 21 Apr 2023 13:34:46 +0000 Subject: [PATCH 47/51] updated devcontainer and workspace extension recommendations --- .devcontainer/devcontainer.json | 22 ++++++++++++---------- .vscode/extensions.json | 6 ++++++ 2 files changed, 18 insertions(+), 10 deletions(-) create mode 100644 .vscode/extensions.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ed3acf3..272f078 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,13 +1,15 @@ { - "image": "mcr.microsoft.com/devcontainers/universal:2", - "features": { -}, -"customizations": { - "vscode": { - "extensions": [ - "sumneko.lua", - "jackmacwindows.vscode-computercraft" - ] + "image": "mcr.microsoft.com/devcontainers/universal:2", + "features": { + }, + "customizations": { + "vscode": { + "extensions": [ + "sumneko.lua", + "jackmacwindows.vscode-computercraft", + "Catppuccin.catppuccin-vsc-icons", + "melishev.feather-vscode" + ] + } } } -} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..72f00e0 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "sumneko.lua", + "jackmacwindows.vscode-computercraft" + ] +} From e1da8b59d3995104adc86219378f75f18fb250de Mon Sep 17 00:00:00 2001 From: Mikayla Date: Fri, 21 Apr 2023 18:53:28 +0000 Subject: [PATCH 48/51] #219 properly close out GUI on error on pocket and coordinator --- coordinator/renderer.lua | 94 ++++++++++++++--------------- coordinator/startup.lua | 2 +- coordinator/ui/layout/main_view.lua | 9 +-- coordinator/ui/layout/unit_view.lua | 12 +--- pocket/renderer.lua | 31 ++++++---- pocket/startup.lua | 2 +- pocket/ui/main.lua | 33 +++++----- reactor-plc/panel/front_panel.lua | 4 +- reactor-plc/renderer.lua | 6 +- reactor-plc/startup.lua | 2 +- rtu/panel/front_panel.lua | 4 +- rtu/startup.lua | 2 +- 12 files changed, 89 insertions(+), 112 deletions(-) diff --git a/coordinator/renderer.lua b/coordinator/renderer.lua index f0563ca..f354d3c 100644 --- a/coordinator/renderer.lua +++ b/coordinator/renderer.lua @@ -2,29 +2,29 @@ -- Graphics Rendering Control -- -local log = require("scada-common.log") -local util = require("scada-common.util") +local log = require("scada-common.log") +local util = require("scada-common.util") -local style = require("coordinator.ui.style") +local style = require("coordinator.ui.style") -local main_view = require("coordinator.ui.layout.main_view") -local unit_view = require("coordinator.ui.layout.unit_view") +local main_view = require("coordinator.ui.layout.main_view") +local unit_view = require("coordinator.ui.layout.unit_view") -local flasher = require("graphics.flasher") +local flasher = require("graphics.flasher") + +local DisplayBox = require("graphics.elements.displaybox") local renderer = {} -- render engine local engine = { - monitors = nil, - dmesg_window = nil, - ui_ready = false -} - --- UI layouts -local ui = { - main_layout = nil, - unit_layouts = {} + monitors = nil, ---@type monitors_struct|nil + dmesg_window = nil, ---@type table|nil + ui_ready = false, + ui = { + main_display = nil, ---@type graphics_element|nil + unit_displays = {} + } } -- init a display to the "default", but set text scale to 0.5 @@ -57,10 +57,8 @@ function renderer.is_monitor_used(periph) if engine.monitors.primary == periph then return true else - for i = 1, #engine.monitors.unit_displays do - if engine.monitors.unit_displays[i] == periph then - return true - end + for _, monitor in ipairs(engine.monitors.units) do + if monitor == periph then return true end end end end @@ -74,7 +72,7 @@ function renderer.init_displays() _init_display(engine.monitors.primary) -- init unit displays - for _, monitor in pairs(engine.monitors.unit_displays) do + for _, monitor in ipairs(engine.monitors.units) do _init_display(monitor) end end @@ -93,7 +91,7 @@ end function renderer.validate_unit_display_sizes() local valid = true - for id, monitor in pairs(engine.monitors.unit_displays) do + for id, monitor in ipairs(engine.monitors.units) do local w, h = monitor.getSize() if w ~= 79 or h ~= 52 then log.warning(util.c("RENDERER: unit ", id, " display resolution not 79 wide by 52 tall: ", w, ", ", h)) @@ -108,7 +106,6 @@ end function renderer.init_dmesg() local disp_x, disp_y = engine.monitors.primary.getSize() engine.dmesg_window = window.create(engine.monitors.primary, 1, 1, disp_x, disp_y) - log.direct_dmesg(engine.dmesg_window) end @@ -119,11 +116,13 @@ function renderer.start_ui() engine.dmesg_window.setVisible(false) -- show main view on main monitor - ui.main_layout = main_view(engine.monitors.primary) + engine.ui.main_display = DisplayBox{window=engine.monitors.primary,fg_bg=style.root} + main_view(engine.ui.main_display) -- show unit views on unit displays - for id, monitor in pairs(engine.monitors.unit_displays) do - table.insert(ui.unit_layouts, unit_view(monitor, id)) + for i = 1, #engine.monitors.units do + engine.ui.unit_displays[i] = DisplayBox{window=engine.monitors.units[i],fg_bg=style.root} + unit_view(engine.ui.unit_displays[i], i) end -- start flasher callback task @@ -136,29 +135,22 @@ end -- close out the UI function renderer.close_ui() - -- report ui as not ready - engine.ui_ready = false - -- stop blinking indicators flasher.clear() - if engine.ui_ready then - -- hide to stop animation callbacks - ui.main_layout.hide() - for i = 1, #ui.unit_layouts do - ui.unit_layouts[i].hide() - engine.monitors.unit_displays[i].clear() - end - else - -- clear unit displays - for i = 1, #ui.unit_layouts do - engine.monitors.unit_displays[i].clear() - end - end + -- hide to stop animation callbacks + if engine.ui.main_display ~= nil then engine.ui.main_display.hide() end + for _, display in ipairs(engine.ui.unit_displays) do display.hide() end + + -- report ui as not ready + engine.ui_ready = false -- clear root UI elements - ui.main_layout = nil - ui.unit_layouts = {} + engine.ui.main_display = nil + engine.ui.unit_displays = {} + + -- clear unit monitors + for _, monitor in ipairs(engine.monitors.units) do monitor.clear() end -- re-draw dmesg engine.dmesg_window.setVisible(true) @@ -173,13 +165,15 @@ function renderer.ui_ready() return engine.ui_ready end -- handle a touch event ---@param event mouse_interaction function renderer.handle_mouse(event) - if event.monitor == engine.monitors.primary_name then - ui.main_layout.handle_mouse(event) - else - for id, monitor in pairs(engine.monitors.unit_name_map) do - if event.monitor == monitor then - local layout = ui.unit_layouts[id] ---@type graphics_element - layout.handle_mouse(event) + if engine.ui_ready then + if event.monitor == engine.monitors.primary_name then + engine.ui.main_display.handle_mouse(event) + else + for id, monitor in ipairs(engine.monitors.unit_name_map) do + if event.monitor == monitor then + local layout = engine.ui.unit_displays[id] ---@type graphics_element + layout.handle_mouse(event) + end end end end diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 9018547..4cffa5a 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -20,7 +20,7 @@ local sounder = require("coordinator.sounder") local apisessions = require("coordinator.session.apisessions") -local COORDINATOR_VERSION = "v0.13.5" +local COORDINATOR_VERSION = "v0.13.6" local println = util.println local println_ts = util.println_ts diff --git a/coordinator/ui/layout/main_view.lua b/coordinator/ui/layout/main_view.lua index 5c8da4b..a7f8ae2 100644 --- a/coordinator/ui/layout/main_view.lua +++ b/coordinator/ui/layout/main_view.lua @@ -14,7 +14,6 @@ local unit_overview = require("coordinator.ui.components.unit_overview") local core = require("graphics.core") -local DisplayBox = require("graphics.elements.displaybox") local TextBox = require("graphics.elements.textbox") local DataIndicator = require("graphics.elements.indicators.data") @@ -24,13 +23,11 @@ local TEXT_ALIGN = core.graphics.TEXT_ALIGN local cpair = core.graphics.cpair -- create new main view ----@param monitor table main viewscreen -local function init(monitor) +---@param main graphics_element main displaybox +local function init(main) local facility = iocontrol.get_db().facility local units = iocontrol.get_db().units - local main = DisplayBox{window=monitor,fg_bg=style.root} - -- window header message local header = TextBox{parent=main,y=1,text="Nuclear Generation Facility SCADA Coordinator",alignment=TEXT_ALIGN.CENTER,height=1,fg_bg=style.header} local ping = DataIndicator{parent=main,x=1,y=1,label="SVTT",format="%d",value=0,unit="ms",lu_colors=cpair(colors.lightGray, colors.white),width=12,fg_bg=style.header} @@ -87,8 +84,6 @@ local function init(monitor) process_ctl(main, 2, cnc_bottom_align_start) imatrix(main, 131, cnc_bottom_align_start, facility.induction_data_tbl[1], facility.induction_ps_tbl[1]) - - return main end return init diff --git a/coordinator/ui/layout/unit_view.lua b/coordinator/ui/layout/unit_view.lua index 1c5fddf..7ac1b7c 100644 --- a/coordinator/ui/layout/unit_view.lua +++ b/coordinator/ui/layout/unit_view.lua @@ -2,21 +2,13 @@ -- Reactor Unit SCADA Coordinator GUI -- -local style = require("coordinator.ui.style") - local unit_detail = require("coordinator.ui.components.unit_detail") -local DisplayBox = require("graphics.elements.displaybox") - -- create a unit view ----@param monitor table +---@param main graphics_element main displaybox ---@param id integer -local function init(monitor, id) - local main = DisplayBox{window=monitor,fg_bg=style.root} - +local function init(main, id) unit_detail(main, id) - - return main end return init diff --git a/pocket/renderer.lua b/pocket/renderer.lua index 4be1ec6..499b7c7 100644 --- a/pocket/renderer.lua +++ b/pocket/renderer.lua @@ -2,20 +2,22 @@ -- Graphics Rendering Control -- -local main_view = require("pocket.ui.main") -local style = require("pocket.ui.style") +local main_view = require("pocket.ui.main") +local style = require("pocket.ui.style") -local flasher = require("graphics.flasher") +local flasher = require("graphics.flasher") + +local DisplayBox = require("graphics.elements.displaybox") local renderer = {} local ui = { - view = nil + display = nil } -- start the pocket GUI function renderer.start_ui() - if ui.view == nil then + if ui.display == nil then -- reset screen term.setTextColor(colors.white) term.setBackgroundColor(colors.black) @@ -27,11 +29,12 @@ function renderer.start_ui() term.setPaletteColor(style.colors[i].c, style.colors[i].hex) end + -- init front panel view + ui.display = DisplayBox{window=term.current(),fg_bg=style.root} + main_view(ui.display) + -- start flasher callback task flasher.run() - - -- init front panel view - ui.view = main_view(term.current()) end end @@ -40,13 +43,13 @@ function renderer.close_ui() -- stop blinking indicators flasher.clear() - if ui.view ~= nil then + if ui.display ~= nil then -- hide to stop animation callbacks - ui.view.hide() + ui.display.hide() end -- clear root UI elements - ui.view = nil + ui.display = nil -- restore colors for i = 1, #style.colors do @@ -64,12 +67,14 @@ end -- is the UI ready? ---@nodiscard ---@return boolean ready -function renderer.ui_ready() return ui.view ~= nil end +function renderer.ui_ready() return ui.display ~= nil end -- handle a mouse event ---@param event mouse_interaction function renderer.handle_mouse(event) - ui.view.handle_mouse(event) + if ui.display ~= nil then + ui.display.handle_mouse(event) + end end return renderer diff --git a/pocket/startup.lua b/pocket/startup.lua index 0109033..0ad35bc 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -17,7 +17,7 @@ local coreio = require("pocket.coreio") local pocket = require("pocket.pocket") local renderer = require("pocket.renderer") -local POCKET_VERSION = "alpha-v0.2.4" +local POCKET_VERSION = "alpha-v0.2.5" local println = util.println local println_ts = util.println_ts diff --git a/pocket/ui/main.lua b/pocket/ui/main.lua index d8202a7..5af9ce8 100644 --- a/pocket/ui/main.lua +++ b/pocket/ui/main.lua @@ -4,34 +4,31 @@ local coreio = require("pocket.coreio") -local style = require("pocket.ui.style") +local style = require("pocket.ui.style") -local conn_waiting = require("pocket.ui.components.conn_waiting") +local conn_waiting = require("pocket.ui.components.conn_waiting") -local home_page = require("pocket.ui.components.home_page") -local unit_page = require("pocket.ui.components.unit_page") -local reactor_page = require("pocket.ui.components.reactor_page") -local boiler_page = require("pocket.ui.components.boiler_page") -local turbine_page = require("pocket.ui.components.turbine_page") +local home_page = require("pocket.ui.components.home_page") +local unit_page = require("pocket.ui.components.unit_page") +local reactor_page = require("pocket.ui.components.reactor_page") +local boiler_page = require("pocket.ui.components.boiler_page") +local turbine_page = require("pocket.ui.components.turbine_page") -local core = require("graphics.core") +local core = require("graphics.core") -local DisplayBox = require("graphics.elements.displaybox") -local Div = require("graphics.elements.div") -local MultiPane = require("graphics.elements.multipane") -local TextBox = require("graphics.elements.textbox") +local Div = require("graphics.elements.div") +local MultiPane = require("graphics.elements.multipane") +local TextBox = require("graphics.elements.textbox") -local Sidebar = require("graphics.elements.controls.sidebar") +local Sidebar = require("graphics.elements.controls.sidebar") local TEXT_ALIGN = core.graphics.TEXT_ALIGN local cpair = core.graphics.cpair -- create new main view ----@param monitor table main viewscreen -local function init(monitor) - local main = DisplayBox{window=monitor,fg_bg=style.root} - +---@param main graphics_element main displaybox +local function init(main) -- window header message TextBox{parent=main,y=1,text="",alignment=TEXT_ALIGN.LEFT,height=1,fg_bg=style.header} @@ -97,8 +94,6 @@ local function init(monitor) local page_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes} Sidebar{parent=main_pane,x=1,y=1,tabs=sidebar_tabs,fg_bg=cpair(colors.white,colors.gray),callback=page_pane.set_value} - - return main end return init diff --git a/reactor-plc/panel/front_panel.lua b/reactor-plc/panel/front_panel.lua index fed7e02..70c80ef 100644 --- a/reactor-plc/panel/front_panel.lua +++ b/reactor-plc/panel/front_panel.lua @@ -28,7 +28,7 @@ local cpair = core.graphics.cpair local border = core.graphics.border -- create new main view ----@param panel table main displaybox +---@param panel graphics_element main displaybox local function init(panel) local header = TextBox{parent=panel,y=1,text="REACTOR PLC - UNIT ?",alignment=TEXT_ALIGN.CENTER,height=1,fg_bg=style.header} databus.rx_field("unit_id", function (id) header.set_value(util.c("REACTOR PLC - UNIT ", id)) end) @@ -137,8 +137,6 @@ local function init(panel) databus.rx_field("rps_high_waste", rps_wst.update) databus.rx_field("rps_low_ccool", rps_ccl.update) databus.rx_field("rps_high_hcool", rps_hcl.update) - - return panel end return init diff --git a/reactor-plc/renderer.lua b/reactor-plc/renderer.lua index 87b7ffa..4c4f799 100644 --- a/reactor-plc/renderer.lua +++ b/reactor-plc/renderer.lua @@ -29,12 +29,12 @@ function renderer.start_ui() term.setPaletteColor(style.colors[i].c, style.colors[i].hex) end - -- start flasher callback task - flasher.run() - -- init front panel view ui.display = DisplayBox{window=term.current(),fg_bg=style.root} panel_view(ui.display) + + -- start flasher callback task + flasher.run() end end diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 4670694..6189673 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.1.14" +local R_PLC_VERSION = "v1.1.15" local println = util.println local println_ts = util.println_ts diff --git a/rtu/panel/front_panel.lua b/rtu/panel/front_panel.lua index 9bde6c7..f6014da 100644 --- a/rtu/panel/front_panel.lua +++ b/rtu/panel/front_panel.lua @@ -33,7 +33,7 @@ local UNIT_TYPE_LABELS = { -- create new main view ----@param panel table main displaybox +---@param panel graphics_element main displaybox ---@param units table unit list local function init(panel, units) TextBox{parent=panel,y=1,text="RTU GATEWAY",alignment=TEXT_ALIGN.CENTER,height=1,fg_bg=style.header} @@ -116,8 +116,6 @@ local function init(panel, units) local for_unit = util.trinary(unit.reactor == 0, "\x1a FACIL ", "\x1a UNIT " .. unit.reactor) TextBox{parent=unit_hw_statuses,y=i,x=19,text=for_unit,height=1,fg_bg=cpair(colors.lightGray,colors.ivory)} end - - return panel end return init diff --git a/rtu/startup.lua b/rtu/startup.lua index c1b4d60..d670475 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -28,7 +28,7 @@ local sna_rtu = require("rtu.dev.sna_rtu") local sps_rtu = require("rtu.dev.sps_rtu") local turbinev_rtu = require("rtu.dev.turbinev_rtu") -local RTU_VERSION = "v1.0.2" +local RTU_VERSION = "v1.0.3" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE From c75f08a9f794ee4338ad0b42e89dd81ca9d30283 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Fri, 21 Apr 2023 18:56:32 +0000 Subject: [PATCH 49/51] added python to devcontainer and recommendations --- .devcontainer/devcontainer.json | 1 + .vscode/extensions.json | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 272f078..00bf13a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,6 +7,7 @@ "extensions": [ "sumneko.lua", "jackmacwindows.vscode-computercraft", + "ms-python.python", "Catppuccin.catppuccin-vsc-icons", "melishev.feather-vscode" ] diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 72f00e0..db97cc3 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,6 +1,7 @@ { "recommendations": [ "sumneko.lua", - "jackmacwindows.vscode-computercraft" + "jackmacwindows.vscode-computercraft", + "ms-python.python" ] } From 783c4936cccbb8f69a6f5f7351c72ffb85267fc4 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Fri, 21 Apr 2023 21:10:15 +0000 Subject: [PATCH 50/51] #213 strict sequence verification --- coordinator/coordinator.lua | 2 +- coordinator/session/api.lua | 2 +- coordinator/startup.lua | 2 +- install_manifest.json | 2 +- pocket/pocket.lua | 4 ++-- pocket/startup.lua | 2 +- reactor-plc/plc.lua | 2 +- reactor-plc/startup.lua | 2 +- rtu/rtu.lua | 2 +- rtu/startup.lua | 2 +- supervisor/session/coordinator.lua | 2 +- supervisor/session/plc.lua | 2 +- supervisor/session/pocket.lua | 2 +- supervisor/session/rtu.lua | 2 +- supervisor/startup.lua | 2 +- 15 files changed, 16 insertions(+), 16 deletions(-) diff --git a/coordinator/coordinator.lua b/coordinator/coordinator.lua index b13134a..d7e58f7 100644 --- a/coordinator/coordinator.lua +++ b/coordinator/coordinator.lua @@ -506,7 +506,7 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range -- check sequence number if self.sv_r_seq_num == nil then self.sv_r_seq_num = packet.scada_frame.seq_num() - elseif self.connected and self.sv_r_seq_num >= packet.scada_frame.seq_num() then + elseif self.connected and ((self.sv_r_seq_num + 1) ~= packet.scada_frame.seq_num()) then log.warning("sequence out-of-order: last = " .. self.sv_r_seq_num .. ", new = " .. packet.scada_frame.seq_num()) return else diff --git a/coordinator/session/api.lua b/coordinator/session/api.lua index 7ed5a07..4820bef 100644 --- a/coordinator/session/api.lua +++ b/coordinator/session/api.lua @@ -104,7 +104,7 @@ function api.new_session(id, in_queue, out_queue, timeout) -- check sequence number if self.r_seq_num == nil then self.r_seq_num = pkt.scada_frame.seq_num() - elseif self.r_seq_num >= pkt.scada_frame.seq_num() then + elseif (self.r_seq_num + 1) ~= pkt.scada_frame.seq_num() then log.warning(log_header .. "sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num()) return else diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 4cffa5a..a2ff1dc 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -20,7 +20,7 @@ local sounder = require("coordinator.sounder") local apisessions = require("coordinator.session.apisessions") -local COORDINATOR_VERSION = "v0.13.6" +local COORDINATOR_VERSION = "v0.13.7" local println = util.println local println_ts = util.println_ts diff --git a/install_manifest.json b/install_manifest.json index 0bae10d..0f0a2d2 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.1.14", "rtu": "v1.0.2", "supervisor": "v0.15.4", "coordinator": "v0.13.5", "pocket": "alpha-v0.2.4"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/api.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/turbine_page.lua", "pocket/ui/components/reactor_page.lua", "pocket/ui/components/home_page.lua", "pocket/ui/components/unit_page.lua", "pocket/ui/components/boiler_page.lua", "pocket/ui/components/conn_waiting.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5467, "system": 1991, "common": 90337, "graphics": 115781, "lockbox": 100797, "reactor-plc": 95274, "rtu": 100077, "supervisor": 282682, "coordinator": 196065, "pocket": 36014}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.1.16", "rtu": "v1.0.4", "supervisor": "v0.15.5", "coordinator": "v0.13.7", "pocket": "alpha-v0.2.6"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/constants.lua", "scada-common/crypto.lua", "scada-common/types.lua", "scada-common/comms.lua", "scada-common/mqueue.lua", "scada-common/util.lua", "scada-common/psil.lua", "scada-common/crash.lua", "scada-common/rsio.lua", "scada-common/ppm.lua", "scada-common/tcallbackdsp.lua", "scada-common/log.lua"], "graphics": ["graphics/core.lua", "graphics/flasher.lua", "graphics/element.lua", "graphics/elements/div.lua", "graphics/elements/colormap.lua", "graphics/elements/textbox.lua", "graphics/elements/pipenet.lua", "graphics/elements/multipane.lua", "graphics/elements/displaybox.lua", "graphics/elements/rectangle.lua", "graphics/elements/tiling.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/animations/waiting.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/indicators/alight.lua"], "lockbox": ["lockbox/LICENSE", "lockbox/init.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/digest/sha2_224.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/mac/hmac.lua", "lockbox/kdf/pbkdf2.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/isoiec7816.lua", "lockbox/padding/zero.lua", "lockbox/padding/pkcs7.lua", "lockbox/util/stream.lua", "lockbox/util/bit.lua", "lockbox/util/queue.lua", "lockbox/util/array.lua"], "reactor-plc": ["reactor-plc/config.lua", "reactor-plc/plc.lua", "reactor-plc/renderer.lua", "reactor-plc/databus.lua", "reactor-plc/startup.lua", "reactor-plc/threads.lua", "reactor-plc/panel/style.lua", "reactor-plc/panel/front_panel.lua"], "rtu": ["rtu/modbus.lua", "rtu/rtu.lua", "rtu/config.lua", "rtu/renderer.lua", "rtu/databus.lua", "rtu/startup.lua", "rtu/threads.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/turbinev_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/panel/style.lua", "rtu/panel/front_panel.lua"], "supervisor": ["supervisor/unit.lua", "supervisor/supervisor.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/facility.lua", "supervisor/unitlogic.lua", "supervisor/session/coordinator.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/svsessions.lua", "supervisor/session/pocket.lua", "supervisor/session/svqtypes.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/redstone.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/sps.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/iocontrol.lua", "coordinator/config.lua", "coordinator/renderer.lua", "coordinator/startup.lua", "coordinator/sounder.lua", "coordinator/process.lua", "coordinator/session/api.lua", "coordinator/session/apisessions.lua", "coordinator/ui/style.lua", "coordinator/ui/dialog.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/turbine.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua"], "pocket": ["pocket/config.lua", "pocket/renderer.lua", "pocket/startup.lua", "pocket/coreio.lua", "pocket/pocket.lua", "pocket/ui/style.lua", "pocket/ui/main.lua", "pocket/ui/components/reactor_page.lua", "pocket/ui/components/boiler_page.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/components/home_page.lua", "pocket/ui/components/unit_page.lua", "pocket/ui/components/turbine_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5467, "system": 1991, "common": 90337, "graphics": 115781, "lockbox": 100797, "reactor-plc": 95464, "rtu": 100717, "supervisor": 282706, "coordinator": 195929, "pocket": 36066}} \ No newline at end of file diff --git a/pocket/pocket.lua b/pocket/pocket.lua index 97ad87a..cd999c6 100644 --- a/pocket/pocket.lua +++ b/pocket/pocket.lua @@ -224,7 +224,7 @@ function pocket.comms(version, modem, local_port, sv_port, api_port, range, sv_w -- check sequence number if self.api.r_seq_num == nil then self.api.r_seq_num = packet.scada_frame.seq_num() - elseif self.connected and self.api.r_seq_num >= packet.scada_frame.seq_num() then + elseif self.connected and ((self.api.r_seq_num + 1) ~= packet.scada_frame.seq_num()) then log.warning("sequence out-of-order: last = " .. self.api.r_seq_num .. ", new = " .. packet.scada_frame.seq_num()) return else @@ -308,7 +308,7 @@ function pocket.comms(version, modem, local_port, sv_port, api_port, range, sv_w -- check sequence number if self.sv.r_seq_num == nil then self.sv.r_seq_num = packet.scada_frame.seq_num() - elseif self.connected and self.sv.r_seq_num >= packet.scada_frame.seq_num() then + elseif self.connected and ((self.sv.r_seq_num + 1) ~= packet.scada_frame.seq_num()) then log.warning("sequence out-of-order: last = " .. self.sv.r_seq_num .. ", new = " .. packet.scada_frame.seq_num()) return else diff --git a/pocket/startup.lua b/pocket/startup.lua index 0ad35bc..a396748 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -17,7 +17,7 @@ local coreio = require("pocket.coreio") local pocket = require("pocket.pocket") local renderer = require("pocket.renderer") -local POCKET_VERSION = "alpha-v0.2.5" +local POCKET_VERSION = "alpha-v0.2.6" local println = util.println local println_ts = util.println_ts diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index d89e86f..4f04138 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -782,7 +782,7 @@ function plc.comms(id, version, modem, local_port, server_port, range, reactor, -- check sequence number if self.r_seq_num == nil then self.r_seq_num = packet.scada_frame.seq_num() - elseif self.linked and self.r_seq_num >= packet.scada_frame.seq_num() then + elseif self.linked and ((self.r_seq_num + 1) ~= packet.scada_frame.seq_num()) then log.warning("sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. packet.scada_frame.seq_num()) return else diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 6189673..8de0790 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.1.15" +local R_PLC_VERSION = "v1.1.16" local println = util.println local println_ts = util.println_ts diff --git a/rtu/rtu.lua b/rtu/rtu.lua index 689d7c4..bb43706 100644 --- a/rtu/rtu.lua +++ b/rtu/rtu.lua @@ -331,7 +331,7 @@ function rtu.comms(version, modem, local_port, server_port, range, conn_watchdog -- check sequence number if self.r_seq_num == nil then self.r_seq_num = packet.scada_frame.seq_num() - elseif rtu_state.linked and self.r_seq_num >= packet.scada_frame.seq_num() then + elseif rtu_state.linked and ((self.r_seq_num + 1) ~= packet.scada_frame.seq_num()) then log.warning("sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. packet.scada_frame.seq_num()) return else diff --git a/rtu/startup.lua b/rtu/startup.lua index d670475..39024cb 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -28,7 +28,7 @@ local sna_rtu = require("rtu.dev.sna_rtu") local sps_rtu = require("rtu.dev.sps_rtu") local turbinev_rtu = require("rtu.dev.turbinev_rtu") -local RTU_VERSION = "v1.0.3" +local RTU_VERSION = "v1.0.4" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE diff --git a/supervisor/session/coordinator.lua b/supervisor/session/coordinator.lua index 50cbfdb..b093d87 100644 --- a/supervisor/session/coordinator.lua +++ b/supervisor/session/coordinator.lua @@ -178,7 +178,7 @@ function coordinator.new_session(id, in_queue, out_queue, timeout, facility) -- check sequence number if self.r_seq_num == nil then self.r_seq_num = pkt.scada_frame.seq_num() - elseif self.r_seq_num >= pkt.scada_frame.seq_num() then + elseif (self.r_seq_num + 1) ~= pkt.scada_frame.seq_num() then log.warning(log_header .. "sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num()) return else diff --git a/supervisor/session/plc.lua b/supervisor/session/plc.lua index fd15808..cca8a26 100644 --- a/supervisor/session/plc.lua +++ b/supervisor/session/plc.lua @@ -284,7 +284,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) -- check sequence number if self.r_seq_num == nil then self.r_seq_num = pkt.scada_frame.seq_num() - elseif self.r_seq_num >= pkt.scada_frame.seq_num() then + elseif (self.r_seq_num + 1) ~= pkt.scada_frame.seq_num() then log.warning(log_header .. "sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num()) return else diff --git a/supervisor/session/pocket.lua b/supervisor/session/pocket.lua index e760512..9cf0a5d 100644 --- a/supervisor/session/pocket.lua +++ b/supervisor/session/pocket.lua @@ -89,7 +89,7 @@ function pocket.new_session(id, in_queue, out_queue, timeout) -- check sequence number if self.r_seq_num == nil then self.r_seq_num = pkt.scada_frame.seq_num() - elseif self.r_seq_num >= pkt.scada_frame.seq_num() then + elseif (self.r_seq_num + 1) ~= pkt.scada_frame.seq_num() then log.warning(log_header .. "sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num()) return else diff --git a/supervisor/session/rtu.lua b/supervisor/session/rtu.lua index 7da723c..96309a0 100644 --- a/supervisor/session/rtu.lua +++ b/supervisor/session/rtu.lua @@ -214,7 +214,7 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili -- check sequence number if self.r_seq_num == nil then self.r_seq_num = pkt.scada_frame.seq_num() - elseif self.r_seq_num >= pkt.scada_frame.seq_num() then + elseif (self.r_seq_num + 1) ~= pkt.scada_frame.seq_num() then log.warning(log_header .. "sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num()) return else diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 397674a..bf27e2e 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -14,7 +14,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.15.4" +local SUPERVISOR_VERSION = "v0.15.5" local println = util.println local println_ts = util.println_ts From 43e708aa0da09cc97c83c02a3f7052ec6bd6033e Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Fri, 21 Apr 2023 23:43:28 -0400 Subject: [PATCH 51/51] #219 bugfixes with renderer exit handling --- coordinator/renderer.lua | 12 ++++++------ coordinator/session/api.lua | 4 ++-- coordinator/startup.lua | 2 +- install_manifest.json | 2 +- pocket/pocket.lua | 4 ++-- pocket/renderer.lua | 36 ++++++++++++++++++------------------ pocket/startup.lua | 2 +- reactor-plc/renderer.lua | 36 ++++++++++++++++++------------------ reactor-plc/startup.lua | 2 +- rtu/renderer.lua | 36 ++++++++++++++++++------------------ rtu/startup.lua | 2 +- 11 files changed, 69 insertions(+), 69 deletions(-) diff --git a/coordinator/renderer.lua b/coordinator/renderer.lua index f354d3c..4aa0b53 100644 --- a/coordinator/renderer.lua +++ b/coordinator/renderer.lua @@ -57,7 +57,7 @@ function renderer.is_monitor_used(periph) if engine.monitors.primary == periph then return true else - for _, monitor in ipairs(engine.monitors.units) do + for _, monitor in ipairs(engine.monitors.unit_displays) do if monitor == periph then return true end end end @@ -72,7 +72,7 @@ function renderer.init_displays() _init_display(engine.monitors.primary) -- init unit displays - for _, monitor in ipairs(engine.monitors.units) do + for _, monitor in ipairs(engine.monitors.unit_displays) do _init_display(monitor) end end @@ -91,7 +91,7 @@ end function renderer.validate_unit_display_sizes() local valid = true - for id, monitor in ipairs(engine.monitors.units) do + for id, monitor in ipairs(engine.monitors.unit_displays) do local w, h = monitor.getSize() if w ~= 79 or h ~= 52 then log.warning(util.c("RENDERER: unit ", id, " display resolution not 79 wide by 52 tall: ", w, ", ", h)) @@ -120,8 +120,8 @@ function renderer.start_ui() main_view(engine.ui.main_display) -- show unit views on unit displays - for i = 1, #engine.monitors.units do - engine.ui.unit_displays[i] = DisplayBox{window=engine.monitors.units[i],fg_bg=style.root} + for i = 1, #engine.monitors.unit_displays do + engine.ui.unit_displays[i] = DisplayBox{window=engine.monitors.unit_displays[i],fg_bg=style.root} unit_view(engine.ui.unit_displays[i], i) end @@ -150,7 +150,7 @@ function renderer.close_ui() engine.ui.unit_displays = {} -- clear unit monitors - for _, monitor in ipairs(engine.monitors.units) do monitor.clear() end + for _, monitor in ipairs(engine.monitors.unit_displays) do monitor.clear() end -- re-draw dmesg engine.dmesg_window.setVisible(true) diff --git a/coordinator/session/api.lua b/coordinator/session/api.lua index 4820bef..8f21483 100644 --- a/coordinator/session/api.lua +++ b/coordinator/session/api.lua @@ -71,8 +71,8 @@ function api.new_session(id, in_queue, out_queue, timeout) end -- send a CAPI packet - ---@param msg_type CAPI_TYPE - ---@param msg table + -----@param msg_type CAPI_TYPE + -----@param msg table -- local function _send(msg_type, msg) -- local s_pkt = comms.scada_packet() -- local c_pkt = comms.capi_packet() diff --git a/coordinator/startup.lua b/coordinator/startup.lua index a2ff1dc..97408da 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -20,7 +20,7 @@ local sounder = require("coordinator.sounder") local apisessions = require("coordinator.session.apisessions") -local COORDINATOR_VERSION = "v0.13.7" +local COORDINATOR_VERSION = "v0.13.8" local println = util.println local println_ts = util.println_ts diff --git a/install_manifest.json b/install_manifest.json index 0f0a2d2..91054c0 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.1.16", "rtu": "v1.0.4", "supervisor": "v0.15.5", "coordinator": "v0.13.7", "pocket": "alpha-v0.2.6"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/constants.lua", "scada-common/crypto.lua", "scada-common/types.lua", "scada-common/comms.lua", "scada-common/mqueue.lua", "scada-common/util.lua", "scada-common/psil.lua", "scada-common/crash.lua", "scada-common/rsio.lua", "scada-common/ppm.lua", "scada-common/tcallbackdsp.lua", "scada-common/log.lua"], "graphics": ["graphics/core.lua", "graphics/flasher.lua", "graphics/element.lua", "graphics/elements/div.lua", "graphics/elements/colormap.lua", "graphics/elements/textbox.lua", "graphics/elements/pipenet.lua", "graphics/elements/multipane.lua", "graphics/elements/displaybox.lua", "graphics/elements/rectangle.lua", "graphics/elements/tiling.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/animations/waiting.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/indicators/alight.lua"], "lockbox": ["lockbox/LICENSE", "lockbox/init.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/digest/sha2_224.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/mac/hmac.lua", "lockbox/kdf/pbkdf2.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/isoiec7816.lua", "lockbox/padding/zero.lua", "lockbox/padding/pkcs7.lua", "lockbox/util/stream.lua", "lockbox/util/bit.lua", "lockbox/util/queue.lua", "lockbox/util/array.lua"], "reactor-plc": ["reactor-plc/config.lua", "reactor-plc/plc.lua", "reactor-plc/renderer.lua", "reactor-plc/databus.lua", "reactor-plc/startup.lua", "reactor-plc/threads.lua", "reactor-plc/panel/style.lua", "reactor-plc/panel/front_panel.lua"], "rtu": ["rtu/modbus.lua", "rtu/rtu.lua", "rtu/config.lua", "rtu/renderer.lua", "rtu/databus.lua", "rtu/startup.lua", "rtu/threads.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/turbinev_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/panel/style.lua", "rtu/panel/front_panel.lua"], "supervisor": ["supervisor/unit.lua", "supervisor/supervisor.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/facility.lua", "supervisor/unitlogic.lua", "supervisor/session/coordinator.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/svsessions.lua", "supervisor/session/pocket.lua", "supervisor/session/svqtypes.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/redstone.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/sps.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/iocontrol.lua", "coordinator/config.lua", "coordinator/renderer.lua", "coordinator/startup.lua", "coordinator/sounder.lua", "coordinator/process.lua", "coordinator/session/api.lua", "coordinator/session/apisessions.lua", "coordinator/ui/style.lua", "coordinator/ui/dialog.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/turbine.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua"], "pocket": ["pocket/config.lua", "pocket/renderer.lua", "pocket/startup.lua", "pocket/coreio.lua", "pocket/pocket.lua", "pocket/ui/style.lua", "pocket/ui/main.lua", "pocket/ui/components/reactor_page.lua", "pocket/ui/components/boiler_page.lua", "pocket/ui/components/conn_waiting.lua", "pocket/ui/components/home_page.lua", "pocket/ui/components/unit_page.lua", "pocket/ui/components/turbine_page.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5467, "system": 1991, "common": 90337, "graphics": 115781, "lockbox": 100797, "reactor-plc": 95464, "rtu": 100717, "supervisor": 282706, "coordinator": 195929, "pocket": 36066}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.1.17", "rtu": "v1.0.5", "supervisor": "v0.15.5", "coordinator": "v0.13.8", "pocket": "alpha-v0.2.6"}, "files": {"system": ["initenv.lua", "startup.lua"], "common": ["scada-common/crypto.lua", "scada-common/ppm.lua", "scada-common/comms.lua", "scada-common/psil.lua", "scada-common/tcallbackdsp.lua", "scada-common/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/textbox.lua", "graphics/elements/displaybox.lua", "graphics/elements/pipenet.lua", "graphics/elements/rectangle.lua", "graphics/elements/div.lua", "graphics/elements/multipane.lua", "graphics/elements/tiling.lua", "graphics/elements/colormap.lua", "graphics/elements/indicators/alight.lua", "graphics/elements/indicators/icon.lua", "graphics/elements/indicators/power.lua", "graphics/elements/indicators/rad.lua", "graphics/elements/indicators/state.lua", "graphics/elements/indicators/light.lua", "graphics/elements/indicators/vbar.lua", "graphics/elements/indicators/led.lua", "graphics/elements/indicators/coremap.lua", "graphics/elements/indicators/data.lua", "graphics/elements/indicators/ledpair.lua", "graphics/elements/indicators/hbar.lua", "graphics/elements/indicators/trilight.lua", "graphics/elements/indicators/ledrgb.lua", "graphics/elements/controls/switch_button.lua", "graphics/elements/controls/spinbox_numeric.lua", "graphics/elements/controls/hazard_button.lua", "graphics/elements/controls/push_button.lua", "graphics/elements/controls/radio_button.lua", "graphics/elements/controls/multi_button.lua", "graphics/elements/controls/sidebar.lua", "graphics/elements/animations/waiting.lua"], "lockbox": ["lockbox/init.lua", "lockbox/LICENSE", "lockbox/kdf/pbkdf2.lua", "lockbox/util/bit.lua", "lockbox/util/array.lua", "lockbox/util/stream.lua", "lockbox/util/queue.lua", "lockbox/digest/sha2_224.lua", "lockbox/digest/sha1.lua", "lockbox/digest/sha2_256.lua", "lockbox/cipher/aes128.lua", "lockbox/cipher/aes256.lua", "lockbox/cipher/aes192.lua", "lockbox/cipher/mode/ofb.lua", "lockbox/cipher/mode/cbc.lua", "lockbox/cipher/mode/ctr.lua", "lockbox/cipher/mode/cfb.lua", "lockbox/mac/hmac.lua", "lockbox/padding/ansix923.lua", "lockbox/padding/pkcs7.lua", "lockbox/padding/zero.lua", "lockbox/padding/isoiec7816.lua"], "reactor-plc": ["reactor-plc/renderer.lua", "reactor-plc/threads.lua", "reactor-plc/databus.lua", "reactor-plc/plc.lua", "reactor-plc/config.lua", "reactor-plc/startup.lua", "reactor-plc/panel/front_panel.lua", "reactor-plc/panel/style.lua"], "rtu": ["rtu/renderer.lua", "rtu/threads.lua", "rtu/rtu.lua", "rtu/databus.lua", "rtu/modbus.lua", "rtu/config.lua", "rtu/startup.lua", "rtu/panel/front_panel.lua", "rtu/panel/style.lua", "rtu/dev/sps_rtu.lua", "rtu/dev/envd_rtu.lua", "rtu/dev/boilerv_rtu.lua", "rtu/dev/redstone_rtu.lua", "rtu/dev/sna_rtu.lua", "rtu/dev/imatrix_rtu.lua", "rtu/dev/turbinev_rtu.lua"], "supervisor": ["supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/session/coordinator.lua", "supervisor/session/svqtypes.lua", "supervisor/session/pocket.lua", "supervisor/session/svsessions.lua", "supervisor/session/rtu.lua", "supervisor/session/plc.lua", "supervisor/session/rsctl.lua", "supervisor/session/rtu/boilerv.lua", "supervisor/session/rtu/txnctrl.lua", "supervisor/session/rtu/unit_session.lua", "supervisor/session/rtu/turbinev.lua", "supervisor/session/rtu/envd.lua", "supervisor/session/rtu/imatrix.lua", "supervisor/session/rtu/sps.lua", "supervisor/session/rtu/qtypes.lua", "supervisor/session/rtu/sna.lua", "supervisor/session/rtu/redstone.lua"], "coordinator": ["coordinator/coordinator.lua", "coordinator/renderer.lua", "coordinator/iocontrol.lua", "coordinator/sounder.lua", "coordinator/config.lua", "coordinator/startup.lua", "coordinator/process.lua", "coordinator/ui/dialog.lua", "coordinator/ui/style.lua", "coordinator/ui/layout/main_view.lua", "coordinator/ui/layout/unit_view.lua", "coordinator/ui/components/reactor.lua", "coordinator/ui/components/processctl.lua", "coordinator/ui/components/unit_overview.lua", "coordinator/ui/components/boiler.lua", "coordinator/ui/components/unit_detail.lua", "coordinator/ui/components/imatrix.lua", "coordinator/ui/components/turbine.lua", "coordinator/session/api.lua", "coordinator/session/apisessions.lua"], "pocket": ["pocket/pocket.lua", "pocket/renderer.lua", "pocket/config.lua", "pocket/coreio.lua", "pocket/startup.lua", "pocket/ui/main.lua", "pocket/ui/style.lua", "pocket/ui/components/turbine_page.lua", "pocket/ui/components/reactor_page.lua", "pocket/ui/components/home_page.lua", "pocket/ui/components/unit_page.lua", "pocket/ui/components/boiler_page.lua", "pocket/ui/components/conn_waiting.lua"]}, "depends": {"reactor-plc": ["system", "common", "graphics"], "rtu": ["system", "common", "graphics"], "supervisor": ["system", "common"], "coordinator": ["system", "common", "graphics"], "pocket": ["system", "common", "graphics"]}, "sizes": {"manifest": 5467, "system": 1991, "common": 90337, "graphics": 115781, "lockbox": 100797, "reactor-plc": 95517, "rtu": 100134, "supervisor": 282706, "coordinator": 195981, "pocket": 36123}} \ No newline at end of file diff --git a/pocket/pocket.lua b/pocket/pocket.lua index cd999c6..cc4d870 100644 --- a/pocket/pocket.lua +++ b/pocket/pocket.lua @@ -82,8 +82,8 @@ function pocket.comms(version, modem, local_port, sv_port, api_port, range, sv_w end -- send a packet to the coordinator API - ---@param msg_type CAPI_TYPE - ---@param msg table + -----@param msg_type CAPI_TYPE + -----@param msg table -- local function _send_api(msg_type, msg) -- local s_pkt = comms.scada_packet() -- local pkt = comms.capi_packet() diff --git a/pocket/renderer.lua b/pocket/renderer.lua index 499b7c7..1ecf3ab 100644 --- a/pocket/renderer.lua +++ b/pocket/renderer.lua @@ -40,28 +40,28 @@ end -- close out the UI function renderer.close_ui() - -- stop blinking indicators - flasher.clear() - if ui.display ~= nil then + -- stop blinking indicators + flasher.clear() + -- hide to stop animation callbacks ui.display.hide() + + -- clear root UI elements + ui.display = nil + + -- restore colors + for i = 1, #style.colors do + local r, g, b = term.nativePaletteColor(style.colors[i].c) + term.setPaletteColor(style.colors[i].c, r, g, b) + end + + -- reset terminal + term.setTextColor(colors.white) + term.setBackgroundColor(colors.black) + term.clear() + term.setCursorPos(1, 1) end - - -- clear root UI elements - ui.display = nil - - -- restore colors - for i = 1, #style.colors do - local r, g, b = term.nativePaletteColor(style.colors[i].c) - term.setPaletteColor(style.colors[i].c, r, g, b) - end - - -- reset terminal - term.setTextColor(colors.white) - term.setBackgroundColor(colors.black) - term.clear() - term.setCursorPos(1, 1) end -- is the UI ready? diff --git a/pocket/startup.lua b/pocket/startup.lua index a396748..9516340 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -104,7 +104,7 @@ local function main() local ui_ok, message = pcall(renderer.start_ui) if not ui_ok then renderer.close_ui() - println_ts(util.c("UI error: ", message)) + println(util.c("UI error: ", message)) log.error(util.c("startup> GUI crashed with error ", message)) else -- start clock diff --git a/reactor-plc/renderer.lua b/reactor-plc/renderer.lua index 4c4f799..0700ebe 100644 --- a/reactor-plc/renderer.lua +++ b/reactor-plc/renderer.lua @@ -40,28 +40,28 @@ end -- close out the UI function renderer.close_ui() - -- stop blinking indicators - flasher.clear() - if ui.display ~= nil then + -- stop blinking indicators + flasher.clear() + -- hide to stop animation callbacks ui.display.hide() + + -- clear root UI elements + ui.display = nil + + -- restore colors + for i = 1, #style.colors do + local r, g, b = term.nativePaletteColor(style.colors[i].c) + term.setPaletteColor(style.colors[i].c, r, g, b) + end + + -- reset terminal + term.setTextColor(colors.white) + term.setBackgroundColor(colors.black) + term.clear() + term.setCursorPos(1, 1) end - - -- clear root UI elements - ui.display = nil - - -- restore colors - for i = 1, #style.colors do - local r, g, b = term.nativePaletteColor(style.colors[i].c) - term.setPaletteColor(style.colors[i].c, r, g, b) - end - - -- reset terminal - term.setTextColor(colors.white) - term.setBackgroundColor(colors.black) - term.clear() - term.setCursorPos(1, 1) end -- is the UI ready? diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 8de0790..bd40fce 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.1.16" +local R_PLC_VERSION = "v1.1.17" local println = util.println local println_ts = util.println_ts diff --git a/rtu/renderer.lua b/rtu/renderer.lua index 0ac1d58..f79f19e 100644 --- a/rtu/renderer.lua +++ b/rtu/renderer.lua @@ -41,28 +41,28 @@ end -- close out the UI function renderer.close_ui() - -- stop blinking indicators - flasher.clear() - if ui.display ~= nil then + -- stop blinking indicators + flasher.clear() + -- hide to stop animation callbacks ui.display.hide() + + -- clear root UI elements + ui.display = nil + + -- restore colors + for i = 1, #style.colors do + local r, g, b = term.nativePaletteColor(style.colors[i].c) + term.setPaletteColor(style.colors[i].c, r, g, b) + end + + -- reset terminal + term.setTextColor(colors.white) + term.setBackgroundColor(colors.black) + term.clear() + term.setCursorPos(1, 1) end - - -- clear root UI elements - ui.display = nil - - -- restore colors - for i = 1, #style.colors do - local r, g, b = term.nativePaletteColor(style.colors[i].c) - term.setPaletteColor(style.colors[i].c, r, g, b) - end - - -- reset terminal - term.setTextColor(colors.white) - term.setBackgroundColor(colors.black) - term.clear() - term.setCursorPos(1, 1) end -- is the UI ready? diff --git a/rtu/startup.lua b/rtu/startup.lua index 39024cb..e2d9d94 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -28,7 +28,7 @@ local sna_rtu = require("rtu.dev.sna_rtu") local sps_rtu = require("rtu.dev.sps_rtu") local turbinev_rtu = require("rtu.dev.turbinev_rtu") -local RTU_VERSION = "v1.0.4" +local RTU_VERSION = "v1.0.5" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE