From 81005d3e2c789428d7e340af4ac29f84441caac2 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 29 Apr 2023 23:48:50 -0400 Subject: [PATCH 01/49] pocket cleanup --- pocket/startup.lua | 80 +++++++++---------- pocket/ui/main.lua | 10 +-- .../ui/{components => pages}/boiler_page.lua | 0 pocket/ui/{components => pages}/home_page.lua | 0 .../ui/{components => pages}/reactor_page.lua | 0 .../ui/{components => pages}/turbine_page.lua | 0 pocket/ui/{components => pages}/unit_page.lua | 0 7 files changed, 45 insertions(+), 45 deletions(-) rename pocket/ui/{components => pages}/boiler_page.lua (100%) rename pocket/ui/{components => pages}/home_page.lua (100%) rename pocket/ui/{components => pages}/reactor_page.lua (100%) rename pocket/ui/{components => pages}/turbine_page.lua (100%) rename pocket/ui/{components => pages}/unit_page.lua (100%) diff --git a/pocket/startup.lua b/pocket/startup.lua index 9516340..8397437 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.6" +local POCKET_VERSION = "alpha-v0.2.7" local println = util.println local println_ts = util.println_ts @@ -120,54 +120,54 @@ local function main() conn_wd.sv.feed() conn_wd.api.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() + -- main event loop + while true 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 + -- handle event + if event == "timer" then + if loop_clock.is_clock(param1) then + -- main loop tick - -- relink if necessary - pocket_comms.link_update() + -- 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) + 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) + 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 server connections...") + pocket_comms.close() + log.info("connections closed") + break 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) - 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 server connections...") - pocket_comms.close() - log.info("connections closed") - break - end + renderer.close_ui() end - renderer.close_ui() - println_ts("exited") log.info("exited") end diff --git a/pocket/ui/main.lua b/pocket/ui/main.lua index 5af9ce8..18302a3 100644 --- a/pocket/ui/main.lua +++ b/pocket/ui/main.lua @@ -8,11 +8,11 @@ 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 home_page = require("pocket.ui.pages.home_page") +local unit_page = require("pocket.ui.pages.unit_page") +local reactor_page = require("pocket.ui.pages.reactor_page") +local boiler_page = require("pocket.ui.pages.boiler_page") +local turbine_page = require("pocket.ui.pages.turbine_page") local core = require("graphics.core") diff --git a/pocket/ui/components/boiler_page.lua b/pocket/ui/pages/boiler_page.lua similarity index 100% rename from pocket/ui/components/boiler_page.lua rename to pocket/ui/pages/boiler_page.lua diff --git a/pocket/ui/components/home_page.lua b/pocket/ui/pages/home_page.lua similarity index 100% rename from pocket/ui/components/home_page.lua rename to pocket/ui/pages/home_page.lua diff --git a/pocket/ui/components/reactor_page.lua b/pocket/ui/pages/reactor_page.lua similarity index 100% rename from pocket/ui/components/reactor_page.lua rename to pocket/ui/pages/reactor_page.lua diff --git a/pocket/ui/components/turbine_page.lua b/pocket/ui/pages/turbine_page.lua similarity index 100% rename from pocket/ui/components/turbine_page.lua rename to pocket/ui/pages/turbine_page.lua diff --git a/pocket/ui/components/unit_page.lua b/pocket/ui/pages/unit_page.lua similarity index 100% rename from pocket/ui/components/unit_page.lua rename to pocket/ui/pages/unit_page.lua From ff9a18a019b4dab151a7308e6be434547e3c070a Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 29 Apr 2023 23:49:04 -0400 Subject: [PATCH 02/49] rtu log message cleanup --- rtu/startup.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtu/startup.lua b/rtu/startup.lua index e2d9d94..97832fa 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.5" +local RTU_VERSION = "v1.0.6" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE @@ -457,9 +457,9 @@ local function main() if not rtu_state.fp_ok then renderer.close_ui() println_ts(util.c("UI error: ", message)) - println("init> running without front panel") + println("startup> running without front panel") log.error(util.c("GUI crashed with error ", message)) - log.info("init> running in headless mode without front panel") + log.info("startup> running in headless mode without front panel") end -- start connection watchdog From 2c7b98ba42e676588ee982d711f2159570bfdcc2 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Fri, 5 May 2023 13:04:13 -0400 Subject: [PATCH 03/49] #184 WIP supervisor front panel --- supervisor/databus.lua | 44 ++++++ supervisor/panel/components/plc_entry.lua | 0 supervisor/panel/front_panel.lua | 91 +++++++++++++ supervisor/panel/style.lua | 41 ++++++ supervisor/renderer.lua | 80 +++++++++++ supervisor/session/coordinator.lua | 3 +- supervisor/session/plc.lua | 3 +- supervisor/session/pocket.lua | 3 +- supervisor/session/rtu.lua | 3 +- supervisor/session/svsessions.lua | 1 + supervisor/startup.lua | 159 +++++++++++++--------- supervisor/supervisor.lua | 3 +- 12 files changed, 365 insertions(+), 66 deletions(-) create mode 100644 supervisor/databus.lua create mode 100644 supervisor/panel/components/plc_entry.lua create mode 100644 supervisor/panel/front_panel.lua create mode 100644 supervisor/panel/style.lua create mode 100644 supervisor/renderer.lua diff --git a/supervisor/databus.lua b/supervisor/databus.lua new file mode 100644 index 0000000..e6bbee7 --- /dev/null +++ b/supervisor/databus.lua @@ -0,0 +1,44 @@ +-- +-- Data Bus - Central Communication Linking for Supervisor Front Panel +-- + +local psil = require("scada-common.psil") + +local databus = {} + +local dbus_iface = { + ps = psil.create(), + session_entries = { rtu = {}, plc = {}, coord = {}, diag = {} } +} + +-- call to toggle heartbeat signal +function databus.heartbeat() dbus_iface.ps.toggle("heartbeat") end + +-- transmit firmware versions across the bus +---@param plc_v string supervisor version +---@param comms_v string comms version +function databus.tx_versions(plc_v, comms_v) + dbus_iface.ps.publish("version", plc_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 + +function databus.tx_svs_connection(type, data) +end + +function databus.tx_svs_disconnection(type, data) +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/supervisor/panel/components/plc_entry.lua b/supervisor/panel/components/plc_entry.lua new file mode 100644 index 0000000..e69de29 diff --git a/supervisor/panel/front_panel.lua b/supervisor/panel/front_panel.lua new file mode 100644 index 0000000..0098a6e --- /dev/null +++ b/supervisor/panel/front_panel.lua @@ -0,0 +1,91 @@ +-- +-- Main SCADA Coordinator GUI +-- + +local util = require("scada-common.util") + +local databus = require("supervisor.databus") + +local style = require("supervisor.panel.style") + +local core = require("graphics.core") + +local Div = require("graphics.elements.div") +local MultiPane = require("graphics.elements.multipane") +local Rectangle = require("graphics.elements.rectangle") +local TextBox = require("graphics.elements.textbox") + +local PushButton = require("graphics.elements.controls.push_button") +local TabBar = require("graphics.elements.controls.tabbar") + +local LED = require("graphics.elements.indicators.led") +local LEDPair = require("graphics.elements.indicators.ledpair") +local RGBLED = require("graphics.elements.indicators.ledrgb") + +local TEXT_ALIGN = core.graphics.TEXT_ALIGN + +local cpair = core.graphics.cpair +local border = core.graphics.border + +-- create new main view +---@param panel graphics_element main displaybox +local function init(panel) + TextBox{parent=panel,y=1,text="SCADA SUPERVISOR",alignment=TEXT_ALIGN.CENTER,height=1,fg_bg=style.header} + + local page_div = Div{parent=panel,x=1,y=3} + + -- + -- system indicators + -- + + local main_page = Div{parent=page_div,x=1,y=1} + + local system = Div{parent=main_page,width=14,height=17,x=2,y=2} + + 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)} + system.line_break() + + databus.rx_field("has_modem", modem.update) + + -- + -- about footer + -- + + local about = Div{parent=main_page,width=15,height=3,x=1,y=16,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) + + -- + -- page handling + -- + + local plc_list = Div{parent=page_div,x=1,y=1} + + TextBox{parent=plc_list,x=2,y=2,text="v1.1.17 - PLC - UNIT 4 - :15004",alignment=TEXT_ALIGN.LEFT,height=1} + + local panes = { main_page, plc_list, main_page, main_page, main_page } + + local page_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes} + + local tabs = { + { name = "Main", color = cpair(colors.black, colors.ivory) }, + { name = "PLCs", color = cpair(colors.black, colors.ivory) }, + { name = "RTUs", color = cpair(colors.black, colors.ivory) }, + { name = "CRDs", color = cpair(colors.black, colors.ivory) }, + { name = "PKTs", color = cpair(colors.black, colors.ivory) }, + } + + TabBar{parent=panel,y=2,tabs=tabs,min_width=10,callback=page_pane.set_value,fg_bg=cpair(colors.black,colors.white)} +end + +return init diff --git a/supervisor/panel/style.lua b/supervisor/panel/style.lua new file mode 100644 index 0000000..31039d4 --- /dev/null +++ b/supervisor/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/supervisor/renderer.lua b/supervisor/renderer.lua new file mode 100644 index 0000000..ca49946 --- /dev/null +++ b/supervisor/renderer.lua @@ -0,0 +1,80 @@ +-- +-- Graphics Rendering Control +-- + +local panel_view = require("supervisor.panel.front_panel") +local style = require("supervisor.panel.style") + +local flasher = require("graphics.flasher") + +local DisplayBox = require("graphics.elements.displaybox") + +local renderer = {} + +local ui = { + display = nil +} + +-- start the UI +function renderer.start_ui() + 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 + + -- 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 + +-- close out the UI +function renderer.close_ui() + 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 +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/supervisor/session/coordinator.lua b/supervisor/session/coordinator.lua index b093d87..b68d815 100644 --- a/supervisor/session/coordinator.lua +++ b/supervisor/session/coordinator.lua @@ -18,7 +18,8 @@ local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local SV_Q_DATA = svqtypes.SV_Q_DATA -local println = util.println +-- local println = util.println +local println = function (str) end -- retry time constants in ms -- local INITIAL_WAIT = 1500 diff --git a/supervisor/session/plc.lua b/supervisor/session/plc.lua index cca8a26..8c61221 100644 --- a/supervisor/session/plc.lua +++ b/supervisor/session/plc.lua @@ -14,7 +14,8 @@ local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE local PLC_AUTO_ACK = comms.PLC_AUTO_ACK local UNIT_COMMAND = comms.UNIT_COMMAND -local println = util.println +-- local println = util.println +local println = function (str) end -- retry time constants in ms local INITIAL_WAIT = 1500 diff --git a/supervisor/session/pocket.lua b/supervisor/session/pocket.lua index 9cf0a5d..5693e02 100644 --- a/supervisor/session/pocket.lua +++ b/supervisor/session/pocket.lua @@ -8,7 +8,8 @@ local pocket = {} local PROTOCOL = comms.PROTOCOL local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE -local println = util.println +-- local println = util.println +local println = function (str) end -- retry time constants in ms -- local INITIAL_WAIT = 1500 diff --git a/supervisor/session/rtu.lua b/supervisor/session/rtu.lua index 96309a0..5d0e5c2 100644 --- a/supervisor/session/rtu.lua +++ b/supervisor/session/rtu.lua @@ -22,7 +22,8 @@ local PROTOCOL = comms.PROTOCOL local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE -local println = util.println +-- local println = util.println +local println = function (str) end local PERIODICS = { KEEP_ALIVE = 2000 diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index 8ad3366..93b35b9 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -22,6 +22,7 @@ local CRD_S_DATA = coordinator.CRD_S_DATA local svsessions = {} +---@enum SESSION_TYPE local SESSION_TYPE = { RTU_SESSION = 0, -- RTU gateway PLC_SESSION = 1, -- reactor PLC diff --git a/supervisor/startup.lua b/supervisor/startup.lua index bf27e2e..c104e1b 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -5,16 +5,21 @@ require("/initenv").init_env() local crash = require("scada-common.crash") +local comms = require("scada-common.comms") local log = require("scada-common.log") local ppm = require("scada-common.ppm") local util = require("scada-common.util") +local core = require("graphics.core") + local config = require("supervisor.config") +local databus = require("supervisor.databus") +local renderer = require("supervisor.renderer") local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.15.5" +local SUPERVISOR_VERSION = "v0.16.0" local println = util.println local println_ts = util.println_ts @@ -79,6 +84,9 @@ local function main() -- startup ---------------------------------------- + -- record firmware versions and ID + databus.tx_versions(SUPERVISOR_VERSION, comms.version) + -- mount connected devices ppm.mount_all() @@ -89,84 +97,113 @@ local function main() return end - -- 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_CTL_LISTEN, config.TRUSTED_RANGE) + databus.tx_hw_modem(true) - -- base loop clock (6.67Hz, 3 ticks) - local MAIN_CLOCK = 0.15 - local loop_clock = util.new_clock(MAIN_CLOCK) + -- start UI + local fp_ok, message = pcall(renderer.start_ui) - -- start clock - loop_clock.start() + if not fp_ok then + renderer.close_ui() + println_ts(util.c("UI error: ", message)) + log.error(util.c("GUI crashed with error ", message)) + else + -- 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_CTL_LISTEN, config.TRUSTED_RANGE) - -- event loop - while true do - local event, param1, param2, param3, param4, param5 = util.pull_event() + -- base loop clock (6.67Hz, 3 ticks) + local MAIN_CLOCK = 0.15 + local loop_clock = util.new_clock(MAIN_CLOCK) - -- handle event - if event == "peripheral_detach" then - local type, device = ppm.handle_unmount(param1) + -- start clock + loop_clock.start() - if type ~= nil and device ~= nil then - if type == "modem" then - -- we only care if this is our wireless modem - if device == modem then - println_ts("wireless modem disconnected!") - log.warning("comms modem disconnected") - else - log.warning("non-comms modem disconnected") + -- event loop + while true do + local event, param1, param2, param3, param4, param5 = util.pull_event() + + -- handle event + if event == "peripheral_detach" then + local type, device = ppm.handle_unmount(param1) + + if type ~= nil and device ~= nil then + if type == "modem" then + -- we only care if this is our wireless modem + if device == modem then + log.warning("comms modem disconnected") + databus.tx_hw_modem(false) + else + log.warning("non-comms modem disconnected") + end end end - end - elseif event == "peripheral" then - local type, device = ppm.mount(param1) + elseif event == "peripheral" then + local type, device = ppm.mount(param1) - if type ~= nil and device ~= nil then - if type == "modem" then - if device.isWireless() then - -- reconnected modem - modem = device - superv_comms.reconnect_modem(modem) + if type ~= nil and device ~= nil then + if type == "modem" then + if device.isWireless() then + -- reconnected modem + modem = device + superv_comms.reconnect_modem(modem) - println_ts("wireless modem reconnected.") - log.info("comms modem reconnected") - else - log.info("wired modem reconnected") + log.info("comms modem reconnected") + + databus.tx_hw_modem(true) + else + log.info("wired modem reconnected") + end end end + elseif event == "timer" and loop_clock.is_clock(param1) then + -- main loop tick + databus.heartbeat() + + -- iterate sessions + svsessions.iterate_all() + + -- free any closed sessions + svsessions.free_all_closed() + + loop_clock.start() + elseif event == "timer" then + -- a non-clock timer event, check watchdogs + svsessions.check_all_watchdogs(param1) + elseif event == "modem_message" then + -- got a packet + local packet = superv_comms.parse_packet(param1, param2, param3, param4, param5) + superv_comms.handle_packet(packet) + elseif event == "mouse_click" then + -- handle a monitor touch event + renderer.handle_mouse(core.events.touch(param1, param2, param3)) + log.debug(util.sprintf("mouse_click: %s [%d, %d]", param1, param2, param3)) + elseif event == "mouse_drag" then + log.debug(util.sprintf("mouse_drag: %s [%d, %d]", param1, param2, param3)) + elseif event == "mouse_scroll" then + log.debug(util.sprintf("mouse_scroll: %s [%d, %d]", param1, param2, param3)) + elseif event == "mouse_up" then + log.debug(util.sprintf("mouse_up: %s [%d, %d]", param1, param2, param3)) end - elseif event == "timer" and loop_clock.is_clock(param1) then - -- main loop tick - -- iterate sessions - svsessions.iterate_all() - - -- free any closed sessions - svsessions.free_all_closed() - - loop_clock.start() - elseif event == "timer" then - -- a non-clock timer event, check watchdogs - svsessions.check_all_watchdogs(param1) - elseif event == "modem_message" then - -- got a packet - local packet = superv_comms.parse_packet(param1, param2, param3, param4, param5) - superv_comms.handle_packet(packet) + -- check for termination request + if event == "terminate" or ppm.should_terminate() then + log.info("terminate requested, closing sessions...") + svsessions.close_all() + log.info("sessions closed") + break + end end - -- check for termination request - if event == "terminate" or ppm.should_terminate() then - println_ts("closing sessions...") - log.info("terminate requested, closing sessions...") - svsessions.close_all() - log.info("sessions closed") - break - end + renderer.close_ui() end println_ts("exited") 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/supervisor/supervisor.lua b/supervisor/supervisor.lua index 49cf482..076f0ac 100644 --- a/supervisor/supervisor.lua +++ b/supervisor/supervisor.lua @@ -11,7 +11,8 @@ local DEVICE_TYPE = comms.DEVICE_TYPE local ESTABLISH_ACK = comms.ESTABLISH_ACK local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE -local println = util.println +-- local println = util.println +local println = function (str) end -- supervisory controller communications ---@nodiscard From e26dc905f828bb63755ad535e80562b75de2a336 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Sun, 7 May 2023 01:27:36 +0000 Subject: [PATCH 04/49] #226 updated mouse events WIP --- coordinator/ui/components/boiler.lua | 4 +- coordinator/ui/components/imatrix.lua | 6 +-- coordinator/ui/components/processctl.lua | 6 +-- coordinator/ui/components/reactor.lua | 4 +- coordinator/ui/components/turbine.lua | 4 +- coordinator/ui/components/unit_detail.lua | 6 +-- coordinator/ui/components/unit_overview.lua | 4 +- coordinator/ui/layout/main_view.lua | 4 +- coordinator/ui/style.lua | 2 +- graphics/core.lua | 48 ++++++++++++-------- graphics/element.lua | 4 +- graphics/elements/controls/hazard_button.lua | 2 +- graphics/elements/controls/push_button.lua | 2 +- graphics/elements/indicators/coremap.lua | 2 +- graphics/elements/pipenet.lua | 4 +- graphics/elements/textbox.lua | 2 +- graphics/graphics.lua | 30 ++++++++++++ pocket/ui/components/boiler_page.lua | 4 +- pocket/ui/components/conn_waiting.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 | 4 +- pocket/ui/style.lua | 2 +- reactor-plc/panel/front_panel.lua | 6 +-- reactor-plc/panel/style.lua | 2 +- rtu/panel/front_panel.lua | 4 +- rtu/panel/style.lua | 2 +- 29 files changed, 109 insertions(+), 69 deletions(-) create mode 100644 graphics/graphics.lua diff --git a/coordinator/ui/components/boiler.lua b/coordinator/ui/components/boiler.lua index c4a433b..9ed497c 100644 --- a/coordinator/ui/components/boiler.lua +++ b/coordinator/ui/components/boiler.lua @@ -9,8 +9,8 @@ local DataIndicator = require("graphics.elements.indicators.data") local StateIndicator = require("graphics.elements.indicators.state") local VerticalBar = require("graphics.elements.indicators.vbar") -local cpair = core.graphics.cpair -local border = core.graphics.border +local cpair = core.cpair +local border = core.border -- new boiler view ---@param root graphics_element parent diff --git a/coordinator/ui/components/imatrix.lua b/coordinator/ui/components/imatrix.lua index 2910fbb..c94ff9f 100644 --- a/coordinator/ui/components/imatrix.lua +++ b/coordinator/ui/components/imatrix.lua @@ -13,10 +13,10 @@ local PowerIndicator = require("graphics.elements.indicators.power") local StateIndicator = require("graphics.elements.indicators.state") local VerticalBar = require("graphics.elements.indicators.vbar") -local cpair = core.graphics.cpair -local border = core.graphics.border +local cpair = core.cpair +local border = core.border -local TEXT_ALIGN = core.graphics.TEXT_ALIGN +local TEXT_ALIGN = core.TEXT_ALIGN -- new induction matrix view ---@param root graphics_element parent diff --git a/coordinator/ui/components/processctl.lua b/coordinator/ui/components/processctl.lua index 5b8d8ae..8719968 100644 --- a/coordinator/ui/components/processctl.lua +++ b/coordinator/ui/components/processctl.lua @@ -21,10 +21,10 @@ local HazardButton = require("graphics.elements.controls.hazard_button") local RadioButton = require("graphics.elements.controls.radio_button") local SpinboxNumeric = require("graphics.elements.controls.spinbox_numeric") -local TEXT_ALIGN = core.graphics.TEXT_ALIGN +local TEXT_ALIGN = core.TEXT_ALIGN -local cpair = core.graphics.cpair -local border = core.graphics.border +local cpair = core.cpair +local border = core.border local period = core.flasher.PERIOD diff --git a/coordinator/ui/components/reactor.lua b/coordinator/ui/components/reactor.lua index db75fb1..578bbba 100644 --- a/coordinator/ui/components/reactor.lua +++ b/coordinator/ui/components/reactor.lua @@ -11,8 +11,8 @@ local DataIndicator = require("graphics.elements.indicators.data") local HorizontalBar = require("graphics.elements.indicators.hbar") local StateIndicator = require("graphics.elements.indicators.state") -local cpair = core.graphics.cpair -local border = core.graphics.border +local cpair = core.cpair +local border = core.border -- create new reactor view ---@param root graphics_element parent diff --git a/coordinator/ui/components/turbine.lua b/coordinator/ui/components/turbine.lua index e4d6967..3bfd731 100644 --- a/coordinator/ui/components/turbine.lua +++ b/coordinator/ui/components/turbine.lua @@ -12,8 +12,8 @@ local PowerIndicator = require("graphics.elements.indicators.power") local StateIndicator = require("graphics.elements.indicators.state") local VerticalBar = require("graphics.elements.indicators.vbar") -local cpair = core.graphics.cpair -local border = core.graphics.border +local cpair = core.cpair +local border = core.border -- new turbine view ---@param root graphics_element parent diff --git a/coordinator/ui/components/unit_detail.lua b/coordinator/ui/components/unit_detail.lua index a29dd4b..7181430 100644 --- a/coordinator/ui/components/unit_detail.lua +++ b/coordinator/ui/components/unit_detail.lua @@ -26,10 +26,10 @@ local PushButton = require("graphics.elements.controls.push_button") local RadioButton = require("graphics.elements.controls.radio_button") local SpinboxNumeric = require("graphics.elements.controls.spinbox_numeric") -local TEXT_ALIGN = core.graphics.TEXT_ALIGN +local TEXT_ALIGN = core.TEXT_ALIGN -local cpair = core.graphics.cpair -local border = core.graphics.border +local cpair = core.cpair +local border = core.border local period = core.flasher.PERIOD diff --git a/coordinator/ui/components/unit_overview.lua b/coordinator/ui/components/unit_overview.lua index 24bc02e..bd341bf 100644 --- a/coordinator/ui/components/unit_overview.lua +++ b/coordinator/ui/components/unit_overview.lua @@ -14,9 +14,9 @@ local Div = require("graphics.elements.div") local PipeNetwork = require("graphics.elements.pipenet") local TextBox = require("graphics.elements.textbox") -local TEXT_ALIGN = core.graphics.TEXT_ALIGN +local TEXT_ALIGN = core.TEXT_ALIGN -local pipe = core.graphics.pipe +local pipe = core.pipe -- make a new unit overview window ---@param parent graphics_element parent diff --git a/coordinator/ui/layout/main_view.lua b/coordinator/ui/layout/main_view.lua index a7f8ae2..5510382 100644 --- a/coordinator/ui/layout/main_view.lua +++ b/coordinator/ui/layout/main_view.lua @@ -18,9 +18,9 @@ local TextBox = require("graphics.elements.textbox") local DataIndicator = require("graphics.elements.indicators.data") -local TEXT_ALIGN = core.graphics.TEXT_ALIGN +local TEXT_ALIGN = core.TEXT_ALIGN -local cpair = core.graphics.cpair +local cpair = core.cpair -- create new main view ---@param main graphics_element main displaybox diff --git a/coordinator/ui/style.lua b/coordinator/ui/style.lua index 74923f2..b78fc91 100644 --- a/coordinator/ui/style.lua +++ b/coordinator/ui/style.lua @@ -6,7 +6,7 @@ local core = require("graphics.core") local style = {} -local cpair = core.graphics.cpair +local cpair = core.cpair -- GLOBAL -- diff --git a/graphics/core.lua b/graphics/core.lua index d03e551..1ef315f 100644 --- a/graphics/core.lua +++ b/graphics/core.lua @@ -1,26 +1,33 @@ -- --- Graphics Core Functions and Objects +-- Graphics Core Types, Checks, and Constructors -- local core = {} -local flasher = require("graphics.flasher") - -core.flasher = flasher +-- Core Events local events = {} ----@enum click_type -events.click_type = { +---@enum click_button +events.click_button = { VIRTUAL = 0, LEFT_BUTTON = 1, RIGHT_BUTTON = 2, MID_BUTTON = 3 } +---@enum click_type +events.click_type = { + TAP = 0, + DOWN = 1, + DRAG = 2, + UP = 3 +} + ---@class mouse_interaction ---@field monitor string ----@field button integer +---@field button click_button +---@field type click_type ---@field x integer ---@field y integer @@ -33,7 +40,8 @@ events.click_type = { function events.touch(monitor, x, y) return { monitor = monitor, - button = events.click_type.LEFT_BUTTON, + button = events.click_button.LEFT_BUTTON, + type = events.click_type.TAP, x = x, y = y } @@ -41,7 +49,7 @@ end -- create a new mouse click mouse interaction event ---@nodiscard ----@param button click_type +---@param button click_button ---@param x integer ---@param y integer ---@return mouse_interaction @@ -49,6 +57,7 @@ function events.click(button, x, y) return { monitor = "terminal", button = button, + type = events.click_type.UP, x = x, y = y } @@ -64,6 +73,7 @@ function events.mouse_transposed(event, new_x, new_y) return { monitor = event.monitor, button = event.button, + type = event.type, x = new_x, y = new_y } @@ -72,14 +82,16 @@ end -- create a new generic mouse interaction event ---@nodiscard ---@param monitor string ----@param button click_type +---@param button click_button +---@param type click_type ---@param x integer ---@param y integer ---@return mouse_interaction -function events.mouse_generic(monitor, button, x, y) +function events.mouse_generic(monitor, button, type, x, y) return { monitor = monitor, button = button, + type = type, x = x, y = y } @@ -87,10 +99,10 @@ end core.events = events -local graphics = {} +-- Core Types ---@enum TEXT_ALIGN -graphics.TEXT_ALIGN = { +core.TEXT_ALIGN = { LEFT = 1, CENTER = 2, RIGHT = 3 @@ -109,7 +121,7 @@ graphics.TEXT_ALIGN = { ---@param color color border color ---@param even? boolean whether to pad width extra to account for rectangular pixels, defaults to false ---@return graphics_border -function graphics.border(width, color, even) +function core.border(width, color, even) return { width = width, color = color, @@ -130,7 +142,7 @@ end ---@param w integer ---@param h integer ---@return graphics_frame -function graphics.gframe(x, y, w, h) +function core.gframe(x, y, w, h) return { x = x, y = y, @@ -154,7 +166,7 @@ end ---@param a color ---@param b color ---@return cpair -function graphics.cpair(a, b) +function core.cpair(a, b) return { -- color pairs color_a = a, @@ -191,7 +203,7 @@ end ---@param thin? boolean true for 1 subpixel, false (default) for 2 ---@param align_tr? boolean false to align bottom left (default), true to align top right ---@return pipe -function graphics.pipe(x1, y1, x2, y2, color, thin, align_tr) +function core.pipe(x1, y1, x2, y2, color, thin, align_tr) return { x1 = x1, y1 = y1, @@ -205,6 +217,4 @@ function graphics.pipe(x1, y1, x2, y2, color, thin, align_tr) } end -core.graphics = graphics - return core diff --git a/graphics/element.lua b/graphics/element.lua index 04d4fd2..13baec3 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -73,8 +73,8 @@ function element.new(args) enabled = true, value = nil, ---@type any window = nil, ---@type table - fg_bg = core.graphics.cpair(colors.white, colors.black), - frame = core.graphics.gframe(1, 1, 1, 1) + fg_bg = core.cpair(colors.white, colors.black), + frame = core.gframe(1, 1, 1, 1) } -- element as string diff --git a/graphics/elements/controls/hazard_button.lua b/graphics/elements/controls/hazard_button.lua index 2b9baa6..d8e2d6d 100644 --- a/graphics/elements/controls/hazard_button.lua +++ b/graphics/elements/controls/hazard_button.lua @@ -176,7 +176,7 @@ local function hazard_button(args) -- set the value (true simulates pressing the button) ---@param val boolean new value function e.set_value(val) - if val then e.handle_mouse(core.events.mouse_generic("", core.events.click_type.VIRTUAL, 1, 1)) end + if val then e.handle_mouse(core.events.mouse_generic("", core.events.click_button.VIRTUAL, core.events.click_type.UP, 1, 1)) end end -- show the button as disabled diff --git a/graphics/elements/controls/push_button.lua b/graphics/elements/controls/push_button.lua index 9b5f971..79cde7f 100644 --- a/graphics/elements/controls/push_button.lua +++ b/graphics/elements/controls/push_button.lua @@ -76,7 +76,7 @@ local function push_button(args) -- set the value (true simulates pressing the button) ---@param val boolean new value function e.set_value(val) - if val then e.handle_mouse(core.events.mouse_generic("", core.events.click_type.VIRTUAL, 1, 1)) end + if val then e.handle_mouse(core.events.mouse_generic("", core.events.click_button.VIRTUAL, core.events.click_type.UP, 1, 1)) end end -- show butten as enabled diff --git a/graphics/elements/indicators/coremap.lua b/graphics/elements/indicators/coremap.lua index 323e17c..05434a3 100644 --- a/graphics/elements/indicators/coremap.lua +++ b/graphics/elements/indicators/coremap.lua @@ -26,7 +26,7 @@ local function core_map(args) args.height = 18 -- inherit only foreground color - args.fg_bg = core.graphics.cpair(args.parent.get_fg_bg().fgd, colors.gray) + args.fg_bg = core.cpair(args.parent.get_fg_bg().fgd, colors.gray) -- create new graphics element base object local e = element.new(args) diff --git a/graphics/elements/pipenet.lua b/graphics/elements/pipenet.lua index 71ee9fd..8a1d29b 100644 --- a/graphics/elements/pipenet.lua +++ b/graphics/elements/pipenet.lua @@ -37,7 +37,7 @@ local function pipenet(args) args.y = args.y or 1 if args.bg ~= nil then - args.fg_bg = core.graphics.cpair(args.bg, args.bg) + args.fg_bg = core.cpair(args.bg, args.bg) end -- create new graphics element base object @@ -55,7 +55,7 @@ local function pipenet(args) e.window.setCursorPos(x, y) - local c = core.graphics.cpair(pipe.color, e.fg_bg.bkg) + local c = core.cpair(pipe.color, e.fg_bg.bkg) if pipe.align_tr then -- cross width then height diff --git a/graphics/elements/textbox.lua b/graphics/elements/textbox.lua index c911677..9066deb 100644 --- a/graphics/elements/textbox.lua +++ b/graphics/elements/textbox.lua @@ -5,7 +5,7 @@ local util = require("scada-common.util") local core = require("graphics.core") local element = require("graphics.element") -local TEXT_ALIGN = core.graphics.TEXT_ALIGN +local TEXT_ALIGN = core.TEXT_ALIGN ---@class textbox_args ---@field text string text to show diff --git a/graphics/graphics.lua b/graphics/graphics.lua new file mode 100644 index 0000000..11b04ff --- /dev/null +++ b/graphics/graphics.lua @@ -0,0 +1,30 @@ + + +local flasher = require("graphics.flasher") +local core = require("graphics.core") + +local graphics = {} + +graphics.flasher = flasher + +-- pass mouse events to graphics engine +-- supports: mouse_click, mouse_up, mouse_drag, mouse_scroll, and monitor_touch +---@param event_type os_event +function graphics.handle_mouse(event_type) + if event_type == "mouse_click" then + elseif event_type == "mouse_up" or event_type == "monitor_touch" then + elseif event_type == "mouse_drag" then + elseif event_type == "mouse_scroll" then + end +end + +-- pass char, key, or key_up event to graphics engine +---@param event_type os_event +function graphics.handle_key(event_type) + if event_type == "char" then + elseif event_type == "key" then + elseif event_type == "key_up" then + end +end + +return graphics diff --git a/pocket/ui/components/boiler_page.lua b/pocket/ui/components/boiler_page.lua index fd0eca1..ec13d59 100644 --- a/pocket/ui/components/boiler_page.lua +++ b/pocket/ui/components/boiler_page.lua @@ -5,9 +5,9 @@ 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.cpair -local TEXT_ALIGN = core.graphics.TEXT_ALIGN +local TEXT_ALIGN = core.TEXT_ALIGN -- new boiler page view ---@param root graphics_element parent diff --git a/pocket/ui/components/conn_waiting.lua b/pocket/ui/components/conn_waiting.lua index cd08652..9bbbfc0 100644 --- a/pocket/ui/components/conn_waiting.lua +++ b/pocket/ui/components/conn_waiting.lua @@ -11,9 +11,9 @@ local TextBox = require("graphics.elements.textbox") local WaitingAnim = require("graphics.elements.animations.waiting") -local TEXT_ALIGN = core.graphics.TEXT_ALIGN +local TEXT_ALIGN = core.TEXT_ALIGN -local cpair = core.graphics.cpair +local cpair = core.cpair -- create a waiting view ---@param parent graphics_element parent diff --git a/pocket/ui/components/home_page.lua b/pocket/ui/components/home_page.lua index 5287cac..a31cae8 100644 --- a/pocket/ui/components/home_page.lua +++ b/pocket/ui/components/home_page.lua @@ -5,9 +5,9 @@ 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.cpair -local TEXT_ALIGN = core.graphics.TEXT_ALIGN +local TEXT_ALIGN = core.TEXT_ALIGN -- new home page view ---@param root graphics_element parent diff --git a/pocket/ui/components/reactor_page.lua b/pocket/ui/components/reactor_page.lua index 50b1939..c7a2e96 100644 --- a/pocket/ui/components/reactor_page.lua +++ b/pocket/ui/components/reactor_page.lua @@ -5,9 +5,9 @@ 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.cpair -local TEXT_ALIGN = core.graphics.TEXT_ALIGN +local TEXT_ALIGN = core.TEXT_ALIGN -- new reactor page view ---@param root graphics_element parent diff --git a/pocket/ui/components/turbine_page.lua b/pocket/ui/components/turbine_page.lua index 9fd7af5..527e419 100644 --- a/pocket/ui/components/turbine_page.lua +++ b/pocket/ui/components/turbine_page.lua @@ -5,9 +5,9 @@ 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.cpair -local TEXT_ALIGN = core.graphics.TEXT_ALIGN +local TEXT_ALIGN = core.TEXT_ALIGN -- new turbine page view ---@param root graphics_element parent diff --git a/pocket/ui/components/unit_page.lua b/pocket/ui/components/unit_page.lua index 2e24df3..a0718e6 100644 --- a/pocket/ui/components/unit_page.lua +++ b/pocket/ui/components/unit_page.lua @@ -5,9 +5,9 @@ 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.cpair -local TEXT_ALIGN = core.graphics.TEXT_ALIGN +local TEXT_ALIGN = core.TEXT_ALIGN -- new unit page view ---@param root graphics_element parent diff --git a/pocket/ui/main.lua b/pocket/ui/main.lua index 5af9ce8..1b7be88 100644 --- a/pocket/ui/main.lua +++ b/pocket/ui/main.lua @@ -22,9 +22,9 @@ local TextBox = require("graphics.elements.textbox") local Sidebar = require("graphics.elements.controls.sidebar") -local TEXT_ALIGN = core.graphics.TEXT_ALIGN +local TEXT_ALIGN = core.TEXT_ALIGN -local cpair = core.graphics.cpair +local cpair = core.cpair -- create new main view ---@param main graphics_element main displaybox diff --git a/pocket/ui/style.lua b/pocket/ui/style.lua index b9a09fc..2fb7526 100644 --- a/pocket/ui/style.lua +++ b/pocket/ui/style.lua @@ -6,7 +6,7 @@ local core = require("graphics.core") local style = {} -local cpair = core.graphics.cpair +local cpair = core.cpair -- GLOBAL -- diff --git a/reactor-plc/panel/front_panel.lua b/reactor-plc/panel/front_panel.lua index 70c80ef..c000a3d 100644 --- a/reactor-plc/panel/front_panel.lua +++ b/reactor-plc/panel/front_panel.lua @@ -22,10 +22,10 @@ local LED = require("graphics.elements.indicators.led") local LEDPair = require("graphics.elements.indicators.ledpair") local RGBLED = require("graphics.elements.indicators.ledrgb") -local TEXT_ALIGN = core.graphics.TEXT_ALIGN +local TEXT_ALIGN = core.TEXT_ALIGN -local cpair = core.graphics.cpair -local border = core.graphics.border +local cpair = core.cpair +local border = core.border -- create new main view ---@param panel graphics_element main displaybox diff --git a/reactor-plc/panel/style.lua b/reactor-plc/panel/style.lua index 31039d4..996453c 100644 --- a/reactor-plc/panel/style.lua +++ b/reactor-plc/panel/style.lua @@ -6,7 +6,7 @@ local core = require("graphics.core") local style = {} -local cpair = core.graphics.cpair +local cpair = core.cpair -- GLOBAL -- diff --git a/rtu/panel/front_panel.lua b/rtu/panel/front_panel.lua index f6014da..8dcaa1f 100644 --- a/rtu/panel/front_panel.lua +++ b/rtu/panel/front_panel.lua @@ -16,9 +16,9 @@ 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 TEXT_ALIGN = core.TEXT_ALIGN -local cpair = core.graphics.cpair +local cpair = core.cpair local UNIT_TYPE_LABELS = { "UNKNOWN", diff --git a/rtu/panel/style.lua b/rtu/panel/style.lua index 31039d4..996453c 100644 --- a/rtu/panel/style.lua +++ b/rtu/panel/style.lua @@ -6,7 +6,7 @@ local core = require("graphics.core") local style = {} -local cpair = core.graphics.cpair +local cpair = core.cpair -- GLOBAL -- From b8a8da1ac4d1969d11a2c487199db74f64c50e46 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Tue, 9 May 2023 20:29:07 -0400 Subject: [PATCH 05/49] #226 graphics core changes for mouse events --- graphics/core.lua | 97 ++------------------------ graphics/element.lua | 44 +++++++----- graphics/events.lua | 152 +++++++++++++++++++++++++++++++++++++++++ graphics/graphics.lua | 30 -------- scada-common/types.lua | 4 ++ 5 files changed, 188 insertions(+), 139 deletions(-) create mode 100644 graphics/events.lua delete mode 100644 graphics/graphics.lua diff --git a/graphics/core.lua b/graphics/core.lua index 1ef315f..58b6b8c 100644 --- a/graphics/core.lua +++ b/graphics/core.lua @@ -2,101 +2,12 @@ -- Graphics Core Types, Checks, and Constructors -- +local events = require("graphics.events") +local flasher = require("graphics.flasher") + local core = {} --- Core Events - -local events = {} - ----@enum click_button -events.click_button = { - VIRTUAL = 0, - LEFT_BUTTON = 1, - RIGHT_BUTTON = 2, - MID_BUTTON = 3 -} - ----@enum click_type -events.click_type = { - TAP = 0, - DOWN = 1, - DRAG = 2, - UP = 3 -} - ----@class mouse_interaction ----@field monitor string ----@field button click_button ----@field type click_type ----@field x integer ----@field y integer - --- create a new monitor touch mouse interaction event ----@nodiscard ----@param monitor string ----@param x integer ----@param y integer ----@return mouse_interaction -function events.touch(monitor, x, y) - return { - monitor = monitor, - button = events.click_button.LEFT_BUTTON, - type = events.click_type.TAP, - x = x, - y = y - } -end - --- create a new mouse click mouse interaction event ----@nodiscard ----@param button click_button ----@param x integer ----@param y integer ----@return mouse_interaction -function events.click(button, x, y) - return { - monitor = "terminal", - button = button, - type = events.click_type.UP, - x = x, - y = y - } -end - --- create a new transposed mouse interaction event using the event's monitor/button fields ----@nodiscard ----@param event mouse_interaction ----@param new_x integer ----@param new_y integer ----@return mouse_interaction -function events.mouse_transposed(event, new_x, new_y) - return { - monitor = event.monitor, - button = event.button, - type = event.type, - x = new_x, - y = new_y - } -end - --- create a new generic mouse interaction event ----@nodiscard ----@param monitor string ----@param button click_button ----@param type click_type ----@param x integer ----@param y integer ----@return mouse_interaction -function events.mouse_generic(monitor, button, type, x, y) - return { - monitor = monitor, - button = button, - type = type, - x = x, - y = y - } -end - +core.flasher = flasher core.events = events -- Core Types diff --git a/graphics/element.lua b/graphics/element.lua index 13baec3..2f8dabd 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -59,10 +59,10 @@ function element.new(args) id = -1, elem_type = debug.getinfo(2).name, define_completed = false, - p_window = nil, ---@type table - position = { x = 1, y = 1 }, + p_window = nil, ---@type table + position = { x = 1, y = 1 }, ---@type coordinate_2d child_offset = { x = 0, y = 0 }, - bounds = { x1 = 1, y1 = 1, x2 = 1, y2 = 1}, + bounds = { x1 = 1, y1 = 1, x2 = 1, y2 = 1 }, ---@class element_bounds next_y = 1, children = {}, mt = {} @@ -77,11 +77,22 @@ function element.new(args) frame = core.gframe(1, 1, 1, 1) } + local name_brief = "graphics.element{" .. self.elem_type .. "}: " + -- element as string function self.mt.__tostring() return "graphics.element{" .. self.elem_type .. "} @ " .. tostring(self) end + -- check if a coordinate is within the bounds of this element + ---@param x integer + ---@param y integer + local function _in_bounds(x, y) + local in_x = x >= self.bounds.x1 and x <= self.bounds.x2 + local in_y = y >= self.bounds.y1 and y <= self.bounds.y2 + return in_x and in_y + end + ---@class graphics_element local public = {} @@ -138,10 +149,10 @@ function element.new(args) end -- check frame - assert(f.x >= 1, "graphics.element{" .. self.elem_type .. "}: frame x not >= 1") - assert(f.y >= 1, "graphics.element{" .. self.elem_type .. "}: frame y not >= 1") - assert(f.w >= 1, "graphics.element{" .. self.elem_type .. "}: frame width not >= 1") - assert(f.h >= 1, "graphics.element{" .. self.elem_type .. "}: frame height not >= 1") + assert(f.x >= 1, name_brief .. "frame x not >= 1") + assert(f.y >= 1, name_brief .. "frame y not >= 1") + assert(f.w >= 1, name_brief .. "frame width not >= 1") + assert(f.h >= 1, name_brief .. "frame height not >= 1") -- create window protected.window = window.create(self.p_window, f.x, f.y, f.w, f.h, true) @@ -252,7 +263,7 @@ function element.new(args) end -- check window - assert(self.p_window, "graphics.element{" .. self.elem_type .. "}: no parent window provided") + assert(self.p_window, name_brief .. "no parent window provided") -- prepare the template if args.parent == nil then @@ -421,17 +432,18 @@ function element.new(args) -- handle a monitor touch or mouse click ---@param event mouse_interaction mouse interaction event function public.handle_mouse(event) - local in_x = event.x >= self.bounds.x1 and event.x <= self.bounds.x2 - local in_y = event.y >= self.bounds.y1 and event.y <= self.bounds.y2 + local x_ini, y_ini, x_cur, y_cur = event.initial.x, event.initial.y, event.current.x, event.current.y - if in_x and in_y then - local event_T = core.events.mouse_transposed(event, (event.x - self.position.x) + 1, (event.y - self.position.y) + 1) + local ini_in = _in_bounds(x_ini, y_ini) + local cur_in = _in_bounds(x_cur, y_cur) - -- handle the touch event, transformed into the window frame + if ini_in then + local event_T = core.events.mouse_transposed(event, self.position.x, self.position.y) + if not cur_in then event_T.type = core.events.CLICK_TYPE.EXITED end + + -- handle the mouse event then pass to children protected.handle_mouse(event_T) - - -- pass on touch event to children - for _, val in pairs(self.children) do val.handle_mouse(event_T) end + for _, child in pairs(self.children) do child.handle_mouse(event_T) end end end diff --git a/graphics/events.lua b/graphics/events.lua new file mode 100644 index 0000000..1b5219c --- /dev/null +++ b/graphics/events.lua @@ -0,0 +1,152 @@ +-- +-- Graphics Events and Event Handlers +-- + +local util = require("scada-common.util") + +local events = {} + +---@enum CLICK_BUTTON +events.CLICK_BUTTON = { + GENERIC = 0, + LEFT_BUTTON = 1, + RIGHT_BUTTON = 2, + MID_BUTTON = 3 +} + +---@enum CLICK_TYPE +events.CLICK_TYPE = { + TAP = 1, -- screen tap (complete click) + DOWN = 2, -- button down + UP = 3, -- button up (completed a click) + DRAG = 4, -- mouse dragged + SCROLL_DOWN = 5, -- scroll down + SCROLL_UP = 6, -- scroll up + EXITED = 7 -- cursor exited bounds of element +} + +---@class mouse_interaction +---@field monitor string +---@field button CLICK_BUTTON +---@field type CLICK_TYPE +---@field initial coordinate_2d +---@field current coordinate_2d + +local handler = { + button_down = { { 0, 0 }, { 0, 0 }, { 0, 0 } } -- left, right, middle button down tracking +} + +-- create a new 2D coordinate +---@param x integer +---@param y integer +---@return coordinate_2d +local function _coord2d(x, y) return { x = x, y = y } end + +-- create a new monitor touch mouse interaction event +---@nodiscard +---@param monitor string +---@param x integer +---@param y integer +---@return mouse_interaction +local function _monitor_touch(monitor, x, y) + return { + monitor = monitor, + button = events.CLICK_BUTTON.GENERIC, + type = events.CLICK_TYPE.TAP, + initial = _coord2d(x, y), + current = _coord2d(x, y) + } +end + +-- create a new mouse button mouse interaction event +---@nodiscard +---@param button CLICK_BUTTON mouse button +---@param type CLICK_TYPE click type +---@param x1 integer initial x +---@param y1 integer initial y +---@param x2 integer current x +---@param y2 integer current y +---@return mouse_interaction +local function _mouse_event(button, type, x1, y1, x2, y2) + return { + monitor = "terminal", + button = button, + type = type, + initial = _coord2d(x1, y1), + current = _coord2d(x2, y2) + } +end + +-- create a new generic mouse interaction event +---@nodiscard +---@param type CLICK_TYPE +---@param x integer +---@param y integer +---@return mouse_interaction +function events.mouse_generic(type, x, y) + return { + monitor = "", + button = events.CLICK_BUTTON.GENERIC, + type = type, + initial = _coord2d(x, y), + current = _coord2d(x, y) + } +end + +-- create a new transposed mouse interaction event using the event's monitor/button fields +---@nodiscard +---@param event mouse_interaction +---@param elem_pos_x integer element's x position: new x = (event x - element x) + 1 +---@param elem_pos_y integer element's y position: new y = (event y - element y) + 1 +---@return mouse_interaction +function events.mouse_transposed(event, elem_pos_x, elem_pos_y) + return { + monitor = event.monitor, + button = event.button, + type = event.type, + initial = _coord2d((event.initial.x - elem_pos_x) + 1, (event.initial.y - elem_pos_y) + 1), + current = _coord2d((event.current.x - elem_pos_x) + 1, (event.current.y - elem_pos_y) + 1) + } +end + +-- create a new mouse event to pass onto graphics renderer
+-- supports: mouse_click, mouse_up, mouse_drag, mouse_scroll, and monitor_touch +---@param event_type os_event OS event to handle +---@param opt integer|string button, scroll direction, or monitor for monitor touch +---@param x integer x coordinate +---@param y integer y coordinate +---@return mouse_interaction|nil +function events.new_mouse_event(event_type, opt, x, y) + if event_type == "mouse_click" then + ---@cast opt 1|2|3 + handler.button_down[opt] = { x, y } + return _mouse_event(opt, events.CLICK_TYPE.DOWN, x, y, x, y) + elseif event_type == "mouse_up" then + ---@cast opt 1|2|3 + local initial = handler.button_down[opt] ---@type coordinate_2d + return _mouse_event(opt, events.CLICK_TYPE.UP, initial.x, initial.y, x, y) + elseif event_type == "monitor_touch" then + ---@cast opt string + return _monitor_touch(opt, x, y) + elseif event_type == "mouse_drag" then + ---@cast opt 1|2|3 + local initial = handler.button_down[opt] ---@type coordinate_2d + return _mouse_event(opt, events.CLICK_TYPE.DRAG, initial.x, initial.y, x, y) + elseif event_type == "mouse_scroll" then + ---@cast opt 1|-1 + local scroll_direction = util.trinary(opt == 1, events.CLICK_TYPE.SCROLL_DOWN, events.CLICK_TYPE.SCROLL_UP) + return _mouse_event(events.CLICK_BUTTON.GENERIC, scroll_direction, x, y, x, y) + end +end + +-- create a new key event to pass onto graphics renderer
+-- supports: char, key, and key_up +---@param event_type os_event +function events.new_key_event(event_type) + if event_type == "char" then + elseif event_type == "key" then + elseif event_type == "key_up" then + end +end + +return events diff --git a/graphics/graphics.lua b/graphics/graphics.lua deleted file mode 100644 index 11b04ff..0000000 --- a/graphics/graphics.lua +++ /dev/null @@ -1,30 +0,0 @@ - - -local flasher = require("graphics.flasher") -local core = require("graphics.core") - -local graphics = {} - -graphics.flasher = flasher - --- pass mouse events to graphics engine --- supports: mouse_click, mouse_up, mouse_drag, mouse_scroll, and monitor_touch ----@param event_type os_event -function graphics.handle_mouse(event_type) - if event_type == "mouse_click" then - elseif event_type == "mouse_up" or event_type == "monitor_touch" then - elseif event_type == "mouse_drag" then - elseif event_type == "mouse_scroll" then - end -end - --- pass char, key, or key_up event to graphics engine ----@param event_type os_event -function graphics.handle_key(event_type) - if event_type == "char" then - elseif event_type == "key" then - elseif event_type == "key_up" then - end -end - -return graphics diff --git a/scada-common/types.lua b/scada-common/types.lua index 9beb1e6..8df01c1 100644 --- a/scada-common/types.lua +++ b/scada-common/types.lua @@ -39,6 +39,10 @@ function types.new_radiation_reading(r, u) return { radiation = r, unit = u } en ---@return radiation_reading function types.new_zero_radiation_reading() return { radiation = 0, unit = "nSv" } end +---@class coordinate_2d +---@field x integer +---@field y integer + ---@class coordinate ---@field x integer ---@field y integer From 40fa0de7a3ad2474c46ebd1d8fdb23145974d982 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 10 May 2023 10:56:56 -0400 Subject: [PATCH 06/49] #226 hazard and push buttons updated for new graphics mouse events --- graphics/elements/controls/hazard_button.lua | 40 +++++++------- graphics/elements/controls/push_button.lua | 56 +++++++++++++------- 2 files changed, 56 insertions(+), 40 deletions(-) diff --git a/graphics/elements/controls/hazard_button.lua b/graphics/elements/controls/hazard_button.lua index d8e2d6d..19047cb 100644 --- a/graphics/elements/controls/hazard_button.lua +++ b/graphics/elements/controls/hazard_button.lua @@ -6,6 +6,8 @@ local util = require("scada-common.util") local core = require("graphics.core") local element = require("graphics.element") +local CLICK_TYPE = core.events.CLICK_TYPE + ---@class hazard_button_args ---@field text string text to show on button ---@field accent color accent color for hazard border @@ -141,23 +143,26 @@ local function hazard_button(args) end -- handle mouse interaction - function e.handle_mouse(_) + ---@param event mouse_interaction + function e.handle_mouse(event) if e.enabled then - -- change text color to indicate clicked - e.window.setTextColor(args.accent) - e.window.setCursorPos(3, 2) - e.window.write(args.text) + if event.type == CLICK_TYPE.TAP or event.type == CLICK_TYPE.UP then + -- change text color to indicate clicked + e.window.setTextColor(args.accent) + e.window.setCursorPos(3, 2) + e.window.write(args.text) - -- abort any other callbacks - tcd.abort(on_timeout) - tcd.abort(on_success) - tcd.abort(on_failure) + -- abort any other callbacks + tcd.abort(on_timeout) + tcd.abort(on_success) + tcd.abort(on_failure) - -- 1.5 second timeout - tcd.dispatch(1.5, on_timeout) + -- 1.5 second timeout + tcd.dispatch(1.5, on_timeout) - -- call the touch callback - args.callback() + -- call the touch callback + args.callback() + end end end @@ -165,18 +170,13 @@ local function hazard_button(args) ---@param result boolean true for success, false for failure function e.response_callback(result) tcd.abort(on_timeout) - - if result then - on_success() - else - on_failure(0) - end + if result then on_success() else on_failure(0) end end -- set the value (true simulates pressing the button) ---@param val boolean new value function e.set_value(val) - if val then e.handle_mouse(core.events.mouse_generic("", core.events.click_button.VIRTUAL, core.events.click_type.UP, 1, 1)) end + if val then e.handle_mouse(core.events.mouse_generic(core.events.CLICK_TYPE.UP, 1, 1)) end end -- show the button as disabled diff --git a/graphics/elements/controls/push_button.lua b/graphics/elements/controls/push_button.lua index 79cde7f..a55a4e4 100644 --- a/graphics/elements/controls/push_button.lua +++ b/graphics/elements/controls/push_button.lua @@ -5,6 +5,8 @@ local tcd = require("scada-common.tcallbackdsp") local core = require("graphics.core") local element = require("graphics.element") +local CLICK_TYPE = core.events.CLICK_TYPE + ---@class push_button_args ---@field text string button text ---@field callback function function to call on touch @@ -47,36 +49,50 @@ local function push_button(args) e.window.write(args.text) end + -- draw the button as pressed (if active_fg_bg set) + local function show_pressed() + if e.enabled and args.active_fg_bg ~= nil then + e.value = true + e.window.setTextColor(args.active_fg_bg.fgd) + e.window.setBackgroundColor(args.active_fg_bg.bkg) + draw() + end + end + + -- draw the button as unpressed (if active_fg_bg set) + local function show_unpressed() + if e.enabled and args.active_fg_bg ~= nil then + e.value = false + e.window.setTextColor(e.fg_bg.fgd) + e.window.setBackgroundColor(e.fg_bg.bkg) + draw() + end + end + -- handle mouse interaction - function e.handle_mouse(_) + ---@param event mouse_interaction + function e.handle_mouse(event) if e.enabled then - if args.active_fg_bg ~= nil then - -- show as pressed - e.value = true - e.window.setTextColor(args.active_fg_bg.fgd) - e.window.setBackgroundColor(args.active_fg_bg.bkg) - draw() - + if event.type == CLICK_TYPE.TAP then + show_pressed() -- show as unpressed in 0.25 seconds - tcd.dispatch(0.25, function () - e.value = false - if e.enabled then - e.window.setTextColor(e.fg_bg.fgd) - e.window.setBackgroundColor(e.fg_bg.bkg) - end - draw() - end) + if args.active_fg_bg ~= nil then tcd.dispatch(0.25, show_unpressed) end + args.callback() + elseif event.type == CLICK_TYPE.DOWN then + show_pressed() + elseif event.type == CLICK_TYPE.UP then + show_unpressed() + args.callback() + elseif event.type == CLICK_TYPE.EXITED then + show_unpressed() end - - -- call the touch callback - args.callback() end end -- set the value (true simulates pressing the button) ---@param val boolean new value function e.set_value(val) - if val then e.handle_mouse(core.events.mouse_generic("", core.events.click_button.VIRTUAL, core.events.click_type.UP, 1, 1)) end + if val then e.handle_mouse(core.events.mouse_generic(core.events.CLICK_TYPE.UP, 1, 1)) end end -- show butten as enabled From 4ef1915137503a04f443842f9eeaf03ee5e4630a Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 10 May 2023 11:08:24 -0400 Subject: [PATCH 07/49] #226 multi button updated for new graphics mouse events --- graphics/elements/controls/hazard_button.lua | 4 +-- graphics/elements/controls/multi_button.lua | 36 +++++++++++++------- graphics/events.lua | 5 +++ 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/graphics/elements/controls/hazard_button.lua b/graphics/elements/controls/hazard_button.lua index 19047cb..3db6a3b 100644 --- a/graphics/elements/controls/hazard_button.lua +++ b/graphics/elements/controls/hazard_button.lua @@ -6,8 +6,6 @@ local util = require("scada-common.util") local core = require("graphics.core") local element = require("graphics.element") -local CLICK_TYPE = core.events.CLICK_TYPE - ---@class hazard_button_args ---@field text string text to show on button ---@field accent color accent color for hazard border @@ -146,7 +144,7 @@ local function hazard_button(args) ---@param event mouse_interaction function e.handle_mouse(event) if e.enabled then - if event.type == CLICK_TYPE.TAP or event.type == CLICK_TYPE.UP then + if core.events.was_clicked(event.type) then -- change text color to indicate clicked e.window.setTextColor(args.accent) e.window.setCursorPos(3, 2) diff --git a/graphics/elements/controls/multi_button.lua b/graphics/elements/controls/multi_button.lua index 2549e2b..fa177f4 100644 --- a/graphics/elements/controls/multi_button.lua +++ b/graphics/elements/controls/multi_button.lua @@ -2,13 +2,13 @@ local util = require("scada-common.util") +local core = require("graphics.core") local element = require("graphics.element") ---@class button_option ---@field text string ---@field fg_bg cpair ---@field active_fg_bg cpair ----@field _lpad integer automatically calculated left pad ---@field _start_x integer starting touch x range (inclusive) ---@field _end_x integer ending touch x range (inclusive) @@ -62,9 +62,7 @@ local function multi_button(args) local next_x = 2 for i = 1, #args.options do local opt = args.options[i] ---@type button_option - local w = string.len(opt.text) - opt._lpad = math.floor((e.frame.w - w) / 2) opt._start_x = next_x opt._end_x = next_x + button_width - 1 @@ -92,20 +90,32 @@ local function multi_button(args) end end + -- check which button a given x is within + ---@return integer|nil button index or nil if not within a button + local function which_button(x) + for i = 1, #args.options do + local opt = args.options[i] ---@type button_option + if x >= opt._start_x and x <= opt._end_x then return i end + end + + return nil + end + -- handle mouse interaction ---@param event mouse_interaction mouse event ----@diagnostic disable-next-line: unused-local function e.handle_mouse(event) - -- determine what was pressed - if e.enabled and event.y == 1 then - for i = 1, #args.options do - local opt = args.options[i] ---@type button_option + -- if enabled and the button row was pressed... + if e.enabled and core.events.was_clicked(event.type) and (event.initial.y == 1) and (event.current.y == 1) then + -- a button may have been pressed, which one was it? + local button_ini = which_button(event.initial.x) + local button_cur = which_button(event.current.x) - if event.x >= opt._start_x and event.x <= opt._end_x then - e.value = i - draw() - args.callback(e.value) - end + -- mouse up must always have started with a mouse down on the same button to count as a click + -- tap always has identical coordinates, so this always passes for taps + if button_ini == button_cur and button_cur ~= nil then + e.value = button_cur + draw() + args.callback(e.value) end end end diff --git a/graphics/events.lua b/graphics/events.lua index 1b5219c..92055f0 100644 --- a/graphics/events.lua +++ b/graphics/events.lua @@ -109,6 +109,11 @@ function events.mouse_transposed(event, elem_pos_x, elem_pos_y) } end +-- check if an event qualifies as a click (tap or up) +---@nodiscard +---@param t CLICK_TYPE +function events.was_clicked(t) return t == events.CLICK_TYPE.TAP or t == events.CLICK_TYPE.UP end + -- create a new mouse event to pass onto graphics renderer
-- supports: mouse_click, mouse_up, mouse_drag, mouse_scroll, and monitor_touch ---@param event_type os_event OS event to handle From 2c2f93623227f7815d6c4fc8db7049f9c2087fde Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 10 May 2023 11:46:06 -0400 Subject: [PATCH 08/49] #226 updated the other controls for new mouse events, added tabbar control --- graphics/element.lua | 1 + graphics/elements/controls/hazard_button.lua | 2 +- graphics/elements/controls/push_button.lua | 2 +- graphics/elements/controls/radio_button.lua | 9 +- graphics/elements/controls/sidebar.lua | 39 ++++-- .../elements/controls/spinbox_numeric.lua | 28 ++-- graphics/elements/controls/switch_button.lua | 6 +- graphics/elements/controls/tabbar.lua | 130 ++++++++++++++++++ 8 files changed, 186 insertions(+), 31 deletions(-) create mode 100644 graphics/elements/controls/tabbar.lua diff --git a/graphics/element.lua b/graphics/element.lua index 2f8dabd..edcbdcc 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -28,6 +28,7 @@ local element = {} ---|sidebar_args ---|spinbox_args ---|switch_button_args +---|tabbar_args ---|alarm_indicator_light ---|core_map_args ---|data_indicator_args diff --git a/graphics/elements/controls/hazard_button.lua b/graphics/elements/controls/hazard_button.lua index 3db6a3b..4dca5c4 100644 --- a/graphics/elements/controls/hazard_button.lua +++ b/graphics/elements/controls/hazard_button.lua @@ -141,7 +141,7 @@ local function hazard_button(args) end -- handle mouse interaction - ---@param event mouse_interaction + ---@param event mouse_interaction mouse event function e.handle_mouse(event) if e.enabled then if core.events.was_clicked(event.type) then diff --git a/graphics/elements/controls/push_button.lua b/graphics/elements/controls/push_button.lua index a55a4e4..64a5aa4 100644 --- a/graphics/elements/controls/push_button.lua +++ b/graphics/elements/controls/push_button.lua @@ -70,7 +70,7 @@ local function push_button(args) end -- handle mouse interaction - ---@param event mouse_interaction + ---@param event mouse_interaction mouse event function e.handle_mouse(event) if e.enabled then if event.type == CLICK_TYPE.TAP then diff --git a/graphics/elements/controls/radio_button.lua b/graphics/elements/controls/radio_button.lua index 3b2a593..050bf39 100644 --- a/graphics/elements/controls/radio_button.lua +++ b/graphics/elements/controls/radio_button.lua @@ -1,5 +1,6 @@ -- Radio Button Graphics Element +local core = require("graphics.core") local element = require("graphics.element") ---@class radio_button_args @@ -82,10 +83,10 @@ local function radio_button(args) -- handle mouse interaction ---@param event mouse_interaction mouse event function e.handle_mouse(event) - -- determine what was pressed - if e.enabled then - if args.options[event.y] ~= nil then - e.value = event.y + if e.enabled and core.events.was_clicked(event.type) and (event.initial.y == event.current.y) then + -- determine what was pressed + if args.options[event.current.y] ~= nil then + e.value = event.current.y draw() args.callback(e.value) end diff --git a/graphics/elements/controls/sidebar.lua b/graphics/elements/controls/sidebar.lua index 885761d..997b372 100644 --- a/graphics/elements/controls/sidebar.lua +++ b/graphics/elements/controls/sidebar.lua @@ -2,8 +2,11 @@ local tcd = require("scada-common.tcallbackdsp") +local core = require("graphics.core") local element = require("graphics.element") +local CLICK_TYPE = core.events.CLICK_TYPE + ---@class sidebar_tab ---@field char string character identifier ---@field color cpair tab colors (fg/bg) @@ -39,7 +42,10 @@ local function sidebar(args) -- show the button state ---@param pressed boolean if the currently selected tab should appear as actively pressed - local function draw(pressed) + ---@param pressed_idx? integer optional index to show as held (that is not yet selected) + local function draw(pressed, pressed_idx) + pressed_idx = pressed_idx or e.value + for i = 1, #args.tabs do local tab = args.tabs[i] ---@type sidebar_tab @@ -47,7 +53,7 @@ local function sidebar(args) e.window.setCursorPos(1, y) - if pressed and e.value == i then + if pressed and i == pressed_idx then e.window.setTextColor(e.fg_bg.fgd) e.window.setBackgroundColor(e.fg_bg.bkg) else @@ -74,16 +80,27 @@ local function sidebar(args) function e.handle_mouse(event) -- determine what was pressed if e.enabled then - local idx = math.ceil(event.y / 3) + local cur_idx = math.ceil(event.current.y / 3) + local ini_idx = math.ceil(event.initial.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) + if args.tabs[cur_idx] ~= nil then + if event.type == CLICK_TYPE.TAP then + e.value = cur_idx + draw(true) + -- show as unpressed in 0.25 seconds + tcd.dispatch(0.25, function () draw(false) end) + args.callback(e.value) + elseif event.type == CLICK_TYPE.DOWN then + draw(true, cur_idx) + elseif event.type == CLICK_TYPE.UP then + if cur_idx == ini_idx then + e.value = cur_idx + draw(false) + args.callback(e.value) + else draw(false) end + elseif event.type == CLICK_TYPE.EXITED then + draw(false) + end end end end diff --git a/graphics/elements/controls/spinbox_numeric.lua b/graphics/elements/controls/spinbox_numeric.lua index 15e0e76..6b88c0e 100644 --- a/graphics/elements/controls/spinbox_numeric.lua +++ b/graphics/elements/controls/spinbox_numeric.lua @@ -2,6 +2,7 @@ local util = require("scada-common.util") +local core = require("graphics.core") local element = require("graphics.element") ---@class spinbox_args @@ -130,19 +131,22 @@ local function spinbox(args) ---@param event mouse_interaction mouse event function e.handle_mouse(event) -- only handle if on an increment or decrement arrow - if e.enabled and event.x ~= dec_point_x then - local idx = util.trinary(event.x > dec_point_x, event.x - 1, event.x) - if digits[idx] ~= nil then - if event.y == 1 then - -- increment - digits[idx] = digits[idx] + 1 - elseif event.y == 3 then - -- decrement - digits[idx] = digits[idx] - 1 - end + if e.enabled and core.events.was_clicked(event.type) and + (event.current.x ~= dec_point_x) and (event.current.y ~= 2) then + if event.current.x == event.initial.x and event.current.y == event.initial.y then + local idx = util.trinary(event.current.x > dec_point_x, event.current.x - 1, event.current.x) + if digits[idx] ~= nil then + if event.current.y == 1 then + -- increment + digits[idx] = digits[idx] + 1 + elseif event.current.y == 3 then + -- decrement + digits[idx] = digits[idx] - 1 + end - update_value() - show_num() + update_value() + show_num() + end end end end diff --git a/graphics/elements/controls/switch_button.lua b/graphics/elements/controls/switch_button.lua index 012872c..344f757 100644 --- a/graphics/elements/controls/switch_button.lua +++ b/graphics/elements/controls/switch_button.lua @@ -1,5 +1,6 @@ -- Button Graphics Element +local core = require("graphics.core") local element = require("graphics.element") ---@class switch_button_args @@ -63,8 +64,9 @@ local function switch_button(args) draw_state() -- handle mouse interaction - function e.handle_mouse(_) - if e.enabled then + ---@param event mouse_interaction mouse event + function e.handle_mouse(event) + if e.enabled and core.events.was_clicked(event.type) then -- toggle state e.value = not e.value draw_state() diff --git a/graphics/elements/controls/tabbar.lua b/graphics/elements/controls/tabbar.lua new file mode 100644 index 0000000..6249951 --- /dev/null +++ b/graphics/elements/controls/tabbar.lua @@ -0,0 +1,130 @@ +-- Tab Bar Graphics Element + +local util = require("scada-common.util") + +local core = require("graphics.core") +local element = require("graphics.element") + +---@class tabbar_tab +---@field name string tab name +---@field color cpair tab colors (fg/bg) +---@field _start_x integer starting touch x range (inclusive) +---@field _end_x integer ending touch x range (inclusive) + +---@class tabbar_args +---@field tabs table tab options +---@field callback function function to call on tab change +---@field min_width? integer text length + 2 if omitted +---@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 fg_bg? cpair foreground/background colors + +-- new tab selector +---@param args tabbar_args +---@return graphics_element element, element_id id +local function tabbar(args) + assert(type(args.tabs) == "table", "graphics.elements.controls.tabbar: tabs is a required field") + assert(#args.tabs > 0, "graphics.elements.controls.tabbar: at least one tab is required") + assert(type(args.callback) == "function", "graphics.elements.controls.tabbar: callback is a required field") + assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0), + "graphics.elements.controls.tabbar: min_width must be nil or a number > 0") + + -- always 1 tall + args.height = 1 + + -- determine widths + local max_width = 1 + for i = 1, #args.tabs do + local opt = args.tabs[i] ---@type tabbar_tab + if string.len(opt.name) > max_width then + max_width = string.len(opt.name) + end + end + + local button_width = math.max(max_width, args.min_width or 0) + + -- create new graphics element base object + local e = element.new(args) + + assert(e.frame.w >= (button_width * #args.tabs), "graphics.elements.controls.tabbar: width insufficent to display all tabs") + + -- default to 1st tab + e.value = 1 + + -- calculate required tab dimension information + local next_x = 1 + for i = 1, #args.tabs do + local tab = args.tabs[i] ---@type tabbar_tab + + tab._start_x = next_x + tab._end_x = next_x + button_width - 1 + + next_x = next_x + button_width + end + + -- show the tab state + local function draw() + for i = 1, #args.tabs do + local tab = args.tabs[i] ---@type tabbar_tab + + e.window.setCursorPos(tab._start_x, 1) + + if e.value == i then + e.window.setTextColor(tab.color.fgd) + e.window.setBackgroundColor(tab.color.bkg) + else + e.window.setTextColor(e.fg_bg.fgd) + e.window.setBackgroundColor(e.fg_bg.bkg) + end + + e.window.write(util.pad(tab.name, button_width)) + end + end + + -- check which tab a given x is within + ---@return integer|nil button index or nil if not within a tab + local function which_tab(x) + for i = 1, #args.tabs do + local tab = args.tabs[i] ---@type tabbar_tab + if x >= tab._start_x and x <= tab._end_x then return i end + end + + return nil + end + + -- handle mouse interaction + ---@param event mouse_interaction mouse event + function e.handle_mouse(event) + -- determine what was pressed + if e.enabled and core.events.was_clicked(event.type) then + -- a button may have been pressed, which one was it? + local tab_ini = which_tab(event.initial.x) + local tab_cur = which_tab(event.current.x) + + -- mouse up must always have started with a mouse down on the same tab to count as a click + -- tap always has identical coordinates, so this always passes for taps + if tab_ini == tab_cur and tab_cur ~= nil then + e.value = tab_cur + draw() + args.callback(e.value) + end + end + end + + -- set the value + ---@param val integer new value + function e.set_value(val) + e.value = val + draw() + end + + -- initial draw + draw() + + return e.get() +end + +return tabbar From 3a0d677c16c90c95815eab65598b762058256f20 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Wed, 10 May 2023 19:21:54 +0000 Subject: [PATCH 09/49] #226 updated PLC/RTU front panels to use new mouse events --- reactor-plc/renderer.lua | 4 ++-- reactor-plc/startup.lua | 2 +- reactor-plc/threads.lua | 6 +++--- rtu/renderer.lua | 4 ++-- rtu/startup.lua | 2 +- rtu/threads.lua | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/reactor-plc/renderer.lua b/reactor-plc/renderer.lua index 0700ebe..9830751 100644 --- a/reactor-plc/renderer.lua +++ b/reactor-plc/renderer.lua @@ -70,9 +70,9 @@ end function renderer.ui_ready() return ui.display ~= nil end -- handle a mouse event ----@param event mouse_interaction +---@param event mouse_interaction|nil function renderer.handle_mouse(event) - if ui.display ~= nil then + if ui.display ~= nil and event ~= nil then ui.display.handle_mouse(event) end end diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index bd40fce..afe733f 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.17" +local R_PLC_VERSION = "v1.2.0" local println = util.println local println_ts = util.println_ts diff --git a/reactor-plc/threads.lua b/reactor-plc/threads.lua index 8470430..8dbea6d 100644 --- a/reactor-plc/threads.lua +++ b/reactor-plc/threads.lua @@ -257,9 +257,9 @@ function threads.thread__main(smem, init) -- update indicators databus.tx_hw_status(plc_state) - elseif event == "mouse_click" then - -- handle a monitor touch event - renderer.handle_mouse(core.events.click(param1, param2, param3)) + elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" then + -- handle a mouse event + renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3)) elseif event == "clock_start" then -- start loop clock loop_clock.start() diff --git a/rtu/renderer.lua b/rtu/renderer.lua index f79f19e..490959c 100644 --- a/rtu/renderer.lua +++ b/rtu/renderer.lua @@ -71,9 +71,9 @@ end function renderer.ui_ready() return ui.display ~= nil end -- handle a mouse event ----@param event mouse_interaction +---@param event mouse_interaction|nil function renderer.handle_mouse(event) - if ui.display ~= nil then + if ui.display ~= nil and event ~= nil then ui.display.handle_mouse(event) end end diff --git a/rtu/startup.lua b/rtu/startup.lua index e2d9d94..8612d72 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.5" +local RTU_VERSION = "v1.1.0" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE diff --git a/rtu/threads.lua b/rtu/threads.lua index 9dac9f1..046525c 100644 --- a/rtu/threads.lua +++ b/rtu/threads.lua @@ -229,9 +229,9 @@ function threads.thread__main(smem) end end end - elseif event == "mouse_click" then - -- handle a monitor touch event - renderer.handle_mouse(core.events.click(param1, param2, param3)) + elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" then + -- handle a mouse event + renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3)) end -- check for termination request From 676dfc8c22246a634079d7b6934b91283e8b34b5 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 10 May 2023 20:01:06 -0400 Subject: [PATCH 10/49] #226 mouse events in coordinator --- coordinator/renderer.lua | 4 ++-- coordinator/startup.lua | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/coordinator/renderer.lua b/coordinator/renderer.lua index 4aa0b53..ffb36bc 100644 --- a/coordinator/renderer.lua +++ b/coordinator/renderer.lua @@ -163,9 +163,9 @@ end function renderer.ui_ready() return engine.ui_ready end -- handle a touch event ----@param event mouse_interaction +---@param event mouse_interaction|nil function renderer.handle_mouse(event) - if engine.ui_ready then + if engine.ui_ready and event ~= nil then if event.monitor == engine.monitors.primary_name then engine.ui.main_display.handle_mouse(event) else diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 97408da..d9d5160 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.8" +local COORDINATOR_VERSION = "v0.14.0" local println = util.println local println_ts = util.println_ts @@ -358,7 +358,7 @@ local function main() end elseif event == "monitor_touch" then -- handle a monitor touch event - renderer.handle_mouse(core.events.touch(param1, param2, param3)) + renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3)) elseif event == "speaker_audio_empty" then -- handle speaker buffer emptied sounder.continue() From 0783c4c01f60ba89408330c8d865f57dece7f6e6 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 11 May 2023 19:55:02 -0400 Subject: [PATCH 11/49] #226 bugfixes and pocket mouse events --- graphics/elements/controls/multi_button.lua | 2 +- graphics/elements/controls/push_button.lua | 2 ++ graphics/elements/controls/switch_button.lua | 12 ++++++----- graphics/events.lua | 21 ++++++++++++-------- pocket/renderer.lua | 4 ++-- pocket/startup.lua | 4 ++-- 6 files changed, 27 insertions(+), 18 deletions(-) diff --git a/graphics/elements/controls/multi_button.lua b/graphics/elements/controls/multi_button.lua index fa177f4..e44bad0 100644 --- a/graphics/elements/controls/multi_button.lua +++ b/graphics/elements/controls/multi_button.lua @@ -105,7 +105,7 @@ local function multi_button(args) ---@param event mouse_interaction mouse event function e.handle_mouse(event) -- if enabled and the button row was pressed... - if e.enabled and core.events.was_clicked(event.type) and (event.initial.y == 1) and (event.current.y == 1) then + if e.enabled and core.events.was_clicked(event.type) then -- a button may have been pressed, which one was it? local button_ini = which_button(event.initial.x) local button_cur = which_button(event.current.x) diff --git a/graphics/elements/controls/push_button.lua b/graphics/elements/controls/push_button.lua index 64a5aa4..ed0fc2a 100644 --- a/graphics/elements/controls/push_button.lua +++ b/graphics/elements/controls/push_button.lua @@ -26,6 +26,8 @@ local CLICK_TYPE = core.events.CLICK_TYPE local function push_button(args) assert(type(args.text) == "string", "graphics.elements.controls.push_button: text is a required field") assert(type(args.callback) == "function", "graphics.elements.controls.push_button: callback is a required field") + assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0), + "graphics.elements.controls.push_button: min_width must be nil or a number > 0") local text_width = string.len(args.text) diff --git a/graphics/elements/controls/switch_button.lua b/graphics/elements/controls/switch_button.lua index 344f757..645bf8a 100644 --- a/graphics/elements/controls/switch_button.lua +++ b/graphics/elements/controls/switch_button.lua @@ -23,13 +23,15 @@ local function switch_button(args) assert(type(args.text) == "string", "graphics.elements.controls.switch_button: text is a required field") assert(type(args.callback) == "function", "graphics.elements.controls.switch_button: callback is a required field") assert(type(args.active_fg_bg) == "table", "graphics.elements.controls.switch_button: active_fg_bg is a required field") + assert(type(args.min_width) == "nil" or (type(args.min_width) == "number" and args.min_width > 0), + "graphics.elements.controls.switch_button: min_width must be nil or a number > 0") - -- single line - args.height = 1 - - -- determine widths local text_width = string.len(args.text) - args.width = math.max(text_width + 2, args.min_width) + + -- single line height, calculate width + args.height = 1 + args.min_width = args.min_width or 0 + args.width = math.max(text_width, args.min_width) -- create new graphics element base object local e = element.new(args) diff --git a/graphics/events.lua b/graphics/events.lua index 92055f0..7370481 100644 --- a/graphics/events.lua +++ b/graphics/events.lua @@ -25,6 +25,12 @@ events.CLICK_TYPE = { EXITED = 7 -- cursor exited bounds of element } +-- create a new 2D coordinate +---@param x integer +---@param y integer +---@return coordinate_2d +local function _coord2d(x, y) return { x = x, y = y } end + ---@class mouse_interaction ---@field monitor string ---@field button CLICK_BUTTON @@ -33,15 +39,14 @@ events.CLICK_TYPE = { ---@field current coordinate_2d local handler = { - button_down = { { 0, 0 }, { 0, 0 }, { 0, 0 } } -- left, right, middle button down tracking + -- left, right, middle button down tracking + button_down = { + _coord2d(0, 0), + _coord2d(0, 0), + _coord2d(0, 0) + } } --- create a new 2D coordinate ----@param x integer ----@param y integer ----@return coordinate_2d -local function _coord2d(x, y) return { x = x, y = y } end - -- create a new monitor touch mouse interaction event ---@nodiscard ---@param monitor string @@ -124,7 +129,7 @@ function events.was_clicked(t) return t == events.CLICK_TYPE.TAP or t == events. function events.new_mouse_event(event_type, opt, x, y) if event_type == "mouse_click" then ---@cast opt 1|2|3 - handler.button_down[opt] = { x, y } + handler.button_down[opt] = _coord2d(x, y) return _mouse_event(opt, events.CLICK_TYPE.DOWN, x, y, x, y) elseif event_type == "mouse_up" then ---@cast opt 1|2|3 diff --git a/pocket/renderer.lua b/pocket/renderer.lua index 1ecf3ab..fa25bcd 100644 --- a/pocket/renderer.lua +++ b/pocket/renderer.lua @@ -70,9 +70,9 @@ end function renderer.ui_ready() return ui.display ~= nil end -- handle a mouse event ----@param event mouse_interaction +---@param event mouse_interaction|nil function renderer.handle_mouse(event) - if ui.display ~= nil then + if ui.display ~= nil and event ~= nil then ui.display.handle_mouse(event) end end diff --git a/pocket/startup.lua b/pocket/startup.lua index 9516340..42752a8 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -152,9 +152,9 @@ local function main() -- got a packet local packet = pocket_comms.parse_packet(param1, param2, param3, param4, param5) pocket_comms.handle_packet(packet) - elseif event == "mouse_click" then + elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" then -- handle a monitor touch event - renderer.handle_mouse(core.events.touch(param1, param2, param3)) + renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3)) end -- check for termination request From fac9a8d104aeff269c358ddd2bcc6b8dcbafa227 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 11 May 2023 19:56:45 -0400 Subject: [PATCH 12/49] updated install manifest --- install_manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install_manifest.json b/install_manifest.json index d69ea32..dea492c 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.17", "rtu": "v1.0.5", "supervisor": "v0.15.6", "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": 90488, "graphics": 115520, "lockbox": 100797, "reactor-plc": 95520, "rtu": 100773, "supervisor": 282569, "coordinator": 196036, "pocket": 36123}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.2.0", "rtu": "v1.1.0", "supervisor": "v0.15.6", "coordinator": "v0.14.0", "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/events.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/tabbar.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": 5530, "system": 1991, "common": 90553, "graphics": 126610, "lockbox": 100797, "reactor-plc": 95588, "rtu": 100851, "supervisor": 282569, "coordinator": 195894, "pocket": 36101}} \ No newline at end of file From a81fd4960494d60eb4f87254096a37b4e79b8546 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 11 May 2023 20:01:04 -0400 Subject: [PATCH 13/49] updated manifest --- install_manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install_manifest.json b/install_manifest.json index dea492c..5da3a0c 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.2.0", "rtu": "v1.1.0", "supervisor": "v0.15.6", "coordinator": "v0.14.0", "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/events.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/tabbar.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": 5530, "system": 1991, "common": 90553, "graphics": 126610, "lockbox": 100797, "reactor-plc": 95588, "rtu": 100851, "supervisor": 282569, "coordinator": 195894, "pocket": 36101}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.2.0", "rtu": "v1.1.0", "supervisor": "v0.15.7", "coordinator": "v0.14.0", "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/events.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/tabbar.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": 5530, "system": 1991, "common": 90635, "graphics": 126610, "lockbox": 100797, "reactor-plc": 95708, "rtu": 100971, "supervisor": 283160, "coordinator": 196014, "pocket": 36221}} \ No newline at end of file From e159dbb85065cebb3c80a36d9faa5ce91d4cf760 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 11 May 2023 20:06:41 -0400 Subject: [PATCH 14/49] #184 updated supervisor for new mouse events --- supervisor/panel/front_panel.lua | 6 +++--- supervisor/panel/style.lua | 2 +- supervisor/renderer.lua | 4 ++-- supervisor/startup.lua | 13 +++---------- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/supervisor/panel/front_panel.lua b/supervisor/panel/front_panel.lua index 0098a6e..21d631b 100644 --- a/supervisor/panel/front_panel.lua +++ b/supervisor/panel/front_panel.lua @@ -22,10 +22,10 @@ local LED = require("graphics.elements.indicators.led") local LEDPair = require("graphics.elements.indicators.ledpair") local RGBLED = require("graphics.elements.indicators.ledrgb") -local TEXT_ALIGN = core.graphics.TEXT_ALIGN +local TEXT_ALIGN = core.TEXT_ALIGN -local cpair = core.graphics.cpair -local border = core.graphics.border +local cpair = core.cpair +local border = core.border -- create new main view ---@param panel graphics_element main displaybox diff --git a/supervisor/panel/style.lua b/supervisor/panel/style.lua index 31039d4..996453c 100644 --- a/supervisor/panel/style.lua +++ b/supervisor/panel/style.lua @@ -6,7 +6,7 @@ local core = require("graphics.core") local style = {} -local cpair = core.graphics.cpair +local cpair = core.cpair -- GLOBAL -- diff --git a/supervisor/renderer.lua b/supervisor/renderer.lua index ca49946..5dfb7d1 100644 --- a/supervisor/renderer.lua +++ b/supervisor/renderer.lua @@ -70,9 +70,9 @@ end function renderer.ui_ready() return ui.display ~= nil end -- handle a mouse event ----@param event mouse_interaction +---@param event mouse_interaction|nil function renderer.handle_mouse(event) - if ui.display ~= nil then + if ui.display ~= nil and event ~= nil then ui.display.handle_mouse(event) end end diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 57888e5..ce18670 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -174,16 +174,9 @@ local function main() -- got a packet local packet = superv_comms.parse_packet(param1, param2, param3, param4, param5) superv_comms.handle_packet(packet) - elseif event == "mouse_click" then - -- handle a monitor touch event - renderer.handle_mouse(core.events.touch(param1, param2, param3)) - log.debug(util.sprintf("mouse_click: %s [%d, %d]", param1, param2, param3)) - elseif event == "mouse_drag" then - log.debug(util.sprintf("mouse_drag: %s [%d, %d]", param1, param2, param3)) - elseif event == "mouse_scroll" then - log.debug(util.sprintf("mouse_scroll: %s [%d, %d]", param1, param2, param3)) - elseif event == "mouse_up" then - log.debug(util.sprintf("mouse_up: %s [%d, %d]", param1, param2, param3)) + elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" then + -- handle a mouse event + renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3)) end -- check for termination request From f6610489c2e451bbe805c9cdcf2937f7d30a9cbe Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 11 May 2023 20:54:43 -0400 Subject: [PATCH 15/49] #224 fix for RTU unit indexing on supervisor when virtual units were present --- install_manifest.json | 2 +- supervisor/session/rtu.lua | 10 +++------- supervisor/startup.lua | 2 +- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/install_manifest.json b/install_manifest.json index 5da3a0c..6327cf6 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.2.0", "rtu": "v1.1.0", "supervisor": "v0.15.7", "coordinator": "v0.14.0", "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/events.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/tabbar.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": 5530, "system": 1991, "common": 90635, "graphics": 126610, "lockbox": 100797, "reactor-plc": 95708, "rtu": 100971, "supervisor": 283160, "coordinator": 196014, "pocket": 36221}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.2.0", "rtu": "v1.1.0", "supervisor": "v0.15.8", "coordinator": "v0.14.0", "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/events.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/tabbar.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": 5530, "system": 1991, "common": 90635, "graphics": 126610, "lockbox": 100797, "reactor-plc": 95708, "rtu": 100333, "supervisor": 283104, "coordinator": 196014, "pocket": 36221}} \ No newline at end of file diff --git a/supervisor/session/rtu.lua b/supervisor/session/rtu.lua index 13460f6..b494aa6 100644 --- a/supervisor/session/rtu.lua +++ b/supervisor/session/rtu.lua @@ -171,7 +171,7 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili end if unit ~= nil then - table.insert(self.units, unit) + self.units[i] = unit elseif u_type ~= RTU_UNIT_TYPE.VIRTUAL then _reset_config() log.error(util.c(log_header, "bad advertisement: error occured while creating a unit (type is ", type_string, ")")) @@ -186,9 +186,7 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili self.connected = false -- mark all RTU unit sessions as closed so the reactor unit knows - for i = 1, #self.units do - self.units[i].close() - end + for _, unit in pairs(self.units) do unit.close() end end -- send a MODBUS packet @@ -351,9 +349,7 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili local time_now = util.time() - for i = 1, #self.units do - self.units[i].update(time_now) - end + for _, unit in pairs(self.units) do unit.update(time_now) end ---------------------- -- update periodics -- diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 2e16777..96a5095 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.7" +local SUPERVISOR_VERSION = "v0.15.8" local println = util.println local println_ts = util.println_ts From 36bd2c5e083a7d86335a2e9cd037a09717b0eb6c Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Fri, 12 May 2023 13:52:42 -0400 Subject: [PATCH 16/49] enabled debug logs on turbine modbustest --- test/turbine_modbustest.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/turbine_modbustest.lua b/test/turbine_modbustest.lua index fe167d7..c8f7801 100644 --- a/test/turbine_modbustest.lua +++ b/test/turbine_modbustest.lua @@ -22,7 +22,7 @@ println("") -- RTU init -- -log.init("/log.txt", log.MODE.NEW) +log.init("/log.txt", log.MODE.NEW, true) print(">>> init turbine RTU: ") From b2115fd0777900c4bf6063c7fd5e97dbcff61d54 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 13 May 2023 08:50:13 -0400 Subject: [PATCH 17/49] #229 element PSIL register/deletion, changes for RTU to use new PSIL register --- graphics/element.lua | 82 ++++++++++++++++++++++++++++++++++++--- rtu/databus.lua | 23 ++++++----- rtu/panel/front_panel.lua | 20 +++++----- rtu/renderer.lua | 6 +-- rtu/startup.lua | 2 +- scada-common/psil.lua | 14 +++++++ 6 files changed, 115 insertions(+), 32 deletions(-) diff --git a/graphics/element.lua b/graphics/element.lua index edcbdcc..891257d 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -3,6 +3,7 @@ -- local core = require("graphics.core") +local log = require("scada-common.log") local element = {} @@ -46,12 +47,18 @@ local element = {} ---|colormap_args ---|displaybox_args ---|div_args +---|listbox_args ---|multipane_args ---|pipenet_args ---|rectangle_args ---|textbox_args ---|tiling_args +---@class element_subscription +---@field ps psil ps used +---@field key string data key +---@field func function callback + -- a base graphics element, should not be created on its own ---@nodiscard ---@param args graphics_args arguments @@ -66,6 +73,7 @@ function element.new(args) bounds = { x1 = 1, y1 = 1, x2 = 1, y2 = 1 }, ---@class element_bounds next_y = 1, children = {}, + subscriptions = {}, mt = {} } @@ -183,6 +191,17 @@ function element.new(args) -- luacheck: push ignore ---@diagnostic disable: unused-local, unused-vararg + -- dynamically insert a child element + ---@param id string|integer element identifier + ---@param elem graphics_element element + function protected.insert(id, elem) + end + + -- dynamically remove a child element + ---@param id string|integer element identifier + function protected.remove(id) + end + -- handle a mouse event ---@param event mouse_interaction mouse interaction event function protected.handle_mouse(event) @@ -281,7 +300,25 @@ function element.new(args) ---@nodiscard function public.window() return protected.window end - -- CHILD ELEMENTS -- + -- delete this element (hide and unsubscribe from PSIL) + function public.delete() + -- hide + stop animations + public.hide() + + -- unsubscribe from PSIL + for i = 1, #self.subscriptions do + local s = self.subscriptions[i] ---@type element_subscription + s.ps.unsubscribe(s.key, s.func) + end + + -- delete all children + for k, v in pairs(self.children) do + v.delete() + self.children[k] = nil + end + end + + -- ELEMENT TREE -- -- add a child element ---@nodiscard @@ -311,12 +348,18 @@ function element.new(args) -- get a child element ---@nodiscard + ---@param id element_id ---@return graphics_element - function public.get_child(key) return self.children[key] end + function public.get_child(id) return self.children[id] end - -- remove child - ---@param key string|integer - function public.remove(key) self.children[key] = nil end + -- remove a child element + ---@param id element_id + function public.remove(id) + if self.children[id] ~= nil then + self.children[id].delete() + self.children[id] = nil + end + end -- attempt to get a child element by ID (does not include this element itself) ---@nodiscard @@ -335,6 +378,25 @@ function element.new(args) return nil end + -- DYNAMIC CHILD ELEMENTS -- + + -- insert an element as a contained child
+ -- this is intended to be used dynamically, and depends on the target element type.
+ -- not all elements support dynamic children. + ---@param id string|integer element identifier + ---@param elem graphics_element element + function public.insert_element(id, elem) + protected.insert(id, elem) + end + + -- remove an element from contained children
+ -- this is intended to be used dynamically, and depends on the target element type.
+ -- not all elements support dynamic children. + ---@param id string|integer element identifier + function public.remove_element(id) + protected.remove(id) + end + -- AUTO-PLACEMENT -- -- skip a line for automatically placed elements @@ -460,6 +522,16 @@ function element.new(args) protected.response_callback(result) end + -- register a callback with a PSIL, allowing for automatic unregister on delete
+ -- do not use graphics elements directly with PSIL subscribe() + ---@param ps psil PSIL to subscribe to + ---@param key string key to subscribe to + ---@param func function function to link + function public.register(ps, key, func) + table.insert(self.subscriptions, { ps = ps, key = key, func = func }) + ps.subscribe(key, func) + end + -- VISIBILITY -- -- show the element diff --git a/rtu/databus.lua b/rtu/databus.lua index 8ef720e..3014367 100644 --- a/rtu/databus.lua +++ b/rtu/databus.lua @@ -7,9 +7,8 @@ local util = require("scada-common.util") local databus = {} -local dbus_iface = { - ps = psil.create() -} +-- databus PSIL +databus.ps = psil.create() ---@enum RTU_UNIT_HW_STATE local RTU_UNIT_HW_STATE = { @@ -22,54 +21,54 @@ local RTU_UNIT_HW_STATE = { databus.RTU_UNIT_HW_STATE = RTU_UNIT_HW_STATE -- call to toggle heartbeat signal -function databus.heartbeat() dbus_iface.ps.toggle("heartbeat") end +function databus.heartbeat() databus.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) + databus.ps.publish("version", rtu_v) + databus.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) + databus.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) + databus.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) + databus.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) + databus.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) + databus.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) + databus.ps.subscribe(field, func) end return databus diff --git a/rtu/panel/front_panel.lua b/rtu/panel/front_panel.lua index 8dcaa1f..4c4aa78 100644 --- a/rtu/panel/front_panel.lua +++ b/rtu/panel/front_panel.lua @@ -49,22 +49,22 @@ local function init(panel, units) on.update(true) system.line_break() - databus.rx_field("heartbeat", heartbeat.update) + heartbeat.register(databus.ps, "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) + modem.register(databus.ps, "has_modem", modem.update) + network.register(databus.ps, "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) + rt_main.register(databus.ps, "routine__main", rt_main.update) + rt_comm.register(databus.ps, "routine__comms", rt_comm.update) -- -- about label @@ -74,8 +74,8 @@ local function init(panel, units) 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) + fw_v.register(databus.ps, "version", function (version) fw_v.set_value(util.c("FW: ", version)) end) + comms_v.register(databus.ps, "comms_version", function (version) comms_v.set_value(util.c("NT: v", version)) end) -- -- unit status list @@ -90,7 +90,7 @@ local function init(panel, units) 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) + rt_unit.register(databus.ps, "routine__unit_" .. i, rt_unit.update) end local unit_hw_statuses = Div{parent=panel,height=18,x=25,y=3} @@ -102,13 +102,13 @@ local function init(panel, units) -- 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_hw.register(databus.ps, "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.register(databus.ps, "unit_type_" .. i, function (t) name_box.set_value(util.c(UNIT_TYPE_LABELS[t + 1], " ", unit.index)) end) diff --git a/rtu/renderer.lua b/rtu/renderer.lua index 490959c..17949ce 100644 --- a/rtu/renderer.lua +++ b/rtu/renderer.lua @@ -45,10 +45,8 @@ function renderer.close_ui() -- stop blinking indicators flasher.clear() - -- hide to stop animation callbacks - ui.display.hide() - - -- clear root UI elements + -- delete element tree + ui.display.delete() ui.display = nil -- restore colors diff --git a/rtu/startup.lua b/rtu/startup.lua index 0693f9f..a284b4b 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.1.0" +local RTU_VERSION = "v1.2.0" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE diff --git a/scada-common/psil.lua b/scada-common/psil.lua index 664d10d..13dcaa5 100644 --- a/scada-common/psil.lua +++ b/scada-common/psil.lua @@ -2,6 +2,8 @@ -- Publisher-Subscriber Interconnect Layer -- +local util = require("scada-common.util") + local psil = {} -- instantiate a new PSI layer @@ -36,6 +38,15 @@ function psil.create() table.insert(self.ic[key].subscribers, { notify = func }) end + -- unsubscribe a function from a given key + ---@param key string data key + ---@param func function function to unsubscribe + function public.unsubscribe(key, func) + if self.ic[key] ~= nil then + util.filter_table(self.ic[key].subscribers, function (s) return s.notify ~= func end) + end + end + -- publish data to a given key, passing it to all subscribers if it has changed ---@param key string data key ---@param value any data value @@ -64,6 +75,9 @@ function psil.create() end end + -- clear the contents of the interconnect + function public.purge() self.ic = nil end + return public end From e763af99816f87715540d302ab27339c8d27b776 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 13 May 2023 09:43:42 -0400 Subject: [PATCH 18/49] #229 PLC changes for UI element register change --- reactor-plc/databus.lua | 54 ++++++++++++++++--------------- reactor-plc/panel/front_panel.lua | 54 +++++++++++++++---------------- reactor-plc/renderer.lua | 6 ++-- reactor-plc/startup.lua | 2 +- 4 files changed, 58 insertions(+), 58 deletions(-) diff --git a/reactor-plc/databus.lua b/reactor-plc/databus.lua index beee265..ba7a68e 100644 --- a/reactor-plc/databus.lua +++ b/reactor-plc/databus.lua @@ -8,14 +8,16 @@ local util = require("scada-common.util") local databus = {} +-- databus PSIL +databus.ps = psil.create() + local dbus_iface = { - ps = psil.create(), rps_scram = function () log.debug("DBUS: unset rps_scram() called") end, rps_reset = function () log.debug("DBUS: unset rps_reset() called") end } -- call to toggle heartbeat signal -function databus.heartbeat() dbus_iface.ps.toggle("heartbeat") end +function databus.heartbeat() databus.ps.toggle("heartbeat") end -- link RPS command functions ---@param scram function reactor SCRAM function @@ -35,42 +37,42 @@ function databus.rps_reset() dbus_iface.rps_reset() end ---@param plc_v string PLC version ---@param comms_v string comms version function databus.tx_versions(plc_v, comms_v) - dbus_iface.ps.publish("version", plc_v) - dbus_iface.ps.publish("comms_version", comms_v) + databus.ps.publish("version", plc_v) + databus.ps.publish("comms_version", comms_v) end -- transmit unit ID across the bus ---@param id integer unit ID function databus.tx_id(id) - dbus_iface.ps.publish("unit_id", id) + databus.ps.publish("unit_id", id) end -- transmit hardware status across the bus ---@param plc_state plc_state function databus.tx_hw_status(plc_state) - dbus_iface.ps.publish("reactor_dev_state", util.trinary(plc_state.no_reactor, 1, util.trinary(plc_state.reactor_formed, 3, 2))) - dbus_iface.ps.publish("has_modem", not plc_state.no_modem) - dbus_iface.ps.publish("degraded", plc_state.degraded) - dbus_iface.ps.publish("init_ok", plc_state.init_ok) + databus.ps.publish("reactor_dev_state", util.trinary(plc_state.no_reactor, 1, util.trinary(plc_state.reactor_formed, 3, 2))) + databus.ps.publish("has_modem", not plc_state.no_modem) + databus.ps.publish("degraded", plc_state.degraded) + databus.ps.publish("init_ok", plc_state.init_ok) 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) + databus.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) + databus.ps.publish("link_state", state) end -- transmit reactor enable state across the bus ---@param active boolean reactor active function databus.tx_reactor_state(active) - dbus_iface.ps.publish("reactor_active", active) + databus.ps.publish("reactor_active", active) end -- transmit RPS data across the bus @@ -78,26 +80,26 @@ end ---@param status table RPS 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]) - dbus_iface.ps.publish("rps_low_ccool", status[3]) - dbus_iface.ps.publish("rps_high_waste", status[4]) - dbus_iface.ps.publish("rps_high_hcool", status[5]) - dbus_iface.ps.publish("rps_no_fuel", status[6]) - dbus_iface.ps.publish("rps_fault", status[7]) - dbus_iface.ps.publish("rps_timeout", status[8]) - 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) + databus.ps.publish("rps_scram", tripped) + databus.ps.publish("rps_damage", status[1]) + databus.ps.publish("rps_high_temp", status[2]) + databus.ps.publish("rps_low_ccool", status[3]) + databus.ps.publish("rps_high_waste", status[4]) + databus.ps.publish("rps_high_hcool", status[5]) + databus.ps.publish("rps_no_fuel", status[6]) + databus.ps.publish("rps_fault", status[7]) + databus.ps.publish("rps_timeout", status[8]) + databus.ps.publish("rps_manual", status[9]) + databus.ps.publish("rps_automatic", status[10]) + databus.ps.publish("rps_sysfail", status[11]) + databus.ps.publish("emer_cool", emer_cool_active) 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) + databus.ps.subscribe(field, func) end return databus diff --git a/reactor-plc/panel/front_panel.lua b/reactor-plc/panel/front_panel.lua index c000a3d..8e28a75 100644 --- a/reactor-plc/panel/front_panel.lua +++ b/reactor-plc/panel/front_panel.lua @@ -31,7 +31,7 @@ local border = core.border ---@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) + header.register(databus.ps, "unit_id", function (id) header.set_value(util.c("REACTOR PLC - UNIT ", id)) end) -- -- system indicators @@ -43,8 +43,8 @@ local function init(panel) local heartbeat = LED{parent=system,label="HEARTBEAT",colors=cpair(colors.green,colors.green_off)} system.line_break() - databus.rx_field("init_ok", init_ok.update) - databus.rx_field("heartbeat", heartbeat.update) + init_ok.register(databus.ps, "init_ok", init_ok.update) + heartbeat.register(databus.ps, "heartbeat", heartbeat.update) local reactor = LEDPair{parent=system,label="REACTOR",off=colors.red,c1=colors.yellow,c2=colors.green} local modem = LED{parent=system,label="MODEM",colors=cpair(colors.green,colors.green_off)} @@ -52,9 +52,9 @@ local function init(panel) network.update(5) system.line_break() - databus.rx_field("reactor_dev_state", reactor.update) - databus.rx_field("has_modem", modem.update) - databus.rx_field("link_state", network.update) + reactor.register(databus.ps, "reactor_dev_state", reactor.update) + modem.register(databus.ps, "has_modem", modem.update) + network.register(databus.ps, "link_state", network.update) local rt_main = LED{parent=system,label="RT MAIN",colors=cpair(colors.green,colors.green_off)} local rt_rps = LED{parent=system,label="RT RPS",colors=cpair(colors.green,colors.green_off)} @@ -63,11 +63,11 @@ local function init(panel) local rt_sctl = LED{parent=system,label="RT SPCTL",colors=cpair(colors.green,colors.green_off)} system.line_break() - databus.rx_field("routine__main", rt_main.update) - databus.rx_field("routine__rps", rt_rps.update) - databus.rx_field("routine__comms_tx", rt_cmtx.update) - databus.rx_field("routine__comms_rx", rt_cmrx.update) - databus.rx_field("routine__spctl", rt_sctl.update) + rt_main.register(databus.ps, "routine__main", rt_main.update) + rt_rps.register(databus.ps, "routine__rps", rt_rps.update) + rt_cmtx.register(databus.ps, "routine__comms_tx", rt_cmtx.update) + rt_cmrx.register(databus.ps, "routine__comms_rx", rt_cmrx.update) + rt_sctl.register(databus.ps, "routine__spctl", rt_sctl.update) -- -- status & controls @@ -80,7 +80,7 @@ local function init(panel) -- 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) + emer_cool.register(databus.ps, "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)} @@ -92,8 +92,8 @@ local function init(panel) 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)} - databus.rx_field("reactor_active", active.update) - databus.rx_field("rps_scram", scram.update) + active.register(databus.ps, "reactor_active", active.update) + scram.register(databus.ps, "rps_scram", scram.update) -- -- about footer @@ -103,8 +103,8 @@ local function init(panel) 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} - 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) + fw_v.register(databus.ps, "version", function (version) fw_v.set_value(util.c("FW: ", version)) end) + comms_v.register(databus.ps, "comms_version", function (version) comms_v.set_value(util.c("NT: v", version)) end) -- -- rps list @@ -126,17 +126,17 @@ local function init(panel) local rps_ccl = LED{parent=rps,label="LO CCOOLANT",colors=cpair(colors.red,colors.red_off)} local rps_hcl = LED{parent=rps,label="HI HCOOLANT",colors=cpair(colors.red,colors.red_off)} - databus.rx_field("rps_manual", rps_man.update) - databus.rx_field("rps_automatic", rps_auto.update) - databus.rx_field("rps_timeout", rps_tmo.update) - databus.rx_field("rps_fault", rps_flt.update) - databus.rx_field("rps_sysfail", rps_fail.update) - databus.rx_field("rps_damage", rps_dmg.update) - databus.rx_field("rps_high_temp", rps_tmp.update) - databus.rx_field("rps_no_fuel", rps_nof.update) - 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) + rps_man.register(databus.ps, "rps_manual", rps_man.update) + rps_auto.register(databus.ps, "rps_automatic", rps_auto.update) + rps_tmo.register(databus.ps, "rps_timeout", rps_tmo.update) + rps_flt.register(databus.ps, "rps_fault", rps_flt.update) + rps_fail.register(databus.ps, "rps_sysfail", rps_fail.update) + rps_dmg.register(databus.ps, "rps_damage", rps_dmg.update) + rps_tmp.register(databus.ps, "rps_high_temp", rps_tmp.update) + rps_nof.register(databus.ps, "rps_no_fuel", rps_nof.update) + rps_wst.register(databus.ps, "rps_high_waste", rps_wst.update) + rps_ccl.register(databus.ps, "rps_low_ccool", rps_ccl.update) + rps_hcl.register(databus.ps, "rps_high_hcool", rps_hcl.update) end return init diff --git a/reactor-plc/renderer.lua b/reactor-plc/renderer.lua index 9830751..038918b 100644 --- a/reactor-plc/renderer.lua +++ b/reactor-plc/renderer.lua @@ -44,10 +44,8 @@ function renderer.close_ui() -- stop blinking indicators flasher.clear() - -- hide to stop animation callbacks - ui.display.hide() - - -- clear root UI elements + -- delete element tree + ui.display.delete() ui.display = nil -- restore colors diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 183fbf3..540b1fd 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.2.0" +local R_PLC_VERSION = "v1.3.0" local println = util.println local println_ts = util.println_ts From 466902371a9782dab28ac01967f6f54eeddc50e4 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 14 May 2023 19:13:12 -0400 Subject: [PATCH 19/49] #229 coordinator changes for UI element register change --- coordinator/renderer.lua | 6 +- coordinator/startup.lua | 2 +- coordinator/ui/components/boiler.lua | 14 +- coordinator/ui/components/imatrix.lua | 30 ++-- coordinator/ui/components/processctl.lua | 73 ++++---- coordinator/ui/components/reactor.lua | 20 +-- coordinator/ui/components/turbine.lua | 10 +- coordinator/ui/components/unit_detail.lua | 200 +++++++++++----------- coordinator/ui/layout/main_view.lua | 4 +- 9 files changed, 178 insertions(+), 181 deletions(-) diff --git a/coordinator/renderer.lua b/coordinator/renderer.lua index ffb36bc..fec6629 100644 --- a/coordinator/renderer.lua +++ b/coordinator/renderer.lua @@ -138,9 +138,9 @@ function renderer.close_ui() -- stop blinking indicators flasher.clear() - -- 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 + -- delete element trees + if engine.ui.main_display ~= nil then engine.ui.main_display.delete() end + for _, display in ipairs(engine.ui.unit_displays) do display.delete() end -- report ui as not ready engine.ui_ready = false diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 2944c14..2e08061 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.14.0" +local COORDINATOR_VERSION = "v0.15.0" local println = util.println local println_ts = util.println_ts diff --git a/coordinator/ui/components/boiler.lua b/coordinator/ui/components/boiler.lua index 9ed497c..114a0bb 100644 --- a/coordinator/ui/components/boiler.lua +++ b/coordinator/ui/components/boiler.lua @@ -27,9 +27,9 @@ local function new_view(root, x, y, ps) local temp = DataIndicator{parent=boiler,x=5,y=3,lu_colors=lu_col,label="Temp:",unit="K",format="%10.2f",value=0,width=22,fg_bg=text_fg_bg} local boil_r = DataIndicator{parent=boiler,x=5,y=4,lu_colors=lu_col,label="Boil:",unit="mB/t",format="%10.0f",value=0,commas=true,width=22,fg_bg=text_fg_bg} - ps.subscribe("computed_status", status.update) - ps.subscribe("temperature", temp.update) - ps.subscribe("boil_rate", boil_r.update) + status.register(ps, "computed_status", status.update) + temp.register(ps, "temperature", temp.update) + boil_r.register(ps, "boil_rate", boil_r.update) TextBox{parent=boiler,text="H",x=2,y=5,height=1,width=1,fg_bg=text_fg_bg} TextBox{parent=boiler,text="W",x=3,y=5,height=1,width=1,fg_bg=text_fg_bg} @@ -41,10 +41,10 @@ local function new_view(root, x, y, ps) local steam = VerticalBar{parent=boiler,x=27,y=1,fg_bg=cpair(colors.white,colors.gray),height=4,width=1} local ccool = VerticalBar{parent=boiler,x=28,y=1,fg_bg=cpair(colors.lightBlue,colors.gray),height=4,width=1} - ps.subscribe("hcool_fill", hcool.update) - ps.subscribe("water_fill", water.update) - ps.subscribe("steam_fill", steam.update) - ps.subscribe("ccool_fill", ccool.update) + hcool.register(ps, "hcool_fill", hcool.update) + water.register(ps, "water_fill", water.update) + steam.register(ps, "steam_fill", steam.update) + ccool.register(ps, "ccool_fill", ccool.update) end return new_view diff --git a/coordinator/ui/components/imatrix.lua b/coordinator/ui/components/imatrix.lua index c94ff9f..a234cbc 100644 --- a/coordinator/ui/components/imatrix.lua +++ b/coordinator/ui/components/imatrix.lua @@ -50,15 +50,15 @@ local function new_view(root, x, y, data, ps, id) local avg_in = PowerIndicator{parent=rect,x=7,y=9,lu_colors=lu_col,label="Avg. In: ",format="%8.2f",rate=true,value=0,width=26,fg_bg=text_fg_bg} local avg_out = PowerIndicator{parent=rect,x=7,y=10,lu_colors=lu_col,label="Avg. Out:",format="%8.2f",rate=true,value=0,width=26,fg_bg=text_fg_bg} - ps.subscribe("computed_status", status.update) - ps.subscribe("energy", function (val) energy.update(util.joules_to_fe(val)) end) - ps.subscribe("max_energy", function (val) capacity.update(util.joules_to_fe(val)) end) - ps.subscribe("last_input", function (val) input.update(util.joules_to_fe(val)) end) - ps.subscribe("last_output", function (val) output.update(util.joules_to_fe(val)) end) + status.register(ps, "computed_status", status.update) + energy.register(ps, "energy", function (val) energy.update(util.joules_to_fe(val)) end) + capacity.register(ps, "max_energy", function (val) capacity.update(util.joules_to_fe(val)) end) + input.register(ps, "last_input", function (val) input.update(util.joules_to_fe(val)) end) + output.register(ps, "last_output", function (val) output.update(util.joules_to_fe(val)) end) - ps.subscribe("avg_charge", avg_chg.update) - ps.subscribe("avg_inflow", avg_in.update) - ps.subscribe("avg_outflow", avg_out.update) + avg_chg.register(ps, "avg_charge", avg_chg.update) + avg_in.register(ps, "avg_inflow", avg_in.update) + avg_out.register(ps, "avg_outflow", avg_out.update) local fill = DataIndicator{parent=rect,x=11,y=12,lu_colors=lu_col,label="Fill:",unit="%",format="%8.2f",value=0,width=18,fg_bg=text_fg_bg} @@ -68,10 +68,10 @@ local function new_view(root, x, y, data, ps, id) TextBox{parent=rect,text="Transfer Capacity",x=11,y=17,height=1,width=17,fg_bg=label_fg_bg} local trans_cap = PowerIndicator{parent=rect,x=19,y=18,lu_colors=lu_col,label="",format="%5.2f",rate=true,value=0,width=12,fg_bg=text_fg_bg} - ps.subscribe("cells", cells.update) - ps.subscribe("providers", providers.update) - ps.subscribe("energy_fill", function (val) fill.update(val * 100) end) - ps.subscribe("transfer_cap", function (val) trans_cap.update(util.joules_to_fe(val)) end) + cells.register(ps, "cells", cells.update) + providers.register(ps, "providers", providers.update) + fill.register(ps, "energy_fill", function (val) fill.update(val * 100) end) + trans_cap.register(ps, "transfer_cap", function (val) trans_cap.update(util.joules_to_fe(val)) end) local charge = VerticalBar{parent=rect,x=2,y=2,fg_bg=cpair(colors.green,colors.gray),height=17,width=4} local in_cap = VerticalBar{parent=rect,x=7,y=12,fg_bg=cpair(colors.red,colors.gray),height=7,width=1} @@ -88,9 +88,9 @@ local function new_view(root, x, y, data, ps, id) end end - ps.subscribe("energy_fill", charge.update) - ps.subscribe("last_input", function (val) in_cap.update(calc_saturation(val)) end) - ps.subscribe("last_output", function (val) out_cap.update(calc_saturation(val)) end) + charge.register(ps, "energy_fill", charge.update) + in_cap.register(ps, "last_input", function (val) in_cap.update(calc_saturation(val)) end) + out_cap.register(ps, "last_output", function (val) out_cap.update(calc_saturation(val)) end) end return new_view diff --git a/coordinator/ui/components/processctl.lua b/coordinator/ui/components/processctl.lua index 8719968..a238a8c 100644 --- a/coordinator/ui/components/processctl.lua +++ b/coordinator/ui/components/processctl.lua @@ -55,9 +55,9 @@ local function new_view(root, x, y) local ind_mat = IndicatorLight{parent=main,label="Induction Matrix",colors=cpair(colors.green,colors.gray)} local rad_mon = TriIndicatorLight{parent=main,label="Radiation Monitor",c1=colors.gray,c2=colors.yellow,c3=colors.green} - facility.ps.subscribe("all_sys_ok", all_ok.update) - facility.induction_ps_tbl[1].subscribe("computed_status", function (status) ind_mat.update(status > 1) end) - facility.ps.subscribe("rad_computed_status", rad_mon.update) + all_ok.register(facility.ps, "all_sys_ok", all_ok.update) + ind_mat.register(facility.induction_ps_tbl[1], "computed_status", function (status) ind_mat.update(status > 1) end) + rad_mon.register(facility.ps, "rad_computed_status", rad_mon.update) main.line_break() @@ -66,10 +66,10 @@ local function new_view(root, x, y) local auto_ramp = IndicatorLight{parent=main,label="Process Ramping",colors=cpair(colors.white,colors.gray),flash=true,period=period.BLINK_250_MS} local auto_sat = IndicatorLight{parent=main,label="Min/Max Burn Rate",colors=cpair(colors.yellow,colors.gray)} - facility.ps.subscribe("auto_ready", auto_ready.update) - facility.ps.subscribe("auto_active", auto_act.update) - facility.ps.subscribe("auto_ramping", auto_ramp.update) - facility.ps.subscribe("auto_saturated", auto_sat.update) + auto_ready.register(facility.ps, "auto_ready", auto_ready.update) + auto_act.register(facility.ps, "auto_active", auto_act.update) + auto_ramp.register(facility.ps, "auto_ramping", auto_ramp.update) + auto_sat.register(facility.ps, "auto_saturated", auto_sat.update) main.line_break() @@ -80,20 +80,20 @@ local function new_view(root, x, y) local fac_rad_h = IndicatorLight{parent=main,label="Facility Radiation High",colors=cpair(colors.red,colors.gray),flash=true,period=period.BLINK_250_MS} local gen_fault = IndicatorLight{parent=main,label="Gen. Control Fault",colors=cpair(colors.yellow,colors.gray),flash=true,period=period.BLINK_500_MS} - facility.ps.subscribe("auto_scram", auto_scram.update) - facility.ps.subscribe("as_matrix_dc", matrix_dc.update) - facility.ps.subscribe("as_matrix_fill", matrix_fill.update) - facility.ps.subscribe("as_crit_alarm", unit_crit.update) - facility.ps.subscribe("as_radiation", fac_rad_h.update) - facility.ps.subscribe("as_gen_fault", gen_fault.update) + auto_scram.register(facility.ps, "auto_scram", auto_scram.update) + matrix_dc.register(facility.ps, "as_matrix_dc", matrix_dc.update) + matrix_fill.register(facility.ps, "as_matrix_fill", matrix_fill.update) + unit_crit.register(facility.ps, "as_crit_alarm", unit_crit.update) + fac_rad_h.register(facility.ps, "as_radiation", fac_rad_h.update) + gen_fault.register(facility.ps, "as_gen_fault", gen_fault.update) TextBox{parent=main,y=23,text="Radiation",height=1,width=13,fg_bg=style.label} local radiation = RadIndicator{parent=main,label="",format="%9.3f",lu_colors=lu_cpair,width=13,fg_bg=bw_fg_bg} - facility.ps.subscribe("radiation", radiation.update) + radiation.register(facility.ps, "radiation", radiation.update) TextBox{parent=main,x=15,y=23,text="Linked RTUs",height=1,width=11,fg_bg=style.label} local rtu_count = DataIndicator{parent=main,x=15,y=24,label="",format="%11d",value=0,lu_colors=lu_cpair,width=11,fg_bg=bw_fg_bg} - facility.ps.subscribe("rtu_count", rtu_count.update) + rtu_count.register(facility.ps, "rtu_count", rtu_count.update) --------------------- -- process control -- @@ -115,8 +115,8 @@ local function new_view(root, x, y) TextBox{parent=burn_target,x=18,y=2,text="mB/t"} local burn_sum = DataIndicator{parent=targets,x=9,y=4,label="",format="%18.1f",value=0,unit="mB/t",commas=true,lu_colors=cpair(colors.black,colors.black),width=23,fg_bg=cpair(colors.black,colors.brown)} - facility.ps.subscribe("process_burn_target", b_target.set_value) - facility.ps.subscribe("burn_sum", burn_sum.update) + b_target.register(facility.ps, "process_burn_target", b_target.set_value) + burn_sum.register(facility.ps, "burn_sum", burn_sum.update) local chg_tag = Div{parent=targets,x=1,y=6,width=8,height=4,fg_bg=cpair(colors.black,colors.purple)} TextBox{parent=chg_tag,x=2,y=2,text="Charge Target",width=7,height=2} @@ -126,8 +126,8 @@ local function new_view(root, x, y) TextBox{parent=chg_target,x=18,y=2,text="MFE"} local cur_charge = DataIndicator{parent=targets,x=9,y=9,label="",format="%19d",value=0,unit="MFE",commas=true,lu_colors=cpair(colors.black,colors.black),width=23,fg_bg=cpair(colors.black,colors.brown)} - facility.ps.subscribe("process_charge_target", c_target.set_value) - facility.induction_ps_tbl[1].subscribe("energy", function (j) cur_charge.update(util.joules_to_fe(j) / 1000000) end) + c_target.register(facility.ps, "process_charge_target", c_target.set_value) + cur_charge.register(facility.induction_ps_tbl[1], "energy", function (j) cur_charge.update(util.joules_to_fe(j) / 1000000) end) local gen_tag = Div{parent=targets,x=1,y=11,width=8,height=4,fg_bg=cpair(colors.black,colors.purple)} TextBox{parent=gen_tag,x=2,y=2,text="Gen. Target",width=7,height=2} @@ -137,8 +137,8 @@ local function new_view(root, x, y) TextBox{parent=gen_target,x=18,y=2,text="kFE/t"} local cur_gen = DataIndicator{parent=targets,x=9,y=14,label="",format="%17d",value=0,unit="kFE/t",commas=true,lu_colors=cpair(colors.black,colors.black),width=23,fg_bg=cpair(colors.black,colors.brown)} - facility.ps.subscribe("process_gen_target", g_target.set_value) - facility.induction_ps_tbl[1].subscribe("last_input", function (j) cur_gen.update(util.round(util.joules_to_fe(j) / 1000)) end) + g_target.register(facility.ps, "process_gen_target", g_target.set_value) + cur_gen.register(facility.induction_ps_tbl[1], "last_input", function (j) cur_gen.update(util.round(util.joules_to_fe(j) / 1000)) end) ----------------- -- unit limits -- @@ -160,12 +160,12 @@ local function new_view(root, x, y) rate_limits[i] = SpinboxNumeric{parent=lim_ctl,x=2,y=1,whole_num_precision=4,fractional_precision=1,min=0.1,arrow_fg_bg=cpair(colors.gray,colors.white),fg_bg=bw_fg_bg} TextBox{parent=lim_ctl,x=9,y=2,text="mB/t",width=4,height=1} - unit.unit_ps.subscribe("max_burn", rate_limits[i].set_max) - unit.unit_ps.subscribe("burn_limit", rate_limits[i].set_value) + rate_limits[i].register(unit.unit_ps, "max_burn", rate_limits[i].set_max) + rate_limits[i].register(unit.unit_ps, "burn_limit", rate_limits[i].set_value) local cur_burn = DataIndicator{parent=limit_div,x=9,y=_y+3,label="",format="%7.1f",value=0,unit="mB/t",commas=false,lu_colors=cpair(colors.black,colors.black),width=14,fg_bg=cpair(colors.black,colors.brown)} - unit.unit_ps.subscribe("act_burn_rate", cur_burn.update) + cur_burn.register(unit.unit_ps, "act_burn_rate", cur_burn.update) end ------------------- @@ -186,8 +186,8 @@ local function new_view(root, x, y) local ready = IndicatorLight{parent=lights,x=2,y=2,label="Ready",colors=cpair(colors.green,colors.gray)} local degraded = IndicatorLight{parent=lights,x=2,y=3,label="Degraded",colors=cpair(colors.red,colors.gray),flash=true,period=period.BLINK_250_MS} - unit.unit_ps.subscribe("U_AutoReady", ready.update) - unit.unit_ps.subscribe("U_AutoDegraded", degraded.update) + ready.register(unit.unit_ps, "U_AutoReady", ready.update) + degraded.register(unit.unit_ps, "U_AutoDegraded", degraded.update) end ------------------------- @@ -197,14 +197,14 @@ local function new_view(root, x, y) local ctl_opts = { "Monitored Max Burn", "Combined Burn Rate", "Charge Level", "Generation Rate" } local mode = RadioButton{parent=proc,x=34,y=1,options=ctl_opts,callback=function()end,radio_colors=cpair(colors.purple,colors.black),radio_bg=colors.gray} - facility.ps.subscribe("process_mode", mode.set_value) + mode.register(facility.ps, "process_mode", mode.set_value) local u_stat = Rectangle{parent=proc,border=border(1,colors.gray,true),thin=true,width=31,height=4,x=1,y=16,fg_bg=bw_fg_bg} local stat_line_1 = TextBox{parent=u_stat,x=1,y=1,text="UNKNOWN",width=31,height=1,alignment=TEXT_ALIGN.CENTER,fg_bg=bw_fg_bg} local stat_line_2 = TextBox{parent=u_stat,x=1,y=2,text="awaiting data...",width=31,height=1,alignment=TEXT_ALIGN.CENTER,fg_bg=cpair(colors.gray, colors.white)} - facility.ps.subscribe("status_line_1", stat_line_1.set_value) - facility.ps.subscribe("status_line_2", stat_line_2.set_value) + stat_line_1.register(facility.ps, "status_line_1", stat_line_1.set_value) + stat_line_2.register(facility.ps, "status_line_2", stat_line_2.set_value) local auto_controls = Div{parent=proc,x=1,y=20,width=31,height=5,fg_bg=cpair(colors.gray,colors.white)} @@ -233,11 +233,14 @@ local function new_view(root, x, y) tcd.dispatch(0.2, function () save.on_response(ack) end) end - facility.ps.subscribe("auto_ready", function (ready) + start.register(facility.ps, "auto_ready", function (ready) if ready and (not facility.auto_active) then start.enable() else start.disable() end end) - facility.ps.subscribe("auto_active", function (active) + -- REGISTER_NOTE: for optimization/brevity, due to not deleting anything but the whole element tree when it comes + -- to the process control display and coordinator GUI as a whole, child elements will not directly be registered here + -- (preventing garbage collection until the parent 'proc' is deleted) + proc.register(facility.ps, "auto_active", function (active) if active then b_target.disable() c_target.disable() @@ -246,9 +249,7 @@ local function new_view(root, x, y) mode.disable() start.disable() - for i = 1, #rate_limits do - rate_limits[i].disable() - end + for i = 1, #rate_limits do rate_limits[i].disable() end else b_target.enable() c_target.enable() @@ -257,9 +258,7 @@ local function new_view(root, x, y) mode.enable() if facility.auto_ready then start.enable() end - for i = 1, #rate_limits do - rate_limits[i].enable() - end + for i = 1, #rate_limits do rate_limits[i].enable() end end end) end diff --git a/coordinator/ui/components/reactor.lua b/coordinator/ui/components/reactor.lua index 578bbba..b4a2c1b 100644 --- a/coordinator/ui/components/reactor.lua +++ b/coordinator/ui/components/reactor.lua @@ -30,10 +30,10 @@ local function new_view(root, x, y, ps) local burn_r = DataIndicator{parent=reactor,x=2,y=4,lu_colors=lu_col,label="Burn Rate:",unit="mB/t",format="%10.2f",value=0,width=26,fg_bg=text_fg_bg} local heating_r = DataIndicator{parent=reactor,x=2,y=5,lu_colors=lu_col,label="Heating:",unit="mB/t",format="%12.0f",value=0,commas=true,width=26,fg_bg=text_fg_bg} - ps.subscribe("computed_status", status.update) - ps.subscribe("temp", core_temp.update) - ps.subscribe("act_burn_rate", burn_r.update) - ps.subscribe("heating_rate", heating_r.update) + status.register(ps, "computed_status", status.update) + core_temp.register(ps, "temp", core_temp.update) + burn_r.register(ps, "act_burn_rate", burn_r.update) + heating_r.register(ps, "heating_rate", heating_r.update) local reactor_fills = Rectangle{parent=root,border=border(1, colors.gray, true),width=24,height=7,x=(x + 29),y=y} @@ -47,7 +47,7 @@ local function new_view(root, x, y, ps) local hcool = HorizontalBar{parent=reactor_fills,x=8,y=4,show_percent=true,bar_fg_bg=cpair(colors.white,colors.gray),height=1,width=14} local waste = HorizontalBar{parent=reactor_fills,x=8,y=5,show_percent=true,bar_fg_bg=cpair(colors.brown,colors.gray),height=1,width=14} - ps.subscribe("ccool_type", function (type) + ccool.register(ps, "ccool_type", function (type) if type == types.FLUID.SODIUM then ccool.recolor(cpair(colors.lightBlue, colors.gray)) else @@ -55,7 +55,7 @@ local function new_view(root, x, y, ps) end end) - ps.subscribe("hcool_type", function (type) + hcool.register(ps, "hcool_type", function (type) if type == types.FLUID.SUPERHEATED_SODIUM then hcool.recolor(cpair(colors.orange, colors.gray)) else @@ -63,10 +63,10 @@ local function new_view(root, x, y, ps) end end) - ps.subscribe("fuel_fill", fuel.update) - ps.subscribe("ccool_fill", ccool.update) - ps.subscribe("hcool_fill", hcool.update) - ps.subscribe("waste_fill", waste.update) + fuel.register(ps, "fuel_fill", fuel.update) + ccool.register(ps, "ccool_fill", ccool.update) + hcool.register(ps, "hcool_fill", hcool.update) + waste.register(ps, "waste_fill", waste.update) end return new_view diff --git a/coordinator/ui/components/turbine.lua b/coordinator/ui/components/turbine.lua index 3bfd731..0e4cb21 100644 --- a/coordinator/ui/components/turbine.lua +++ b/coordinator/ui/components/turbine.lua @@ -30,9 +30,9 @@ local function new_view(root, x, y, ps) local prod_rate = PowerIndicator{parent=turbine,x=5,y=3,lu_colors=lu_col,label="",format="%10.2f",value=0,rate=true,width=16,fg_bg=text_fg_bg} local flow_rate = DataIndicator{parent=turbine,x=5,y=4,lu_colors=lu_col,label="",unit="mB/t",format="%10.0f",value=0,commas=true,width=16,fg_bg=text_fg_bg} - ps.subscribe("computed_status", status.update) - ps.subscribe("prod_rate", function (val) prod_rate.update(util.joules_to_fe(val)) end) - ps.subscribe("flow_rate", flow_rate.update) + status.register(ps, "computed_status", status.update) + prod_rate.register(ps, "prod_rate", function (val) prod_rate.update(util.joules_to_fe(val)) end) + flow_rate.register(ps, "flow_rate", flow_rate.update) local steam = VerticalBar{parent=turbine,x=2,y=1,fg_bg=cpair(colors.white,colors.gray),height=4,width=1} local energy = VerticalBar{parent=turbine,x=3,y=1,fg_bg=cpair(colors.green,colors.gray),height=4,width=1} @@ -40,8 +40,8 @@ local function new_view(root, x, y, ps) TextBox{parent=turbine,text="S",x=2,y=5,height=1,width=1,fg_bg=text_fg_bg} TextBox{parent=turbine,text="E",x=3,y=5,height=1,width=1,fg_bg=text_fg_bg} - ps.subscribe("steam_fill", steam.update) - ps.subscribe("energy_fill", energy.update) + steam.register(ps, "steam_fill", steam.update) + energy.register(ps, "energy_fill", energy.update) end return new_view diff --git a/coordinator/ui/components/unit_detail.lua b/coordinator/ui/components/unit_detail.lua index 7181430..12dc6b2 100644 --- a/coordinator/ui/components/unit_detail.lua +++ b/coordinator/ui/components/unit_detail.lua @@ -79,16 +79,16 @@ local function init(parent, id) ----------------------------- local core_map = CoreMap{parent=main,x=2,y=3,reactor_l=18,reactor_w=18} - u_ps.subscribe("temp", core_map.update) - u_ps.subscribe("size", function (s) core_map.resize(s[1], s[2]) end) + core_map.register(u_ps, "temp", core_map.update) + core_map.register(u_ps, "size", function (s) core_map.resize(s[1], s[2]) end) TextBox{parent=main,x=12,y=22,text="Heating Rate",height=1,width=12,fg_bg=style.label} local heating_r = DataIndicator{parent=main,x=12,label="",format="%14.0f",value=0,unit="mB/t",commas=true,lu_colors=lu_cpair,width=19,fg_bg=bw_fg_bg} - u_ps.subscribe("heating_rate", heating_r.update) + heating_r.register(u_ps, "heating_rate", heating_r.update) TextBox{parent=main,x=12,y=25,text="Commanded Burn Rate",height=1,width=19,fg_bg=style.label} local burn_r = DataIndicator{parent=main,x=12,label="",format="%14.2f",value=0,unit="mB/t",lu_colors=lu_cpair,width=19,fg_bg=bw_fg_bg} - u_ps.subscribe("burn_rate", burn_r.update) + burn_r.register(u_ps, "burn_rate", burn_r.update) TextBox{parent=main,text="F",x=2,y=22,width=1,height=1,fg_bg=style.label} TextBox{parent=main,text="C",x=4,y=22,width=1,height=1,fg_bg=style.label} @@ -102,12 +102,12 @@ local function init(parent, id) local hcool = VerticalBar{parent=main,x=8,y=23,fg_bg=cpair(colors.white,colors.gray),height=4,width=1} local waste = VerticalBar{parent=main,x=10,y=23,fg_bg=cpair(colors.brown,colors.gray),height=4,width=1} - u_ps.subscribe("fuel_fill", fuel.update) - u_ps.subscribe("ccool_fill", ccool.update) - u_ps.subscribe("hcool_fill", hcool.update) - u_ps.subscribe("waste_fill", waste.update) + fuel.register(u_ps, "fuel_fill", fuel.update) + ccool.register(u_ps, "ccool_fill", ccool.update) + hcool.register(u_ps, "hcool_fill", hcool.update) + waste.register(u_ps, "waste_fill", waste.update) - u_ps.subscribe("ccool_type", function (type) + ccool.register(u_ps, "ccool_type", function (type) if type == "mekanism:sodium" then ccool.recolor(cpair(colors.lightBlue, colors.gray)) else @@ -115,7 +115,7 @@ local function init(parent, id) end end) - u_ps.subscribe("hcool_type", function (type) + hcool.register(u_ps, "hcool_type", function (type) if type == "mekanism:superheated_sodium" then hcool.recolor(cpair(colors.orange, colors.gray)) else @@ -125,19 +125,19 @@ local function init(parent, id) TextBox{parent=main,x=32,y=22,text="Core Temp",height=1,width=9,fg_bg=style.label} local core_temp = DataIndicator{parent=main,x=32,label="",format="%11.2f",value=0,unit="K",lu_colors=lu_cpair,width=13,fg_bg=bw_fg_bg} - u_ps.subscribe("temp", core_temp.update) + core_temp.register(u_ps, "temp", core_temp.update) TextBox{parent=main,x=32,y=25,text="Burn Rate",height=1,width=9,fg_bg=style.label} local act_burn_r = DataIndicator{parent=main,x=32,label="",format="%8.2f",value=0,unit="mB/t",lu_colors=lu_cpair,width=13,fg_bg=bw_fg_bg} - u_ps.subscribe("act_burn_rate", act_burn_r.update) + act_burn_r.register(u_ps, "act_burn_rate", act_burn_r.update) TextBox{parent=main,x=32,y=28,text="Damage",height=1,width=6,fg_bg=style.label} local damage_p = DataIndicator{parent=main,x=32,label="",format="%11.0f",value=0,unit="%",lu_colors=lu_cpair,width=13,fg_bg=bw_fg_bg} - u_ps.subscribe("damage", damage_p.update) + damage_p.register(u_ps, "damage", damage_p.update) TextBox{parent=main,x=32,y=31,text="Radiation",height=1,width=21,fg_bg=style.label} local radiation = RadIndicator{parent=main,x=32,label="",format="%9.3f",lu_colors=lu_cpair,width=13,fg_bg=bw_fg_bg} - u_ps.subscribe("radiation", radiation.update) + radiation.register(u_ps, "radiation", radiation.update) ------------------- -- system status -- @@ -147,8 +147,8 @@ local function init(parent, id) local stat_line_1 = TextBox{parent=u_stat,x=1,y=1,text="UNKNOWN",width=33,height=1,alignment=TEXT_ALIGN.CENTER,fg_bg=bw_fg_bg} local stat_line_2 = TextBox{parent=u_stat,x=1,y=2,text="awaiting data...",width=33,height=1,alignment=TEXT_ALIGN.CENTER,fg_bg=cpair(colors.gray, colors.white)} - u_ps.subscribe("U_StatusLine1", stat_line_1.set_value) - u_ps.subscribe("U_StatusLine2", stat_line_2.set_value) + stat_line_1.register(u_ps, "U_StatusLine1", stat_line_1.set_value) + stat_line_2.register(u_ps, "U_StatusLine2", stat_line_2.set_value) ----------------- -- annunciator -- @@ -163,9 +163,9 @@ local function init(parent, id) local plc_hbeat = IndicatorLight{parent=annunciator,label="PLC Heartbeat",colors=cpair(colors.white,colors.gray)} local rad_mon = TriIndicatorLight{parent=annunciator,label="Radiation Monitor",c1=colors.gray,c2=colors.yellow,c3=colors.green} - u_ps.subscribe("PLCOnline", plc_online.update) - u_ps.subscribe("PLCHeartbeat", plc_hbeat.update) - u_ps.subscribe("RadiationMonitor", rad_mon.update) + plc_online.register(u_ps, "PLCOnline", plc_online.update) + plc_hbeat.register(u_ps, "PLCHeartbeat", plc_hbeat.update) + rad_mon.register(u_ps, "RadiationMonitor", rad_mon.update) annunciator.line_break() @@ -173,8 +173,8 @@ local function init(parent, id) local r_active = IndicatorLight{parent=annunciator,label="Active",colors=cpair(colors.green,colors.gray)} local r_auto = IndicatorLight{parent=annunciator,label="Automatic Control",colors=cpair(colors.white,colors.gray)} - u_ps.subscribe("status", r_active.update) - u_ps.subscribe("AutoControl", r_auto.update) + r_active.register(u_ps, "status", r_active.update) + r_auto.register(u_ps, "AutoControl", r_auto.update) -- main unit transient/warning annunciator panel local r_scram = IndicatorLight{parent=annunciator,label="Reactor SCRAM",colors=cpair(colors.red,colors.gray)} @@ -190,18 +190,18 @@ local function init(parent, id) local r_wloc = IndicatorLight{parent=annunciator,label="Waste Line Occlusion",colors=cpair(colors.yellow,colors.gray)} local r_hsrt = IndicatorLight{parent=annunciator,label="Startup Rate High",colors=cpair(colors.yellow,colors.gray)} - u_ps.subscribe("ReactorSCRAM", r_scram.update) - u_ps.subscribe("ManualReactorSCRAM", r_mscrm.update) - u_ps.subscribe("AutoReactorSCRAM", r_ascrm.update) - u_ps.subscribe("RadiationWarning", rad_wrn.update) - u_ps.subscribe("RCPTrip", r_rtrip.update) - u_ps.subscribe("RCSFlowLow", r_cflow.update) - u_ps.subscribe("CoolantLevelLow", r_clow.update) - u_ps.subscribe("ReactorTempHigh", r_temp.update) - u_ps.subscribe("ReactorHighDeltaT", r_rhdt.update) - u_ps.subscribe("FuelInputRateLow", r_firl.update) - u_ps.subscribe("WasteLineOcclusion", r_wloc.update) - u_ps.subscribe("HighStartupRate", r_hsrt.update) + r_scram.register(u_ps, "ReactorSCRAM", r_scram.update) + r_mscrm.register(u_ps, "ManualReactorSCRAM", r_mscrm.update) + r_ascrm.register(u_ps, "AutoReactorSCRAM", r_ascrm.update) + rad_wrn.register(u_ps, "RadiationWarning", rad_wrn.update) + r_rtrip.register(u_ps, "RCPTrip", r_rtrip.update) + r_cflow.register(u_ps, "RCSFlowLow", r_cflow.update) + r_clow.register(u_ps, "CoolantLevelLow", r_clow.update) + r_temp.register(u_ps, "ReactorTempHigh", r_temp.update) + r_rhdt.register(u_ps, "ReactorHighDeltaT", r_rhdt.update) + r_firl.register(u_ps, "FuelInputRateLow", r_firl.update) + r_wloc.register(u_ps, "WasteLineOcclusion", r_wloc.update) + r_hsrt.register(u_ps, "HighStartupRate", r_hsrt.update) -- RPS annunciator panel @@ -220,16 +220,16 @@ local function init(parent, id) local rps_tmo = IndicatorLight{parent=rps_annunc,label="Connection Timeout",colors=cpair(colors.yellow,colors.gray),flash=true,period=period.BLINK_500_MS} local rps_sfl = IndicatorLight{parent=rps_annunc,label="System Failure",colors=cpair(colors.orange,colors.gray),flash=true,period=period.BLINK_500_MS} - u_ps.subscribe("rps_tripped", rps_trp.update) - u_ps.subscribe("high_dmg", rps_dmg.update) - u_ps.subscribe("ex_hcool", rps_exh.update) - u_ps.subscribe("ex_waste", rps_exw.update) - u_ps.subscribe("high_temp", rps_tmp.update) - u_ps.subscribe("no_fuel", rps_nof.update) - u_ps.subscribe("low_cool", rps_loc.update) - u_ps.subscribe("fault", rps_flt.update) - u_ps.subscribe("timeout", rps_tmo.update) - u_ps.subscribe("sys_fail", rps_sfl.update) + rps_trp.register(u_ps, "rps_tripped", rps_trp.update) + rps_dmg.register(u_ps, "high_dmg", rps_dmg.update) + rps_exh.register(u_ps, "ex_hcool", rps_exh.update) + rps_exw.register(u_ps, "ex_waste", rps_exw.update) + rps_tmp.register(u_ps, "high_temp", rps_tmp.update) + rps_nof.register(u_ps, "no_fuel", rps_nof.update) + rps_loc.register(u_ps, "low_cool", rps_loc.update) + rps_flt.register(u_ps, "fault", rps_flt.update) + rps_tmo.register(u_ps, "timeout", rps_tmo.update) + rps_sfl.register(u_ps, "sys_fail", rps_sfl.update) -- cooling annunciator panel @@ -245,12 +245,12 @@ local function init(parent, id) local c_sfm = IndicatorLight{parent=rcs_annunc,label="Steam Feed Mismatch",colors=cpair(colors.yellow,colors.gray)} local c_mwrf = IndicatorLight{parent=rcs_annunc,label="Max Water Return Feed",colors=cpair(colors.yellow,colors.gray)} - u_ps.subscribe("RCSFault", c_flt.update) - u_ps.subscribe("EmergencyCoolant", c_emg.update) - u_ps.subscribe("CoolantFeedMismatch", c_cfm.update) - u_ps.subscribe("BoilRateMismatch", c_brm.update) - u_ps.subscribe("SteamFeedMismatch", c_sfm.update) - u_ps.subscribe("MaxWaterReturnFeed", c_mwrf.update) + c_flt.register(u_ps, "RCSFault", c_flt.update) + c_emg.register(u_ps, "EmergencyCoolant", c_emg.update) + c_cfm.register(u_ps, "CoolantFeedMismatch", c_cfm.update) + c_brm.register(u_ps, "BoilRateMismatch", c_brm.update) + c_sfm.register(u_ps, "SteamFeedMismatch", c_sfm.update) + c_mwrf.register(u_ps, "MaxWaterReturnFeed", c_mwrf.update) local available_space = 16 - (unit.num_boilers * 2 + unit.num_turbines * 4) @@ -267,11 +267,11 @@ local function init(parent, id) if unit.num_boilers > 0 then TextBox{parent=rcs_tags,x=1,text="B1",width=2,height=1,fg_bg=bw_fg_bg} local b1_wll = IndicatorLight{parent=rcs_annunc,label="Water Level Low",colors=cpair(colors.red,colors.gray)} - b_ps[1].subscribe("WasterLevelLow", b1_wll.update) + b1_wll.register(b_ps[1], "WasterLevelLow", b1_wll.update) TextBox{parent=rcs_tags,text="B1",width=2,height=1,fg_bg=bw_fg_bg} local b1_hr = IndicatorLight{parent=rcs_annunc,label="Heating Rate Low",colors=cpair(colors.yellow,colors.gray)} - b_ps[1].subscribe("HeatingRateLow", b1_hr.update) + b1_hr.register(b_ps[1], "HeatingRateLow", b1_hr.update) end if unit.num_boilers > 1 then -- note, can't (shouldn't for sure...) have 0 turbines @@ -283,11 +283,11 @@ local function init(parent, id) TextBox{parent=rcs_tags,text="B2",width=2,height=1,fg_bg=bw_fg_bg} local b2_wll = IndicatorLight{parent=rcs_annunc,label="Water Level Low",colors=cpair(colors.red,colors.gray)} - b_ps[2].subscribe("WasterLevelLow", b2_wll.update) + b2_wll.register(b_ps[2], "WasterLevelLow", b2_wll.update) TextBox{parent=rcs_tags,text="B2",width=2,height=1,fg_bg=bw_fg_bg} local b2_hr = IndicatorLight{parent=rcs_annunc,label="Heating Rate Low",colors=cpair(colors.yellow,colors.gray)} - b_ps[2].subscribe("HeatingRateLow", b2_hr.update) + b2_hr.register(b_ps[2], "HeatingRateLow", b2_hr.update) end -- turbine annunciator panels @@ -296,19 +296,19 @@ local function init(parent, id) TextBox{parent=rcs_tags,text="T1",width=2,height=1,fg_bg=bw_fg_bg} local t1_sdo = TriIndicatorLight{parent=rcs_annunc,label="Steam Relief Valve Open",c1=colors.gray,c2=colors.yellow,c3=colors.red} - t_ps[1].subscribe("SteamDumpOpen", t1_sdo.update) + t1_sdo.register(t_ps[1], "SteamDumpOpen", t1_sdo.update) TextBox{parent=rcs_tags,text="T1",width=2,height=1,fg_bg=bw_fg_bg} local t1_tos = IndicatorLight{parent=rcs_annunc,label="Turbine Over Speed",colors=cpair(colors.red,colors.gray)} - t_ps[1].subscribe("TurbineOverSpeed", t1_tos.update) + t1_tos.register(t_ps[1], "TurbineOverSpeed", t1_tos.update) TextBox{parent=rcs_tags,text="T1",width=2,height=1,fg_bg=bw_fg_bg} local t1_gtrp = IndicatorLight{parent=rcs_annunc,label="Generator Trip",colors=cpair(colors.yellow,colors.gray),flash=true,period=period.BLINK_250_MS} - t_ps[1].subscribe("GeneratorTrip", t1_gtrp.update) + t1_gtrp.register(t_ps[1], "GeneratorTrip", t1_gtrp.update) TextBox{parent=rcs_tags,text="T1",width=2,height=1,fg_bg=bw_fg_bg} local t1_trp = IndicatorLight{parent=rcs_annunc,label="Turbine Trip",colors=cpair(colors.red,colors.gray),flash=true,period=period.BLINK_250_MS} - t_ps[1].subscribe("TurbineTrip", t1_trp.update) + t1_trp.register(t_ps[1], "TurbineTrip", t1_trp.update) if unit.num_turbines > 1 then if (available_space > 2 and unit.num_turbines == 2) or available_space > 3 then @@ -317,19 +317,19 @@ local function init(parent, id) TextBox{parent=rcs_tags,text="T2",width=2,height=1,fg_bg=bw_fg_bg} local t2_sdo = TriIndicatorLight{parent=rcs_annunc,label="Steam Relief Valve Open",c1=colors.gray,c2=colors.yellow,c3=colors.red} - t_ps[2].subscribe("SteamDumpOpen", t2_sdo.update) + t2_sdo.register(t_ps[2], "SteamDumpOpen", t2_sdo.update) TextBox{parent=rcs_tags,text="T2",width=2,height=1,fg_bg=bw_fg_bg} local t2_tos = IndicatorLight{parent=rcs_annunc,label="Turbine Over Speed",colors=cpair(colors.red,colors.gray)} - t_ps[2].subscribe("TurbineOverSpeed", t2_tos.update) + t2_tos.register(t_ps[2], "TurbineOverSpeed", t2_tos.update) TextBox{parent=rcs_tags,text="T2",width=2,height=1,fg_bg=bw_fg_bg} local t2_gtrp = IndicatorLight{parent=rcs_annunc,label="Generator Trip",colors=cpair(colors.yellow,colors.gray),flash=true,period=period.BLINK_250_MS} - t_ps[2].subscribe("GeneratorTrip", t2_gtrp.update) + t2_gtrp.register(t_ps[2], "GeneratorTrip", t2_gtrp.update) TextBox{parent=rcs_tags,text="T2",width=2,height=1,fg_bg=bw_fg_bg} local t2_trp = IndicatorLight{parent=rcs_annunc,label="Turbine Trip",colors=cpair(colors.red,colors.gray),flash=true,period=period.BLINK_250_MS} - t_ps[2].subscribe("TurbineTrip", t2_trp.update) + t2_trp.register(t_ps[2], "TurbineTrip", t2_trp.update) end if unit.num_turbines > 2 then @@ -337,19 +337,19 @@ local function init(parent, id) TextBox{parent=rcs_tags,text="T3",width=2,height=1,fg_bg=bw_fg_bg} local t3_sdo = TriIndicatorLight{parent=rcs_annunc,label="Steam Relief Valve Open",c1=colors.gray,c2=colors.yellow,c3=colors.red} - t_ps[3].subscribe("SteamDumpOpen", t3_sdo.update) + t3_sdo.register(t_ps[3], "SteamDumpOpen", t3_sdo.update) TextBox{parent=rcs_tags,text="T3",width=2,height=1,fg_bg=bw_fg_bg} local t3_tos = IndicatorLight{parent=rcs_annunc,label="Turbine Over Speed",colors=cpair(colors.red,colors.gray)} - t_ps[3].subscribe("TurbineOverSpeed", t3_tos.update) + t3_tos.register(t_ps[3], "TurbineOverSpeed", t3_tos.update) TextBox{parent=rcs_tags,text="T3",width=2,height=1,fg_bg=bw_fg_bg} local t3_gtrp = IndicatorLight{parent=rcs_annunc,label="Generator Trip",colors=cpair(colors.yellow,colors.gray),flash=true,period=period.BLINK_250_MS} - t_ps[3].subscribe("GeneratorTrip", t3_gtrp.update) + t3_gtrp.register(t_ps[3], "GeneratorTrip", t3_gtrp.update) TextBox{parent=rcs_tags,text="T3",width=2,height=1,fg_bg=bw_fg_bg} local t3_trp = IndicatorLight{parent=rcs_annunc,label="Turbine Trip",colors=cpair(colors.red,colors.gray),flash=true,period=period.BLINK_250_MS} - t_ps[3].subscribe("TurbineTrip", t3_trp.update) + t3_trp.register(t_ps[3], "TurbineTrip", t3_trp.update) end ---------------------- @@ -365,8 +365,8 @@ local function init(parent, id) local set_burn = function () unit.set_burn(burn_rate.get_value()) end local set_burn_btn = PushButton{parent=burn_control,x=14,y=2,text="SET",min_width=5,fg_bg=cpair(colors.black,colors.yellow),active_fg_bg=cpair(colors.white,colors.gray),dis_fg_bg=dis_colors,callback=set_burn} - u_ps.subscribe("burn_rate", burn_rate.set_value) - u_ps.subscribe("max_burn", burn_rate.set_max) + burn_rate.register(u_ps, "burn_rate", burn_rate.set_value) + burn_rate.register(u_ps, "max_burn", burn_rate.set_max) local start = HazardButton{parent=main,x=2,y=28,text="START",accent=colors.lightBlue,dis_colors=dis_colors,callback=unit.start,fg_bg=hzd_fg_bg} local ack_a = HazardButton{parent=main,x=12,y=32,text="ACK \x13",accent=colors.orange,dis_colors=dis_colors,callback=unit.ack_alarms,fg_bg=hzd_fg_bg} @@ -387,9 +387,12 @@ local function init(parent, id) end end - u_ps.subscribe("status", start_button_en_check) - u_ps.subscribe("rps_tripped", start_button_en_check) - u_ps.subscribe("rps_tripped", function (active) if active then reset.enable() else reset.disable() end end) + start.register(u_ps, "status", start_button_en_check) + start.register(u_ps, "rps_tripped", start_button_en_check) + start.register(u_ps, "auto_group_id", start_button_en_check) + start.register(u_ps, "AutoControl", start_button_en_check) + + reset.register(u_ps, "rps_tripped", function (active) if active then reset.enable() else reset.disable() end end) TextBox{parent=main,text="WASTE PROCESSING",fg_bg=cpair(colors.black,colors.brown),alignment=TEXT_ALIGN.CENTER,width=33,height=1,x=46,y=48} local waste_proc = Rectangle{parent=main,border=border(1,colors.brown,true),thin=true,width=33,height=3,x=46,y=49} @@ -397,7 +400,7 @@ local function init(parent, id) local waste_mode = MultiButton{parent=waste_div,x=1,y=1,options=waste_opts,callback=unit.set_waste,min_width=6} - u_ps.subscribe("U_WasteMode", waste_mode.set_value) + waste_mode.register(u_ps, "U_WasteMode", waste_mode.set_value) ---------------------- -- alarm management -- @@ -420,20 +423,20 @@ local function init(parent, id) local a_clt = AlarmLight{parent=alarm_panel,x=6,label="RCS Transient",c1=colors.gray,c2=colors.yellow,c3=colors.green,flash=true,period=period.BLINK_500_MS} local a_tbt = AlarmLight{parent=alarm_panel,x=6,label="Turbine Trip",c1=colors.gray,c2=colors.red,c3=colors.green,flash=true,period=period.BLINK_250_MS} - u_ps.subscribe("Alarm_1", a_brc.update) - u_ps.subscribe("Alarm_2", a_rad.update) - u_ps.subscribe("Alarm_4", a_dmg.update) + a_brc.register(u_ps, "Alarm_1", a_brc.update) + a_rad.register(u_ps, "Alarm_2", a_rad.update) + a_dmg.register(u_ps, "Alarm_4", a_dmg.update) - u_ps.subscribe("Alarm_3", a_rcl.update) - u_ps.subscribe("Alarm_5", a_rcd.update) - u_ps.subscribe("Alarm_6", a_rot.update) - u_ps.subscribe("Alarm_7", a_rht.update) - u_ps.subscribe("Alarm_8", a_rwl.update) - u_ps.subscribe("Alarm_9", a_rwh.update) + a_rcl.register(u_ps, "Alarm_3", a_rcl.update) + a_rcd.register(u_ps, "Alarm_5", a_rcd.update) + a_rot.register(u_ps, "Alarm_6", a_rot.update) + a_rht.register(u_ps, "Alarm_7", a_rht.update) + a_rwl.register(u_ps, "Alarm_8", a_rwl.update) + a_rwh.register(u_ps, "Alarm_9", a_rwh.update) - u_ps.subscribe("Alarm_10", a_rps.update) - u_ps.subscribe("Alarm_11", a_clt.update) - u_ps.subscribe("Alarm_12", a_tbt.update) + a_rps.register(u_ps, "Alarm_10", a_rps.update) + a_clt.register(u_ps, "Alarm_11", a_clt.update) + a_tbt.register(u_ps, "Alarm_12", a_tbt.update) -- ack's and resets @@ -487,7 +490,7 @@ local function init(parent, id) local group = RadioButton{parent=auto_div,options=ctl_opts,callback=function()end,radio_colors=cpair(colors.blue,colors.white),radio_bg=colors.gray} - u_ps.subscribe("auto_group_id", function (gid) group.set_value(gid + 1) end) + group.register(u_ps, "auto_group_id", function (gid) group.set_value(gid + 1) end) auto_div.line_break() @@ -499,24 +502,28 @@ local function init(parent, id) TextBox{parent=auto_div,text="Prio. Group",height=1,width=11,fg_bg=style.label} local auto_grp = TextBox{parent=auto_div,text="Manual",height=1,width=11,fg_bg=bw_fg_bg} - u_ps.subscribe("auto_group", auto_grp.set_value) + auto_grp.register(u_ps, "auto_group", auto_grp.set_value) auto_div.line_break() local a_rdy = IndicatorLight{parent=auto_div,label="Ready",x=2,colors=cpair(colors.green,colors.gray)} local a_stb = IndicatorLight{parent=auto_div,label="Standby",x=2,colors=cpair(colors.white,colors.gray),flash=true,period=period.BLINK_1000_MS} - u_ps.subscribe("U_AutoReady", a_rdy.update) + a_rdy.register(u_ps, "U_AutoReady", a_rdy.update) -- update standby indicator - u_ps.subscribe("status", function (active) + a_stb.register(u_ps, "status", function (active) a_stb.update(unit.annunciator.AutoControl and (not active)) end) + a_stb.register(u_ps, "AutoControl", function (auto_active) + if auto_active then + a_stb.update(unit.reactor_data.mek_status.status == false) + else a_stb.update(false) end + end) - -- enable and disable controls based on group assignment - u_ps.subscribe("auto_group_id", function (gid) - start_button_en_check() - + -- enable/disable controls based on group assignment (start button is separate) + -- REGISTER_NOTE: register to parent element for brevity + burn_control.register(u_ps, "auto_group_id", function (gid) if gid == 0 then burn_rate.enable() set_burn_btn.enable() @@ -526,17 +533,8 @@ local function init(parent, id) end end) - -- enable and disable controls based on auto control state (start button is handled separately) - u_ps.subscribe("AutoControl", function (auto_active) - start_button_en_check() - - if auto_active then - a_stb.update(unit.reactor_data.mek_status.status == false) - else a_stb.update(false) end - end) - -- can't change group if auto is engaged regardless of if this unit is part of auto control - f_ps.subscribe("auto_active", function (auto_active) + set_grp_btn.register(f_ps, "auto_active", function (auto_active) if auto_active then set_grp_btn.disable() else set_grp_btn.enable() end end) diff --git a/coordinator/ui/layout/main_view.lua b/coordinator/ui/layout/main_view.lua index 5510382..a758b24 100644 --- a/coordinator/ui/layout/main_view.lua +++ b/coordinator/ui/layout/main_view.lua @@ -34,8 +34,8 @@ local function init(main) -- max length example: "01:23:45 AM - Wednesday, September 28 2022" local datetime = TextBox{parent=main,x=(header.width()-42),y=1,text="",alignment=TEXT_ALIGN.RIGHT,width=42,height=1,fg_bg=style.header} - facility.ps.subscribe("sv_ping", ping.update) - facility.ps.subscribe("date_time", datetime.set_value) + ping.register(facility.ps, "sv_ping", ping.update) + datetime.register(facility.ps, "date_time", datetime.set_value) local uo_1, uo_2, uo_3, uo_4 ---@type graphics_element From 82e3fa494c2e80fd293aedb00584546aba617a72 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 14 May 2023 19:13:44 -0400 Subject: [PATCH 20/49] #229 pocket changes for UI element register change --- pocket/startup.lua | 2 +- pocket/ui/main.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pocket/startup.lua b/pocket/startup.lua index 9ed088c..086cd68 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.6" +local POCKET_VERSION = "alpha-v0.3.0" local println = util.println local println_ts = util.println_ts diff --git a/pocket/ui/main.lua b/pocket/ui/main.lua index 1b7be88..c143b0b 100644 --- a/pocket/ui/main.lua +++ b/pocket/ui/main.lua @@ -45,7 +45,7 @@ local function init(main) local root_pane = MultiPane{parent=root_pane_div,x=1,y=1,panes=root_panes} - coreio.core_ps().subscribe("link_state", function (state) + root_pane.register(coreio.core_ps(), "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 From beda7624f48b5c414fe4fa2b83221f4a3741b941 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 18 May 2023 10:58:42 -0400 Subject: [PATCH 21/49] #233 fixed mouse enter/exit behavior via simplification --- graphics/element.lua | 24 ++++++++++------------ graphics/elements/controls/push_button.lua | 6 +++--- graphics/elements/controls/sidebar.lua | 6 +++--- graphics/events.lua | 3 +-- 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/graphics/element.lua b/graphics/element.lua index 891257d..8355cd6 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -93,15 +93,6 @@ function element.new(args) return "graphics.element{" .. self.elem_type .. "} @ " .. tostring(self) end - -- check if a coordinate is within the bounds of this element - ---@param x integer - ---@param y integer - local function _in_bounds(x, y) - local in_x = x >= self.bounds.x1 and x <= self.bounds.x2 - local in_y = y >= self.bounds.y1 and y <= self.bounds.y2 - return in_x and in_y - end - ---@class graphics_element local public = {} @@ -188,6 +179,15 @@ function element.new(args) self.bounds.y2 = self.position.y + f.h - 1 end + -- check if a coordinate is within the bounds of this element + ---@param x integer + ---@param y integer + function protected.in_bounds(x, y) + local in_x = x >= self.bounds.x1 and x <= self.bounds.x2 + local in_y = y >= self.bounds.y1 and y <= self.bounds.y2 + return in_x and in_y + end + -- luacheck: push ignore ---@diagnostic disable: unused-local, unused-vararg @@ -495,14 +495,12 @@ function element.new(args) -- handle a monitor touch or mouse click ---@param event mouse_interaction mouse interaction event function public.handle_mouse(event) - local x_ini, y_ini, x_cur, y_cur = event.initial.x, event.initial.y, event.current.x, event.current.y + local x_ini, y_ini = event.initial.x, event.initial.y - local ini_in = _in_bounds(x_ini, y_ini) - local cur_in = _in_bounds(x_cur, y_cur) + local ini_in = protected.in_bounds(x_ini, y_ini) if ini_in then local event_T = core.events.mouse_transposed(event, self.position.x, self.position.y) - if not cur_in then event_T.type = core.events.CLICK_TYPE.EXITED end -- handle the mouse event then pass to children protected.handle_mouse(event_T) diff --git a/graphics/elements/controls/push_button.lua b/graphics/elements/controls/push_button.lua index ed0fc2a..7f91ea5 100644 --- a/graphics/elements/controls/push_button.lua +++ b/graphics/elements/controls/push_button.lua @@ -84,9 +84,9 @@ local function push_button(args) show_pressed() elseif event.type == CLICK_TYPE.UP then show_unpressed() - args.callback() - elseif event.type == CLICK_TYPE.EXITED then - show_unpressed() + if e.in_bounds(event.current.x, event.current.y) then + args.callback() + end end end end diff --git a/graphics/elements/controls/sidebar.lua b/graphics/elements/controls/sidebar.lua index 997b372..a20cb72 100644 --- a/graphics/elements/controls/sidebar.lua +++ b/graphics/elements/controls/sidebar.lua @@ -93,14 +93,14 @@ local function sidebar(args) elseif event.type == CLICK_TYPE.DOWN then draw(true, cur_idx) elseif event.type == CLICK_TYPE.UP then - if cur_idx == ini_idx then + if cur_idx == ini_idx and e.in_bounds(event.current.x, event.current.y) then e.value = cur_idx draw(false) args.callback(e.value) else draw(false) end - elseif event.type == CLICK_TYPE.EXITED then - draw(false) end + elseif event.type == CLICK_TYPE.UP then + draw(false) end end end diff --git a/graphics/events.lua b/graphics/events.lua index 7370481..3391a18 100644 --- a/graphics/events.lua +++ b/graphics/events.lua @@ -21,8 +21,7 @@ events.CLICK_TYPE = { UP = 3, -- button up (completed a click) DRAG = 4, -- mouse dragged SCROLL_DOWN = 5, -- scroll down - SCROLL_UP = 6, -- scroll up - EXITED = 7 -- cursor exited bounds of element + SCROLL_UP = 6 -- scroll up } -- create a new 2D coordinate From d5fe790c86c86e7363f0463e8586ef75c76f31eb Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 18 May 2023 20:21:23 -0400 Subject: [PATCH 22/49] #227 move graphics windows --- graphics/element.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/graphics/element.lua b/graphics/element.lua index 8355cd6..c7b7f74 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -490,6 +490,14 @@ function element.new(args) protected.resize(...) end + -- reposition the element window
+ -- offsets relative to parent frame are where (1, 1) would be on top of the parent's top left corner + ---@param x integer x position relative to parent frame + ---@param y integer y position relative to parent frame + function public.reposition(x, y) + protected.window.reposition(x, y) + end + -- FUNCTION CALLBACKS -- -- handle a monitor touch or mouse click From 86615b03ff9dcd098930c218f1d243bbfb45e4a3 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 18 May 2023 20:42:15 -0400 Subject: [PATCH 23/49] fixed unused variable --- graphics/element.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/graphics/element.lua b/graphics/element.lua index c7b7f74..fc6ebd8 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -3,7 +3,6 @@ -- local core = require("graphics.core") -local log = require("scada-common.log") local element = {} From 792cb46ce6951a7a7a6e1fea0310ff836600e73c Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Fri, 19 May 2023 17:38:08 -0400 Subject: [PATCH 24/49] resolved register simplification --- coordinator/ui/components/unit_detail.lua | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/coordinator/ui/components/unit_detail.lua b/coordinator/ui/components/unit_detail.lua index 12dc6b2..30e2044 100644 --- a/coordinator/ui/components/unit_detail.lua +++ b/coordinator/ui/components/unit_detail.lua @@ -522,15 +522,11 @@ local function init(parent, id) end) -- enable/disable controls based on group assignment (start button is separate) - -- REGISTER_NOTE: register to parent element for brevity - burn_control.register(u_ps, "auto_group_id", function (gid) - if gid == 0 then - burn_rate.enable() - set_burn_btn.enable() - else - burn_rate.disable() - set_burn_btn.disable() - end + burn_rate.register(u_ps, "auto_group_id", function (gid) + if gid == 0 then burn_rate.enable() else burn_rate.disable() end + end) + set_burn_btn.register(u_ps, "auto_group_id", function (gid) + if gid == 0 then set_burn_btn.enable() else set_burn_btn.disable() end end) -- can't change group if auto is engaged regardless of if this unit is part of auto control From d5446f970b56604b39852cf22cc3e83c651c6734 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Fri, 19 May 2023 17:38:55 -0400 Subject: [PATCH 25/49] updated install manifest and removed early ref to listbox --- graphics/element.lua | 1 - install_manifest.json | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/graphics/element.lua b/graphics/element.lua index fc6ebd8..46b9ca1 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -46,7 +46,6 @@ local element = {} ---|colormap_args ---|displaybox_args ---|div_args ----|listbox_args ---|multipane_args ---|pipenet_args ---|rectangle_args diff --git a/install_manifest.json b/install_manifest.json index 6327cf6..e26050a 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.2.0", "rtu": "v1.1.0", "supervisor": "v0.15.8", "coordinator": "v0.14.0", "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/events.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/tabbar.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": 5530, "system": 1991, "common": 90635, "graphics": 126610, "lockbox": 100797, "reactor-plc": 95708, "rtu": 100333, "supervisor": 283104, "coordinator": 196014, "pocket": 36221}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.3.0", "rtu": "v1.2.0", "supervisor": "v0.15.8", "coordinator": "v0.15.0", "pocket": "alpha-v0.3.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/events.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/tabbar.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": 5530, "system": 1991, "common": 91102, "graphics": 129080, "lockbox": 100797, "reactor-plc": 95927, "rtu": 101013, "supervisor": 283104, "coordinator": 197539, "pocket": 36231}} \ No newline at end of file From 142f2c363a673f67b6e4a6e92d31fe3651f54df3 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Fri, 19 May 2023 19:12:27 -0400 Subject: [PATCH 26/49] #234 made debug config setting optional, defaults to false --- coordinator/startup.lua | 5 ++--- install_manifest.json | 2 +- pocket/startup.lua | 5 ++--- reactor-plc/startup.lua | 5 ++--- rtu/startup.lua | 5 ++--- supervisor/startup.lua | 5 ++--- 6 files changed, 11 insertions(+), 16 deletions(-) diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 2e08061..eca2bcc 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.15.0" +local COORDINATOR_VERSION = "v0.15.1" local println = util.println local println_ts = util.println_ts @@ -50,7 +50,6 @@ cfv.assert_type_num(config.SOUNDER_VOLUME) cfv.assert_type_bool(config.TIME_24_HOUR) cfv.assert_type_str(config.LOG_PATH) cfv.assert_type_int(config.LOG_MODE) -cfv.assert_type_bool(config.LOG_DEBUG) assert(cfv.valid(), "bad config file: missing/invalid fields") @@ -58,7 +57,7 @@ assert(cfv.valid(), "bad config file: missing/invalid fields") -- log init ---------------------------------------- -log.init(config.LOG_PATH, config.LOG_MODE, config.LOG_DEBUG) +log.init(config.LOG_PATH, config.LOG_MODE, config.LOG_DEBUG == true) log.info("========================================") log.info("BOOTING coordinator.startup " .. COORDINATOR_VERSION) diff --git a/install_manifest.json b/install_manifest.json index e26050a..18c5137 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.3.0", "rtu": "v1.2.0", "supervisor": "v0.15.8", "coordinator": "v0.15.0", "pocket": "alpha-v0.3.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/events.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/tabbar.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": 5530, "system": 1991, "common": 91102, "graphics": 129080, "lockbox": 100797, "reactor-plc": 95927, "rtu": 101013, "supervisor": 283104, "coordinator": 197539, "pocket": 36231}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.3.1", "rtu": "v1.2.1", "supervisor": "v0.15.9", "coordinator": "v0.15.1", "pocket": "alpha-v0.3.1"}, "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/events.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/tabbar.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": 5530, "system": 1991, "common": 91102, "graphics": 129080, "lockbox": 100797, "reactor-plc": 95896, "rtu": 100982, "supervisor": 283073, "coordinator": 197508, "pocket": 36200}} \ No newline at end of file diff --git a/pocket/startup.lua b/pocket/startup.lua index 086cd68..d1c54d0 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.3.0" +local POCKET_VERSION = "alpha-v0.3.1" local println = util.println local println_ts = util.println_ts @@ -36,7 +36,6 @@ 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) -cfv.assert_type_bool(config.LOG_DEBUG) assert(cfv.valid(), "bad config file: missing/invalid fields") @@ -44,7 +43,7 @@ assert(cfv.valid(), "bad config file: missing/invalid fields") -- log init ---------------------------------------- -log.init(config.LOG_PATH, config.LOG_MODE, config.LOG_DEBUG) +log.init(config.LOG_PATH, config.LOG_MODE, config.LOG_DEBUG == true) log.info("========================================") log.info("BOOTING pocket.startup " .. POCKET_VERSION) diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 540b1fd..c3b546f 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.3.0" +local R_PLC_VERSION = "v1.3.1" local println = util.println local println_ts = util.println_ts @@ -38,7 +38,6 @@ 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) -cfv.assert_type_bool(config.LOG_DEBUG) assert(cfv.valid(), "bad config file: missing/invalid fields") @@ -55,7 +54,7 @@ end -- log init ---------------------------------------- -log.init(config.LOG_PATH, config.LOG_MODE, config.LOG_DEBUG) +log.init(config.LOG_PATH, config.LOG_MODE, config.LOG_DEBUG == true) log.info("========================================") log.info("BOOTING reactor-plc.startup " .. R_PLC_VERSION) diff --git a/rtu/startup.lua b/rtu/startup.lua index a284b4b..a217ac3 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.2.0" +local RTU_VERSION = "v1.2.1" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE @@ -49,7 +49,6 @@ 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) -cfv.assert_type_bool(config.LOG_DEBUG) cfv.assert_type_table(config.RTU_DEVICES) cfv.assert_type_table(config.RTU_REDSTONE) assert(cfv.valid(), "bad config file: missing/invalid fields") @@ -58,7 +57,7 @@ assert(cfv.valid(), "bad config file: missing/invalid fields") -- log init ---------------------------------------- -log.init(config.LOG_PATH, config.LOG_MODE, config.LOG_DEBUG) +log.init(config.LOG_PATH, config.LOG_MODE, config.LOG_DEBUG == true) log.info("========================================") log.info("BOOTING rtu.startup " .. RTU_VERSION) diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 96a5095..534a5d9 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.8" +local SUPERVISOR_VERSION = "v0.15.9" local println = util.println local println_ts = util.println_ts @@ -40,7 +40,6 @@ cfv.assert_type_int(config.NUM_REACTORS) cfv.assert_type_table(config.REACTOR_COOLING) cfv.assert_type_str(config.LOG_PATH) cfv.assert_type_int(config.LOG_MODE) -cfv.assert_type_bool(config.LOG_DEBUG) assert(cfv.valid(), "bad config file: missing/invalid fields") @@ -62,7 +61,7 @@ end -- log init ---------------------------------------- -log.init(config.LOG_PATH, config.LOG_MODE, config.LOG_DEBUG) +log.init(config.LOG_PATH, config.LOG_MODE, config.LOG_DEBUG == true) log.info("========================================") log.info("BOOTING supervisor.startup " .. SUPERVISOR_VERSION) From ece7c0fe9ac47c0b2782ffa03e8789f31c9538c9 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Tue, 23 May 2023 19:22:22 -0400 Subject: [PATCH 27/49] #184 supervisor graphics updates for new system, added PLC and CRD pages on supervisor front panel --- graphics/elements/indicators/data.lua | 11 ++- supervisor/databus.lua | 81 +++++++++++++-- supervisor/panel/components/plc_entry.lua | 0 supervisor/panel/front_panel.lua | 115 +++++++++++++++++----- supervisor/panel/style.lua | 5 +- supervisor/session/coordinator.lua | 5 + supervisor/session/plc.lua | 5 + supervisor/session/svsessions.lua | 5 + supervisor/startup.lua | 2 +- 9 files changed, 190 insertions(+), 39 deletions(-) delete mode 100644 supervisor/panel/components/plc_entry.lua diff --git a/graphics/elements/indicators/data.lua b/graphics/elements/indicators/data.lua index 66d45dc..748c17a 100644 --- a/graphics/elements/indicators/data.lua +++ b/graphics/elements/indicators/data.lua @@ -52,6 +52,8 @@ local function data(args) clear_width = args.width - (label_len + 1) end + local value_color = e.fg_bg.fgd + -- on state change ---@param value any new value function e.on_update(value) @@ -64,7 +66,7 @@ local function data(args) -- write data local data_str = util.sprintf(args.format, value) e.window.setCursorPos(data_start, 1) - e.window.setTextColor(e.fg_bg.fgd) + e.window.setTextColor(value_color) if args.commas then e.window.write(util.comma_format(data_str)) else @@ -84,6 +86,13 @@ local function data(args) ---@param val any new value function e.set_value(val) e.on_update(val) end + -- change the foreground color of the value, or all text if no label/unit colors provided + ---@param c color + function e.recolor(c) + value_color = c + e.on_update(e.value) + end + -- initial value draw e.on_update(args.value) diff --git a/supervisor/databus.lua b/supervisor/databus.lua index e6bbee7..082a71e 100644 --- a/supervisor/databus.lua +++ b/supervisor/databus.lua @@ -6,39 +6,102 @@ local psil = require("scada-common.psil") local databus = {} +-- databus PSIL +databus.ps = psil.create() + local dbus_iface = { - ps = psil.create(), - session_entries = { rtu = {}, plc = {}, coord = {}, diag = {} } + session_entries = { rtu = {}, diag = {} } } -- call to toggle heartbeat signal -function databus.heartbeat() dbus_iface.ps.toggle("heartbeat") end +function databus.heartbeat() databus.ps.toggle("heartbeat") end -- transmit firmware versions across the bus ---@param plc_v string supervisor version ---@param comms_v string comms version function databus.tx_versions(plc_v, comms_v) - dbus_iface.ps.publish("version", plc_v) - dbus_iface.ps.publish("comms_version", comms_v) + databus.ps.publish("version", plc_v) + databus.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) + databus.ps.publish("has_modem", has_modem) end -function databus.tx_svs_connection(type, data) +-- transmit PLC firmware version and session connection state +---@param reactor_id integer reactor unit ID +---@param fw string firmware version +---@param channel integer PLC remote port +function databus.tx_plc_connected(reactor_id, fw, channel) + databus.ps.publish("plc_" .. reactor_id .. "_fw", fw) + databus.ps.publish("plc_" .. reactor_id .. "_conn", true) + databus.ps.publish("plc_" .. reactor_id .. "_chan", tostring(channel)) end -function databus.tx_svs_disconnection(type, data) +-- transmit PLC session connection state +---@param reactor_id integer reactor unit ID +function databus.tx_plc_disconnected(reactor_id) + databus.ps.publish("plc_" .. reactor_id .. "_fw", " ------- ") + databus.ps.publish("plc_" .. reactor_id .. "_conn", false) + databus.ps.publish("plc_" .. reactor_id .. "_chan", " --- ") + databus.ps.publish("plc_" .. reactor_id .. "_rtt", 0) + databus.ps.publish("plc_" .. reactor_id .. "_rtt_color", colors.lightGray) +end + +-- transmit PLC session RTT +---@param reactor_id integer reactor unit ID +---@param rtt integer round trip time +function databus.tx_plc_rtt(reactor_id, rtt) + databus.ps.publish("plc_" .. reactor_id .. "_rtt", rtt) + + if rtt > 700 then + databus.ps.publish("plc_" .. reactor_id .. "_rtt_color", colors.red) + elseif rtt > 300 then + databus.ps.publish("plc_" .. reactor_id .. "_rtt_color", colors.yellow_hc) + else + databus.ps.publish("plc_" .. reactor_id .. "_rtt_color", colors.green) + end +end + +-- transmit coordinator firmware version and session connection state +---@param fw string firmware version +---@param channel integer coordinator remote port +function databus.tx_crd_connected(fw, channel) + databus.ps.publish("crd_fw", fw) + databus.ps.publish("crd_conn", true) + databus.ps.publish("crd_chan", tostring(channel)) +end + +-- transmit coordinator session connection state +function databus.tx_crd_disconnected() + databus.ps.publish("crd_fw", " ------- ") + databus.ps.publish("crd_conn", false) + databus.ps.publish("crd_chan", "---") + databus.ps.publish("crd_rtt", 0) + databus.ps.publish("crd_rtt_color", colors.lightGray) +end + +-- transmit coordinator session RTT +---@param rtt integer round trip time +function databus.tx_crd_rtt(rtt) + databus.ps.publish("crd_rtt", rtt) + + if rtt > 700 then + databus.ps.publish("crd_rtt_color", colors.red) + elseif rtt > 300 then + databus.ps.publish("crd_rtt_color", colors.yellow_hc) + else + databus.ps.publish("crd_rtt_color", colors.green) + end 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) + databus.ps.subscribe(field, func) end return databus diff --git a/supervisor/panel/components/plc_entry.lua b/supervisor/panel/components/plc_entry.lua deleted file mode 100644 index e69de29..0000000 diff --git a/supervisor/panel/front_panel.lua b/supervisor/panel/front_panel.lua index 21d631b..bf95c6b 100644 --- a/supervisor/panel/front_panel.lua +++ b/supervisor/panel/front_panel.lua @@ -2,25 +2,28 @@ -- Main SCADA Coordinator GUI -- -local util = require("scada-common.util") +local util = require("scada-common.util") -local databus = require("supervisor.databus") +local config = require("supervisor.config") +local databus = require("supervisor.databus") -local style = require("supervisor.panel.style") +local style = require("supervisor.panel.style") -local core = require("graphics.core") +local core = require("graphics.core") -local Div = require("graphics.elements.div") -local MultiPane = require("graphics.elements.multipane") -local Rectangle = require("graphics.elements.rectangle") -local TextBox = require("graphics.elements.textbox") +local Div = require("graphics.elements.div") +local ListBox = require("graphics.elements.listbox") +local MultiPane = require("graphics.elements.multipane") +local Rectangle = require("graphics.elements.rectangle") +local TextBox = require("graphics.elements.textbox") -local PushButton = require("graphics.elements.controls.push_button") -local TabBar = require("graphics.elements.controls.tabbar") +local PushButton = require("graphics.elements.controls.push_button") +local TabBar = require("graphics.elements.controls.tabbar") -local LED = require("graphics.elements.indicators.led") -local LEDPair = require("graphics.elements.indicators.ledpair") -local RGBLED = require("graphics.elements.indicators.ledrgb") +local LED = require("graphics.elements.indicators.led") +local LEDPair = require("graphics.elements.indicators.ledpair") +local RGBLED = require("graphics.elements.indicators.ledrgb") +local DataIndicator = require("graphics.elements.indicators.data") local TEXT_ALIGN = core.TEXT_ALIGN @@ -47,12 +50,12 @@ local function init(panel) on.update(true) system.line_break() - databus.rx_field("heartbeat", heartbeat.update) + heartbeat.register(databus.ps, "heartbeat", heartbeat.update) local modem = LED{parent=system,label="MODEM",colors=cpair(colors.green,colors.green_off)} system.line_break() - databus.rx_field("has_modem", modem.update) + modem.register(databus.ps, "has_modem", modem.update) -- -- about footer @@ -62,30 +65,90 @@ local function init(panel) 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) + fw_v.register(databus.ps, "version", function (version) fw_v.set_value(util.c("FW: ", version)) end) + comms_v.register(databus.ps, "comms_version", function (version) comms_v.set_value(util.c("NT: v", version)) end) -- -- page handling -- - local plc_list = Div{parent=page_div,x=1,y=1} + -- plc page - TextBox{parent=plc_list,x=2,y=2,text="v1.1.17 - PLC - UNIT 4 - :15004",alignment=TEXT_ALIGN.LEFT,height=1} + local plc_page = Div{parent=page_div,x=1,y=1} + local plc_list = Div{parent=plc_page,x=2,y=2,width=49} - local panes = { main_page, plc_list, main_page, main_page, main_page } + for i = 1, config.NUM_REACTORS do + local ps_prefix = "plc_" .. i .. "_" + local plc_entry = Div{parent=plc_list,height=3,fg_bg=cpair(colors.black,colors.white)} + + TextBox{parent=plc_entry,x=1,y=1,text="",width=8,height=1,fg_bg=cpair(colors.black,colors.lightGray)} + TextBox{parent=plc_entry,x=1,y=2,text="UNIT "..i,alignment=TEXT_ALIGN.CENTER,width=8,height=1,fg_bg=cpair(colors.black,colors.lightGray)} + TextBox{parent=plc_entry,x=1,y=3,text="",width=8,height=1,fg_bg=cpair(colors.black,colors.lightGray)} + + local conn = LED{parent=plc_entry,x=10,y=2,label="CONN",colors=cpair(colors.green,colors.green_off)} + conn.register(databus.ps, ps_prefix .. "conn", conn.update) + + local plc_chan = TextBox{parent=plc_entry,x=17,y=2,text=" --- ",width=5,height=1,fg_bg=cpair(colors.gray,colors.white)} + plc_chan.register(databus.ps, ps_prefix .. "chan", plc_chan.set_value) + + TextBox{parent=plc_entry,x=23,y=2,text="FW:",width=3,height=1} + local plc_fw_v = TextBox{parent=plc_entry,x=27,y=2,text=" ------- ",width=9,height=1,fg_bg=cpair(colors.lightGray,colors.white)} + plc_fw_v.register(databus.ps, ps_prefix .. "fw", plc_fw_v.set_value) + + TextBox{parent=plc_entry,x=37,y=2,text="RTT:",width=4,height=1} + local plc_rtt = DataIndicator{parent=plc_entry,x=42,y=2,label="",unit="",format="%4d",value=0,width=4,fg_bg=cpair(colors.lightGray,colors.white)} + TextBox{parent=plc_entry,x=47,y=2,text="ms",width=4,height=1,fg_bg=cpair(colors.lightGray,colors.white)} + plc_rtt.register(databus.ps, ps_prefix .. "rtt", plc_rtt.update) + plc_rtt.register(databus.ps, ps_prefix .. "rtt_color", plc_rtt.recolor) + + plc_list.line_break() + end + + -- rtu page + + local rtu_page = Div{parent=page_div,x=1,y=1} + local rtu_list = Div{parent=rtu_page,x=2,y=2,width=49} + + -- coordinator page + + local crd_page = Div{parent=page_div,x=1,y=1} + local crd_box = Div{parent=crd_page,x=2,y=2,width=49,height=4,fg_bg=cpair(colors.black,colors.white)} + + local crd_conn = LED{parent=crd_box,x=2,y=2,label="CONNECTION",colors=cpair(colors.green,colors.green_off)} + crd_conn.register(databus.ps, "crd_conn", crd_conn.update) + + TextBox{parent=crd_box,x=4,y=3,text="CHANNEL ",width=8,height=1,fg_bg=cpair(colors.gray,colors.white)} + local crd_chan = TextBox{parent=crd_box,x=12,y=3,text="---",width=5,height=1,fg_bg=cpair(colors.gray,colors.white)} + crd_chan.register(databus.ps, "crd_chan", crd_chan.set_value) + + TextBox{parent=crd_box,x=22,y=2,text="FW:",width=3,height=1} + local crd_fw_v = TextBox{parent=crd_box,x=26,y=2,text=" ------- ",width=9,height=1,fg_bg=cpair(colors.lightGray,colors.white)} + crd_fw_v.register(databus.ps, "crd_fw", crd_fw_v.set_value) + + TextBox{parent=crd_box,x=36,y=2,text="RTT:",width=4,height=1} + local crd_rtt = DataIndicator{parent=crd_box,x=41,y=2,label="",unit="",format="%5d",value=0,width=5,fg_bg=cpair(colors.lightGray,colors.white)} + TextBox{parent=crd_box,x=47,y=2,text="ms",width=4,height=1,fg_bg=cpair(colors.lightGray,colors.white)} + crd_rtt.register(databus.ps, "crd_rtt", crd_rtt.update) + crd_rtt.register(databus.ps, "crd_rtt_color", crd_rtt.recolor) + + -- pocket page + + local pkt_page = Div{parent=page_div,x=1,y=1} + local pkt_box = Div{parent=pkt_page,x=2,y=2,width=49} + + local panes = { main_page, plc_page, rtu_page, crd_page, pkt_page } local page_pane = MultiPane{parent=page_div,x=1,y=1,panes=panes} local tabs = { - { name = "Main", color = cpair(colors.black, colors.ivory) }, - { name = "PLCs", color = cpair(colors.black, colors.ivory) }, - { name = "RTUs", color = cpair(colors.black, colors.ivory) }, - { name = "CRDs", color = cpair(colors.black, colors.ivory) }, - { name = "PKTs", color = cpair(colors.black, colors.ivory) }, + { name = "SVR", color = cpair(colors.black, colors.ivory) }, + { name = "PLC", color = cpair(colors.black, colors.ivory) }, + { name = "RTU", color = cpair(colors.black, colors.ivory) }, + { name = "CRD", color = cpair(colors.black, colors.ivory) }, + { name = "PKT", color = cpair(colors.black, colors.ivory) }, } - TabBar{parent=panel,y=2,tabs=tabs,min_width=10,callback=page_pane.set_value,fg_bg=cpair(colors.black,colors.white)} + TabBar{parent=panel,y=2,tabs=tabs,min_width=9,callback=page_pane.set_value,fg_bg=cpair(colors.black,colors.white)} end return init diff --git a/supervisor/panel/style.lua b/supervisor/panel/style.lua index 996453c..0668ccc 100644 --- a/supervisor/panel/style.lua +++ b/supervisor/panel/style.lua @@ -12,6 +12,7 @@ local cpair = core.cpair -- remap global colors colors.ivory = colors.pink +colors.yellow_hc = colors.purple colors.red_off = colors.brown colors.yellow_off = colors.magenta colors.green_off = colors.lime @@ -27,8 +28,8 @@ style.colors = { { 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.blue, hex = 0x0008fe }, -- LCD BLUE + { c = colors.purple, hex = 0xe3bc2a }, -- YELLOW HIGH CONTRAST { c = colors.pink, hex = 0xdcd9ca }, -- IVORY { c = colors.magenta, hex = 0x85862c }, -- YELLOW OFF -- { c = colors.white, hex = 0xdcd9ca }, diff --git a/supervisor/session/coordinator.lua b/supervisor/session/coordinator.lua index b68d815..03a579d 100644 --- a/supervisor/session/coordinator.lua +++ b/supervisor/session/coordinator.lua @@ -4,6 +4,8 @@ local mqueue = require("scada-common.mqueue") local types = require("scada-common.types") local util = require("scada-common.util") +local databus = require("supervisor.databus") + local svqtypes = require("supervisor.session.svqtypes") local coordinator = {} @@ -85,6 +87,7 @@ function coordinator.new_session(id, in_queue, out_queue, timeout, facility) local function _close() self.conn_watchdog.cancel() self.connected = false + databus.tx_crd_disconnected() end -- send a CRDN packet @@ -206,6 +209,8 @@ function coordinator.new_session(id, in_queue, out_queue, timeout, facility) -- log.debug(log_header .. "COORD RTT = " .. self.last_rtt .. "ms") -- log.debug(log_header .. "COORD TT = " .. (srv_now - coord_send) .. "ms") + + databus.tx_crd_rtt(self.last_rtt) else log.debug(log_header .. "SCADA keep alive packet length mismatch") end diff --git a/supervisor/session/plc.lua b/supervisor/session/plc.lua index 8c61221..0fb987a 100644 --- a/supervisor/session/plc.lua +++ b/supervisor/session/plc.lua @@ -4,6 +4,8 @@ local mqueue = require("scada-common.mqueue") local types = require("scada-common.types") local util = require("scada-common.util") +local databus = require("supervisor.databus") + local svqtypes = require("supervisor.session.svqtypes") local plc = {} @@ -236,6 +238,7 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) local function _close() self.conn_watchdog.cancel() self.connected = false + databus.tx_plc_disconnected(reactor_id) end -- send an RPLC packet @@ -486,6 +489,8 @@ function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) -- log.debug(log_header .. "PLC RTT = " .. self.last_rtt .. "ms") -- log.debug(log_header .. "PLC TT = " .. (srv_now - plc_send) .. "ms") + + databus.tx_plc_rtt(reactor_id, self.last_rtt) else log.debug(log_header .. "SCADA keep alive packet length mismatch") end diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index 93b35b9..8c56419 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -3,6 +3,7 @@ local mqueue = require("scada-common.mqueue") local util = require("scada-common.util") local config = require("supervisor.config") +local databus = require("supervisor.databus") local facility = require("supervisor.facility") local svqtypes = require("supervisor.session.svqtypes") @@ -317,6 +318,8 @@ function svsessions.establish_plc_session(local_port, remote_port, for_reactor, self.next_ids.plc = self.next_ids.plc + 1 + databus.tx_plc_connected(for_reactor, version, remote_port) + -- success return plc_s.instance.get_id() else @@ -383,6 +386,8 @@ function svsessions.establish_coord_session(local_port, remote_port, version) self.next_ids.coord = self.next_ids.coord + 1 + databus.tx_crd_connected(version, remote_port) + -- success return coord_s.instance.get_id() else diff --git a/supervisor/startup.lua b/supervisor/startup.lua index c3d966a..1c3f84c 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -19,7 +19,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.16.1" +local SUPERVISOR_VERSION = "v0.16.2" local println = util.println local println_ts = util.println_ts From 43a0ff86d7bda6b3f9893ad5d56b8c4f822ca781 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Tue, 23 May 2023 19:51:48 -0400 Subject: [PATCH 28/49] #238 bugfix for push button and sidebar in bounds checks --- coordinator/startup.lua | 2 +- graphics/element.lua | 15 ++++++++++++--- graphics/elements/controls/push_button.lua | 2 +- graphics/elements/controls/sidebar.lua | 2 +- pocket/startup.lua | 2 +- reactor-plc/startup.lua | 2 +- rtu/startup.lua | 2 +- 7 files changed, 18 insertions(+), 9 deletions(-) diff --git a/coordinator/startup.lua b/coordinator/startup.lua index eca2bcc..367c1ca 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.15.1" +local COORDINATOR_VERSION = "v0.15.2" local println = util.println local println_ts = util.println_ts diff --git a/graphics/element.lua b/graphics/element.lua index 46b9ca1..b865af0 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -177,15 +177,24 @@ function element.new(args) self.bounds.y2 = self.position.y + f.h - 1 end - -- check if a coordinate is within the bounds of this element + -- check if a coordinate relative to the parent is within the bounds of this element ---@param x integer ---@param y integer - function protected.in_bounds(x, y) + function protected.in_window_bounds(x, y) local in_x = x >= self.bounds.x1 and x <= self.bounds.x2 local in_y = y >= self.bounds.y1 and y <= self.bounds.y2 return in_x and in_y end + -- check if a coordinate relative to this window is within the bounds of this element + ---@param x integer + ---@param y integer + function protected.in_frame_bounds(x, y) + local in_x = x >= 1 and x <= protected.frame.w + local in_y = y >= 1 and y <= protected.frame.h + return in_x and in_y + end + -- luacheck: push ignore ---@diagnostic disable: unused-local, unused-vararg @@ -503,7 +512,7 @@ function element.new(args) function public.handle_mouse(event) local x_ini, y_ini = event.initial.x, event.initial.y - local ini_in = protected.in_bounds(x_ini, y_ini) + local ini_in = protected.in_window_bounds(x_ini, y_ini) if ini_in then local event_T = core.events.mouse_transposed(event, self.position.x, self.position.y) diff --git a/graphics/elements/controls/push_button.lua b/graphics/elements/controls/push_button.lua index 7f91ea5..27be991 100644 --- a/graphics/elements/controls/push_button.lua +++ b/graphics/elements/controls/push_button.lua @@ -84,7 +84,7 @@ local function push_button(args) show_pressed() elseif event.type == CLICK_TYPE.UP then show_unpressed() - if e.in_bounds(event.current.x, event.current.y) then + if e.in_frame_bounds(event.current.x, event.current.y) then args.callback() end end diff --git a/graphics/elements/controls/sidebar.lua b/graphics/elements/controls/sidebar.lua index a20cb72..45771b2 100644 --- a/graphics/elements/controls/sidebar.lua +++ b/graphics/elements/controls/sidebar.lua @@ -93,7 +93,7 @@ local function sidebar(args) elseif event.type == CLICK_TYPE.DOWN then draw(true, cur_idx) elseif event.type == CLICK_TYPE.UP then - if cur_idx == ini_idx and e.in_bounds(event.current.x, event.current.y) then + if cur_idx == ini_idx and e.in_frame_bounds(event.current.x, event.current.y) then e.value = cur_idx draw(false) args.callback(e.value) diff --git a/pocket/startup.lua b/pocket/startup.lua index d1c54d0..075919d 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.3.1" +local POCKET_VERSION = "alpha-v0.3.2" local println = util.println local println_ts = util.println_ts diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index c3b546f..1a7f550 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.3.1" +local R_PLC_VERSION = "v1.3.2" local println = util.println local println_ts = util.println_ts diff --git a/rtu/startup.lua b/rtu/startup.lua index a217ac3..6ff5e7d 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.2.1" +local RTU_VERSION = "v1.2.2" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE From f9aa75a1055e6a411ddc9eaa0e636f8aceeddc1a Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 25 May 2023 17:40:16 -0400 Subject: [PATCH 29/49] graphics element hidden on creation option, changed hide/show logic to only hide/show current element --- coordinator/startup.lua | 2 +- graphics/element.lua | 62 ++++++++++--------- graphics/elements/animations/waiting.lua | 1 + graphics/elements/colormap.lua | 1 + graphics/elements/controls/hazard_button.lua | 1 + graphics/elements/controls/multi_button.lua | 1 + graphics/elements/controls/push_button.lua | 1 + graphics/elements/controls/radio_button.lua | 1 + graphics/elements/controls/sidebar.lua | 1 + .../elements/controls/spinbox_numeric.lua | 1 + graphics/elements/controls/switch_button.lua | 1 + graphics/elements/controls/tabbar.lua | 1 + graphics/elements/displaybox.lua | 1 + graphics/elements/div.lua | 1 + graphics/elements/indicators/alight.lua | 1 + graphics/elements/indicators/data.lua | 1 + graphics/elements/indicators/hbar.lua | 1 + graphics/elements/indicators/icon.lua | 1 + graphics/elements/indicators/led.lua | 1 + graphics/elements/indicators/ledpair.lua | 1 + graphics/elements/indicators/ledrgb.lua | 1 + graphics/elements/indicators/light.lua | 1 + graphics/elements/indicators/power.lua | 1 + graphics/elements/indicators/rad.lua | 1 + graphics/elements/indicators/state.lua | 1 + graphics/elements/indicators/trilight.lua | 1 + graphics/elements/indicators/vbar.lua | 1 + graphics/elements/multipane.lua | 1 + graphics/elements/pipenet.lua | 1 + graphics/elements/rectangle.lua | 1 + graphics/elements/textbox.lua | 1 + graphics/elements/tiling.lua | 1 + pocket/startup.lua | 2 +- reactor-plc/startup.lua | 2 +- rtu/startup.lua | 2 +- supervisor/startup.lua | 2 +- 36 files changed, 69 insertions(+), 33 deletions(-) diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 367c1ca..60a0c88 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.15.2" +local COORDINATOR_VERSION = "v0.15.3" local println = util.println local println_ts = util.println_ts diff --git a/graphics/element.lua b/graphics/element.lua index b865af0..c6dbaa7 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -18,6 +18,7 @@ local element = {} ---@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 +---@field hidden? boolean true to hide on initial draw ---@alias graphics_args graphics_args_generic ---|waiting_args @@ -153,7 +154,7 @@ function element.new(args) assert(f.h >= 1, name_brief .. "frame height not >= 1") -- create window - protected.window = window.create(self.p_window, f.x, f.y, f.w, f.h, true) + protected.window = window.create(self.p_window, f.x, f.y, f.w, f.h, args.hidden ~= true) -- init colors if args.fg_bg ~= nil then @@ -385,25 +386,6 @@ function element.new(args) return nil end - -- DYNAMIC CHILD ELEMENTS -- - - -- insert an element as a contained child
- -- this is intended to be used dynamically, and depends on the target element type.
- -- not all elements support dynamic children. - ---@param id string|integer element identifier - ---@param elem graphics_element element - function public.insert_element(id, elem) - protected.insert(id, elem) - end - - -- remove an element from contained children
- -- this is intended to be used dynamically, and depends on the target element type.
- -- not all elements support dynamic children. - ---@param id string|integer element identifier - function public.remove_element(id) - protected.remove(id) - end - -- AUTO-PLACEMENT -- -- skip a line for automatically placed elements @@ -545,22 +527,46 @@ function element.new(args) ps.subscribe(key, func) end - -- VISIBILITY -- + -- VISIBILITY & ANIMATIONS -- - -- show the element - function public.show() + -- show the element and enables animations by default + ---@param animate? boolean true (default) to automatically resume animations + function public.show(animate) protected.window.setVisible(true) - protected.start_anim() - for _, child in pairs(self.children) do child.show() end + if animate ~= false then public.animate_all() end end - -- hide the element + -- hide the element and disables animations function public.hide() - protected.stop_anim() - for _, child in pairs(self.children) do child.hide() end + public.freeze_all() -- stop animations for efficiency/performance protected.window.setVisible(false) end + -- start/resume animation(s) + function public.animate() + protected.start_anim() + end + + -- start/resume animation(s) for this element and all its children
+ -- only animates if a window is visible + function public.animate_all() + if protected.window.isVisible() then + public.animate() + for _, child in pairs(self.children) do child.animate_all() end + end + end + + -- freeze animation(s) + function public.freeze() + protected.stop_anim() + end + + -- freeze animation(s) for this element and all its children + function public.freeze_all() + public.freeze() + for _, child in pairs(self.children) do child.freeze_all() end + end + -- re-draw the element function public.redraw() protected.window.redraw() diff --git a/graphics/elements/animations/waiting.lua b/graphics/elements/animations/waiting.lua index a0d7b3e..9d88c91 100644 --- a/graphics/elements/animations/waiting.lua +++ b/graphics/elements/animations/waiting.lua @@ -10,6 +10,7 @@ local element = require("graphics.element") ---@field x? integer 1 if omitted ---@field y? integer 1 if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new waiting animation element ---@param args waiting_args diff --git a/graphics/elements/colormap.lua b/graphics/elements/colormap.lua index 4c7ba94..f494158 100644 --- a/graphics/elements/colormap.lua +++ b/graphics/elements/colormap.lua @@ -9,6 +9,7 @@ local element = require("graphics.element") ---@field id? string element id ---@field x? integer 1 if omitted ---@field y? integer 1 if omitted +---@field hidden? boolean true to hide on initial draw -- new color map ---@param args colormap_args diff --git a/graphics/elements/controls/hazard_button.lua b/graphics/elements/controls/hazard_button.lua index 4dca5c4..844a6c8 100644 --- a/graphics/elements/controls/hazard_button.lua +++ b/graphics/elements/controls/hazard_button.lua @@ -16,6 +16,7 @@ local element = require("graphics.element") ---@field x? integer 1 if omitted ---@field y? integer 1 if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new hazard button ---@param args hazard_button_args diff --git a/graphics/elements/controls/multi_button.lua b/graphics/elements/controls/multi_button.lua index e44bad0..ca6600b 100644 --- a/graphics/elements/controls/multi_button.lua +++ b/graphics/elements/controls/multi_button.lua @@ -23,6 +23,7 @@ local element = require("graphics.element") ---@field y? integer 1 if omitted ---@field height? integer parent height if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new multi button (latch selection, exclusively one button at a time) ---@param args multi_button_args diff --git a/graphics/elements/controls/push_button.lua b/graphics/elements/controls/push_button.lua index 27be991..cfcd772 100644 --- a/graphics/elements/controls/push_button.lua +++ b/graphics/elements/controls/push_button.lua @@ -19,6 +19,7 @@ local CLICK_TYPE = core.events.CLICK_TYPE ---@field y? integer 1 if omitted ---@field height? integer parent height if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new push button ---@param args push_button_args diff --git a/graphics/elements/controls/radio_button.lua b/graphics/elements/controls/radio_button.lua index 050bf39..6fc5d56 100644 --- a/graphics/elements/controls/radio_button.lua +++ b/graphics/elements/controls/radio_button.lua @@ -15,6 +15,7 @@ local element = require("graphics.element") ---@field x? integer 1 if omitted ---@field y? integer 1 if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new radio button list (latch selection, exclusively one button at a time) ---@param args radio_button_args diff --git a/graphics/elements/controls/sidebar.lua b/graphics/elements/controls/sidebar.lua index 45771b2..7dae6ed 100644 --- a/graphics/elements/controls/sidebar.lua +++ b/graphics/elements/controls/sidebar.lua @@ -20,6 +20,7 @@ local CLICK_TYPE = core.events.CLICK_TYPE ---@field y? integer 1 if omitted ---@field height? integer parent height if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new sidebar tab selector ---@param args sidebar_args diff --git a/graphics/elements/controls/spinbox_numeric.lua b/graphics/elements/controls/spinbox_numeric.lua index 6b88c0e..bcdc9e5 100644 --- a/graphics/elements/controls/spinbox_numeric.lua +++ b/graphics/elements/controls/spinbox_numeric.lua @@ -18,6 +18,7 @@ local element = require("graphics.element") ---@field x? integer 1 if omitted ---@field y? integer 1 if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new spinbox control (minimum value is 0) ---@param args spinbox_args diff --git a/graphics/elements/controls/switch_button.lua b/graphics/elements/controls/switch_button.lua index 645bf8a..e02f506 100644 --- a/graphics/elements/controls/switch_button.lua +++ b/graphics/elements/controls/switch_button.lua @@ -15,6 +15,7 @@ local element = require("graphics.element") ---@field y? integer 1 if omitted ---@field height? integer parent height if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new switch button (latch high/low) ---@param args switch_button_args diff --git a/graphics/elements/controls/tabbar.lua b/graphics/elements/controls/tabbar.lua index 6249951..e188174 100644 --- a/graphics/elements/controls/tabbar.lua +++ b/graphics/elements/controls/tabbar.lua @@ -21,6 +21,7 @@ local element = require("graphics.element") ---@field y? integer 1 if omitted ---@field width? integer parent width if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new tab selector ---@param args tabbar_args diff --git a/graphics/elements/displaybox.lua b/graphics/elements/displaybox.lua index c7e5c9f..f6f520a 100644 --- a/graphics/elements/displaybox.lua +++ b/graphics/elements/displaybox.lua @@ -10,6 +10,7 @@ local element = require("graphics.element") ---@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 +---@field hidden? boolean true to hide on initial draw -- new root display box ---@nodiscard diff --git a/graphics/elements/div.lua b/graphics/elements/div.lua index 5eeef71..53e3e84 100644 --- a/graphics/elements/div.lua +++ b/graphics/elements/div.lua @@ -11,6 +11,7 @@ local element = require("graphics.element") ---@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 +---@field hidden? boolean true to hide on initial draw -- new div element ---@nodiscard diff --git a/graphics/elements/indicators/alight.lua b/graphics/elements/indicators/alight.lua index 8bb8fa6..2d933d6 100644 --- a/graphics/elements/indicators/alight.lua +++ b/graphics/elements/indicators/alight.lua @@ -18,6 +18,7 @@ local flasher = require("graphics.flasher") ---@field x? integer 1 if omitted ---@field y? integer 1 if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new alarm indicator light ---@nodiscard diff --git a/graphics/elements/indicators/data.lua b/graphics/elements/indicators/data.lua index 748c17a..a2b4ea9 100644 --- a/graphics/elements/indicators/data.lua +++ b/graphics/elements/indicators/data.lua @@ -17,6 +17,7 @@ local element = require("graphics.element") ---@field y? integer 1 if omitted ---@field width integer length ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new data indicator ---@nodiscard diff --git a/graphics/elements/indicators/hbar.lua b/graphics/elements/indicators/hbar.lua index 2d9b110..f69374e 100644 --- a/graphics/elements/indicators/hbar.lua +++ b/graphics/elements/indicators/hbar.lua @@ -15,6 +15,7 @@ local element = require("graphics.element") ---@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 +---@field hidden? boolean true to hide on initial draw -- new horizontal bar ---@nodiscard diff --git a/graphics/elements/indicators/icon.lua b/graphics/elements/indicators/icon.lua index f31479d..f079178 100644 --- a/graphics/elements/indicators/icon.lua +++ b/graphics/elements/indicators/icon.lua @@ -18,6 +18,7 @@ local element = require("graphics.element") ---@field x? integer 1 if omitted ---@field y? integer 1 if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new icon indicator ---@nodiscard diff --git a/graphics/elements/indicators/led.lua b/graphics/elements/indicators/led.lua index dd2264e..6a6f829 100644 --- a/graphics/elements/indicators/led.lua +++ b/graphics/elements/indicators/led.lua @@ -16,6 +16,7 @@ local flasher = require("graphics.flasher") ---@field x? integer 1 if omitted ---@field y? integer 1 if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new indicator LED ---@nodiscard diff --git a/graphics/elements/indicators/ledpair.lua b/graphics/elements/indicators/ledpair.lua index 727d4cd..94e6955 100644 --- a/graphics/elements/indicators/ledpair.lua +++ b/graphics/elements/indicators/ledpair.lua @@ -18,6 +18,7 @@ local flasher = require("graphics.flasher") ---@field x? integer 1 if omitted ---@field y? integer 1 if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new dual LED indicator light ---@nodiscard diff --git a/graphics/elements/indicators/ledrgb.lua b/graphics/elements/indicators/ledrgb.lua index 266e0ab..b66d102 100644 --- a/graphics/elements/indicators/ledrgb.lua +++ b/graphics/elements/indicators/ledrgb.lua @@ -11,6 +11,7 @@ local element = require("graphics.element") ---@field x? integer 1 if omitted ---@field y? integer 1 if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new RGB LED indicator light ---@nodiscard diff --git a/graphics/elements/indicators/light.lua b/graphics/elements/indicators/light.lua index e764ad9..8213439 100644 --- a/graphics/elements/indicators/light.lua +++ b/graphics/elements/indicators/light.lua @@ -16,6 +16,7 @@ local flasher = require("graphics.flasher") ---@field x? integer 1 if omitted ---@field y? integer 1 if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new indicator light ---@nodiscard diff --git a/graphics/elements/indicators/power.lua b/graphics/elements/indicators/power.lua index 1d727ae..b7137d7 100644 --- a/graphics/elements/indicators/power.lua +++ b/graphics/elements/indicators/power.lua @@ -16,6 +16,7 @@ local element = require("graphics.element") ---@field y? integer 1 if omitted ---@field width integer length ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new power indicator ---@nodiscard diff --git a/graphics/elements/indicators/rad.lua b/graphics/elements/indicators/rad.lua index 2e4ad56..c843cf4 100644 --- a/graphics/elements/indicators/rad.lua +++ b/graphics/elements/indicators/rad.lua @@ -17,6 +17,7 @@ local element = require("graphics.element") ---@field y? integer 1 if omitted ---@field width integer length ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new radiation indicator ---@nodiscard diff --git a/graphics/elements/indicators/state.lua b/graphics/elements/indicators/state.lua index 10d081b..3bb2831 100644 --- a/graphics/elements/indicators/state.lua +++ b/graphics/elements/indicators/state.lua @@ -18,6 +18,7 @@ local element = require("graphics.element") ---@field y? integer 1 if omitted ---@field height? integer 1 if omitted, must be an odd number ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new state indicator ---@nodiscard diff --git a/graphics/elements/indicators/trilight.lua b/graphics/elements/indicators/trilight.lua index 543ebf5..bbc7526 100644 --- a/graphics/elements/indicators/trilight.lua +++ b/graphics/elements/indicators/trilight.lua @@ -18,6 +18,7 @@ local flasher = require("graphics.flasher") ---@field x? integer 1 if omitted ---@field y? integer 1 if omitted ---@field fg_bg? cpair foreground/background colors +---@field hidden? boolean true to hide on initial draw -- new tri-state indicator light ---@nodiscard diff --git a/graphics/elements/indicators/vbar.lua b/graphics/elements/indicators/vbar.lua index fe7f9bc..9c8a8f4 100644 --- a/graphics/elements/indicators/vbar.lua +++ b/graphics/elements/indicators/vbar.lua @@ -13,6 +13,7 @@ local element = require("graphics.element") ---@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 +---@field hidden? boolean true to hide on initial draw -- new vertical bar ---@nodiscard diff --git a/graphics/elements/multipane.lua b/graphics/elements/multipane.lua index 8e25bab..20da7ed 100644 --- a/graphics/elements/multipane.lua +++ b/graphics/elements/multipane.lua @@ -12,6 +12,7 @@ local element = require("graphics.element") ---@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 +---@field hidden? boolean true to hide on initial draw -- new multipane element ---@nodiscard diff --git a/graphics/elements/pipenet.lua b/graphics/elements/pipenet.lua index 8a1d29b..8314fd2 100644 --- a/graphics/elements/pipenet.lua +++ b/graphics/elements/pipenet.lua @@ -12,6 +12,7 @@ local element = require("graphics.element") ---@field id? string element id ---@field x? integer 1 if omitted ---@field y? integer 1 if omitted +---@field hidden? boolean true to hide on initial draw -- new pipe network ---@param args pipenet_args diff --git a/graphics/elements/rectangle.lua b/graphics/elements/rectangle.lua index 2f7a68d..b80b37c 100644 --- a/graphics/elements/rectangle.lua +++ b/graphics/elements/rectangle.lua @@ -16,6 +16,7 @@ local element = require("graphics.element") ---@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 +---@field hidden? boolean true to hide on initial draw -- new rectangle ---@param args rectangle_args diff --git a/graphics/elements/textbox.lua b/graphics/elements/textbox.lua index 9066deb..6e5717f 100644 --- a/graphics/elements/textbox.lua +++ b/graphics/elements/textbox.lua @@ -18,6 +18,7 @@ local TEXT_ALIGN = core.TEXT_ALIGN ---@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 +---@field hidden? boolean true to hide on initial draw -- new text box ---@param args textbox_args diff --git a/graphics/elements/tiling.lua b/graphics/elements/tiling.lua index a97438a..0dcaaf8 100644 --- a/graphics/elements/tiling.lua +++ b/graphics/elements/tiling.lua @@ -16,6 +16,7 @@ local element = require("graphics.element") ---@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 +---@field hidden? boolean true to hide on initial draw -- new tiling box ---@param args tiling_args diff --git a/pocket/startup.lua b/pocket/startup.lua index 2ea5958..9265558 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.3.2" +local POCKET_VERSION = "alpha-v0.3.3" local println = util.println local println_ts = util.println_ts diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 1a7f550..89b5b6d 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.3.2" +local R_PLC_VERSION = "v1.3.3" local println = util.println local println_ts = util.println_ts diff --git a/rtu/startup.lua b/rtu/startup.lua index 27c7c14..0994261 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.2.2" +local RTU_VERSION = "v1.2.3" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 1c3f84c..6dc7253 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -19,7 +19,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.16.2" +local SUPERVISOR_VERSION = "v0.16.3" local println = util.println local println_ts = util.println_ts From 82ab85daa54ef6dea8e7e9e78141ba1379c22912 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 25 May 2023 17:41:44 -0400 Subject: [PATCH 30/49] updated install manifest hotfix 2023.05.23 --- install_manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install_manifest.json b/install_manifest.json index 18c5137..d1b808d 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.3.1", "rtu": "v1.2.1", "supervisor": "v0.15.9", "coordinator": "v0.15.1", "pocket": "alpha-v0.3.1"}, "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/events.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/tabbar.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": 5530, "system": 1991, "common": 91102, "graphics": 129080, "lockbox": 100797, "reactor-plc": 95896, "rtu": 100982, "supervisor": 283073, "coordinator": 197508, "pocket": 36200}} \ No newline at end of file +{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.3.2", "rtu": "v1.2.2", "supervisor": "v0.15.9", "coordinator": "v0.15.2", "pocket": "alpha-v0.3.2"}, "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/events.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/tabbar.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": 5530, "system": 1991, "common": 91102, "graphics": 129460, "lockbox": 100797, "reactor-plc": 95896, "rtu": 100982, "supervisor": 283073, "coordinator": 197508, "pocket": 36200}} \ No newline at end of file From a892c0cf41c53b70519dbeb5d16f6581622f491a Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 27 May 2023 23:36:32 -0400 Subject: [PATCH 31/49] #242 create manifest.yml --- .github/workflows/manifest.yml | 61 ++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 .github/workflows/manifest.yml diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml new file mode 100644 index 0000000..29bd6b3 --- /dev/null +++ b/.github/workflows/manifest.yml @@ -0,0 +1,61 @@ +# Simple workflow for deploying static content to GitHub Pages +name: Deploy Installation Manifests + +on: + workflow_dispatch: + push: + branches: + - main + - latest + - devel + pull_request: + branches: + - main + - latest + - devel + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + # Single deploy job since we're just deploying + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup Pages + uses: actions/configure-pages@v3 + - name: Setup Python + uses: actions/setup-python@v3.1.3 + - name: Extract branch name + shell: bash + run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT + id: extract_branch + - name: Create outputs folder + shell: bash + run: mkdir temp; mkdir temp/manifests; mkdir temp/manifests/${{ steps.extract_branch.outputs.branch }} + - name: Generate manifest + run: python imgen.py + - name: Move manifest + run: mv install_manifest.json temp/manifests/${{ steps.extract_branch.outputs.branch }} + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + with: + # Upload manifest JSON + path: 'temp/' + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 From 37a91986e57de6fc03ef2deba7ac79c91d9ac7e6 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 27 May 2023 23:50:00 -0400 Subject: [PATCH 32/49] #242 updated installer for github pages manifest --- ccmsi.lua | 9 ++++++--- install_manifest.json | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) delete mode 100644 install_manifest.json diff --git a/ccmsi.lua b/ccmsi.lua index 962d5f0..8a87bfa 100644 --- a/ccmsi.lua +++ b/ccmsi.lua @@ -20,9 +20,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. local function println(message) print(tostring(message)) end local function print(message) term.write(tostring(message)) end -local CCMSI_VERSION = "v1.0" +local CCMSI_VERSION = "v1.1" local install_dir = "/.install-cache" +local manifest_path = "https://mikaylafischler.github.io/cc-mek-scada/manifests/" local repo_path = "http://raw.githubusercontent.com/MikaylaFischler/cc-mek-scada/" local opts = { ... } @@ -123,7 +124,8 @@ if mode == "check" then ------------------------- if opts[2] then repo_path = repo_path .. opts[2] .. "/" else repo_path = repo_path .. "main/" end - local install_manifest = repo_path .. "install_manifest.json" + if opts[2] then manifest_path = manifest_path .. opts[2] .. "/" else manifest_path = manifest_path .. "main/" end + local install_manifest = manifest_path .. "install_manifest.json" local response, error = http.get(install_manifest) @@ -203,7 +205,8 @@ elseif mode == "install" or mode == "update" then ------------------------- if opts[3] then repo_path = repo_path .. opts[3] .. "/" else repo_path = repo_path .. "main/" end - local install_manifest = repo_path .. "install_manifest.json" + if opts[3] then manifest_path = manifest_path .. opts[3] .. "/" else manifest_path = manifest_path .. "main/" end + local install_manifest = manifest_path .. "install_manifest.json" local response, error = http.get(install_manifest) diff --git a/install_manifest.json b/install_manifest.json deleted file mode 100644 index d1b808d..0000000 --- a/install_manifest.json +++ /dev/null @@ -1 +0,0 @@ -{"versions": {"installer": "v1.0", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.3.2", "rtu": "v1.2.2", "supervisor": "v0.15.9", "coordinator": "v0.15.2", "pocket": "alpha-v0.3.2"}, "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/events.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/tabbar.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": 5530, "system": 1991, "common": 91102, "graphics": 129460, "lockbox": 100797, "reactor-plc": 95896, "rtu": 100982, "supervisor": 283073, "coordinator": 197508, "pocket": 36200}} \ No newline at end of file From dbd74afbe6dd1f921b1a6c4267aa7bedba4001ab Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 27 May 2023 23:53:20 -0400 Subject: [PATCH 33/49] #242 update per luacheck --- ccmsi.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ccmsi.lua b/ccmsi.lua index 8a87bfa..a8fff8a 100644 --- a/ccmsi.lua +++ b/ccmsi.lua @@ -20,7 +20,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. local function println(message) print(tostring(message)) end local function print(message) term.write(tostring(message)) end -local CCMSI_VERSION = "v1.1" +local CCMSI_VERSION = "v1.2" local install_dir = "/.install-cache" local manifest_path = "https://mikaylafischler.github.io/cc-mek-scada/manifests/" @@ -123,7 +123,6 @@ if mode == "check" then -- GET REMOTE MANIFEST -- ------------------------- - if opts[2] then repo_path = repo_path .. opts[2] .. "/" else repo_path = repo_path .. "main/" end if opts[2] then manifest_path = manifest_path .. opts[2] .. "/" else manifest_path = manifest_path .. "main/" end local install_manifest = manifest_path .. "install_manifest.json" From de9cb3bd3a39aab670fca377c3decf315c8811eb Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Tue, 30 May 2023 19:51:10 -0400 Subject: [PATCH 34/49] #243 graphics core updates for content windows, redrawing, and handling of addition/removal of children --- coordinator/startup.lua | 2 +- coordinator/ui/components/processctl.lua | 2 +- coordinator/ui/components/unit_overview.lua | 2 +- coordinator/ui/layout/main_view.lua | 14 +-- graphics/element.lua | 99 +++++++++++++------ graphics/elements/animations/waiting.lua | 2 +- graphics/elements/colormap.lua | 2 +- graphics/elements/controls/hazard_button.lua | 2 +- graphics/elements/controls/multi_button.lua | 2 +- graphics/elements/controls/push_button.lua | 2 +- graphics/elements/controls/radio_button.lua | 2 +- graphics/elements/controls/sidebar.lua | 2 +- .../elements/controls/spinbox_numeric.lua | 2 +- graphics/elements/controls/switch_button.lua | 2 +- graphics/elements/controls/tabbar.lua | 2 +- graphics/elements/displaybox.lua | 2 +- graphics/elements/div.lua | 2 +- graphics/elements/indicators/alight.lua | 2 +- graphics/elements/indicators/coremap.lua | 2 +- graphics/elements/indicators/data.lua | 2 +- graphics/elements/indicators/hbar.lua | 2 +- graphics/elements/indicators/icon.lua | 2 +- graphics/elements/indicators/led.lua | 2 +- graphics/elements/indicators/ledpair.lua | 2 +- graphics/elements/indicators/ledrgb.lua | 2 +- graphics/elements/indicators/light.lua | 2 +- graphics/elements/indicators/power.lua | 2 +- graphics/elements/indicators/rad.lua | 2 +- graphics/elements/indicators/state.lua | 2 +- graphics/elements/indicators/trilight.lua | 2 +- graphics/elements/indicators/vbar.lua | 2 +- graphics/elements/multipane.lua | 2 +- graphics/elements/pipenet.lua | 2 +- graphics/elements/rectangle.lua | 2 +- graphics/elements/textbox.lua | 2 +- graphics/elements/tiling.lua | 2 +- pocket/startup.lua | 2 +- pocket/ui/components/conn_waiting.lua | 2 +- reactor-plc/startup.lua | 2 +- rtu/startup.lua | 2 +- supervisor/startup.lua | 2 +- 41 files changed, 113 insertions(+), 78 deletions(-) diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 60a0c88..17fcc6f 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.15.3" +local COORDINATOR_VERSION = "v0.15.4" local println = util.println local println_ts = util.println_ts diff --git a/coordinator/ui/components/processctl.lua b/coordinator/ui/components/processctl.lua index a238a8c..7e0016a 100644 --- a/coordinator/ui/components/processctl.lua +++ b/coordinator/ui/components/processctl.lua @@ -33,7 +33,7 @@ local period = core.flasher.PERIOD ---@param x integer top left x ---@param y integer top left y local function new_view(root, x, y) - assert(root.height() >= (y + 24), "main display not of sufficient vertical resolution (add an additional row of monitors)") + assert(root.get_height() >= (y + 24), "main display not of sufficient vertical resolution (add an additional row of monitors)") local facility = iocontrol.get_db().facility local units = iocontrol.get_db().units diff --git a/coordinator/ui/components/unit_overview.lua b/coordinator/ui/components/unit_overview.lua index bd341bf..3af8c83 100644 --- a/coordinator/ui/components/unit_overview.lua +++ b/coordinator/ui/components/unit_overview.lua @@ -38,7 +38,7 @@ local function make(parent, x, y, unit) height = 17 end - assert(parent.height() >= (y + height), "main display not of sufficient vertical resolution (add an additional row of monitors)") + assert(parent.get_height() >= (y + height), "main display not of sufficient vertical resolution (add an additional row of monitors)") -- bounding box div local root = Div{parent=parent,x=x,y=y,width=80,height=height} diff --git a/coordinator/ui/layout/main_view.lua b/coordinator/ui/layout/main_view.lua index a758b24..a7b3c86 100644 --- a/coordinator/ui/layout/main_view.lua +++ b/coordinator/ui/layout/main_view.lua @@ -32,7 +32,7 @@ local function init(main) 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} -- max length example: "01:23:45 AM - Wednesday, September 28 2022" - local datetime = TextBox{parent=main,x=(header.width()-42),y=1,text="",alignment=TEXT_ALIGN.RIGHT,width=42,height=1,fg_bg=style.header} + local datetime = TextBox{parent=main,x=(header.get_width()-42),y=1,text="",alignment=TEXT_ALIGN.RIGHT,width=42,height=1,fg_bg=style.header} ping.register(facility.ps, "sv_ping", ping.update) datetime.register(facility.ps, "date_time", datetime.set_value) @@ -45,12 +45,12 @@ local function init(main) -- unit overviews if facility.num_units >= 1 then uo_1 = unit_overview(main, 2, 3, units[1]) - row_1_height = uo_1.height() + row_1_height = uo_1.get_height() end if facility.num_units >= 2 then uo_2 = unit_overview(main, 84, 3, units[2]) - row_1_height = math.max(row_1_height, uo_2.height()) + row_1_height = math.max(row_1_height, uo_2.get_height()) end cnc_y_start = cnc_y_start + row_1_height + 1 @@ -60,11 +60,11 @@ local function init(main) local row_2_offset = cnc_y_start uo_3 = unit_overview(main, 2, row_2_offset, units[3]) - cnc_y_start = row_2_offset + uo_3.height() + 1 + cnc_y_start = row_2_offset + uo_3.get_height() + 1 if facility.num_units == 4 then uo_4 = unit_overview(main, 84, row_2_offset, units[4]) - cnc_y_start = math.max(cnc_y_start, row_2_offset + uo_4.height() + 1) + cnc_y_start = math.max(cnc_y_start, row_2_offset + uo_4.get_height() + 1) end end @@ -73,11 +73,11 @@ local function init(main) cnc_y_start = cnc_y_start -- induction matrix and process control interfaces are 24 tall + space needed for divider - local cnc_bottom_align_start = main.height() - 26 + local cnc_bottom_align_start = main.get_height() - 26 assert(cnc_bottom_align_start >= cnc_y_start, "main display not of sufficient vertical resolution (add an additional row of monitors)") - TextBox{parent=main,y=cnc_bottom_align_start,text=util.strrep("\x8c", header.width()),alignment=TEXT_ALIGN.CENTER,height=1,fg_bg=cpair(colors.lightGray,colors.gray)} + TextBox{parent=main,y=cnc_bottom_align_start,text=util.strrep("\x8c", header.get_width()),alignment=TEXT_ALIGN.CENTER,height=1,fg_bg=cpair(colors.lightGray,colors.gray)} cnc_bottom_align_start = cnc_bottom_align_start + 2 diff --git a/graphics/element.lua b/graphics/element.lua index c6dbaa7..d0e6a3b 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -68,21 +68,22 @@ function element.new(args) define_completed = false, p_window = nil, ---@type table position = { x = 1, y = 1 }, ---@type coordinate_2d - child_offset = { x = 0, y = 0 }, + child_offset = { x = 0, y = 0 }, ---@type coordinate_2d bounds = { x1 = 1, y1 = 1, x2 = 1, y2 = 1 }, ---@class element_bounds next_y = 1, - children = {}, subscriptions = {}, mt = {} } - ---@class graphics_template + ---@class graphics_base local protected = { enabled = true, - value = nil, ---@type any - window = nil, ---@type table + value = nil, ---@type any + window = nil, ---@type table + content_window = nil, ---@type table|nil fg_bg = core.cpair(colors.white, colors.black), - frame = core.gframe(1, 1, 1, 1) + frame = core.gframe(1, 1, 1, 1), + children = {} } local name_brief = "graphics.element{" .. self.elem_type .. "}: " @@ -199,15 +200,15 @@ function element.new(args) -- luacheck: push ignore ---@diagnostic disable: unused-local, unused-vararg - -- dynamically insert a child element + -- handle a child element having been added ---@param id string|integer element identifier - ---@param elem graphics_element element - function protected.insert(id, elem) + ---@param child graphics_element child element + function protected.on_added(id, child) end - -- dynamically remove a child element + -- handle a child element having been removed ---@param id string|integer element identifier - function protected.remove(id) + function protected.on_removed(id) end -- handle a mouse event @@ -280,6 +281,14 @@ function element.new(args) ---@return graphics_element element, element_id id function protected.get() return public, self.id end + -- report completion of element instantiation and get the public interface + ---@nodiscard + ---@return graphics_element element, element_id id + function protected.complete() + if args.parent ~= nil then args.parent.__child_ready(self.id, public) end + return public, self.id + end + ----------- -- SETUP -- ----------- @@ -306,11 +315,19 @@ function element.new(args) -- get the window object ---@nodiscard - function public.window() return protected.window end + function public.window() return protected.content_window or protected.window end -- delete this element (hide and unsubscribe from PSIL) function public.delete() - -- hide + stop animations + -- grab parent fg/bg so we can clear cleanly + if args.parent ~= nil then + local fg_bg = args.parent.get_fg_bg() + protected.window.setBackgroundColor(fg_bg.bkg) + protected.window.setTextColor(fg_bg.fgd) + end + + -- clear, hide, and stop animations + protected.window.clear() public.hide() -- unsubscribe from PSIL @@ -320,9 +337,9 @@ function element.new(args) end -- delete all children - for k, v in pairs(self.children) do + for k, v in pairs(protected.children) do v.delete() - self.children[k] = nil + protected.children[k] = nil end end @@ -331,7 +348,7 @@ function element.new(args) -- add a child element ---@nodiscard ---@param key string|nil id - ---@param child graphics_template + ---@param child graphics_base ---@return integer|string key function public.__add_child(key, child) -- offset first automatic placement @@ -346,26 +363,34 @@ function element.new(args) local child_element = child.get() if key == nil then - table.insert(self.children, child_element) - return #self.children + table.insert(protected.children, child_element) + return #protected.children else - self.children[key] = child_element + protected.children[key] = child_element return key end end + -- actions to take upon a child element becoming ready (initial draw/construction completed) + ---@param key string|integer id + ---@param child graphics_element + function public.__child_ready(key, child) + protected.on_added(key, child) + end + -- get a child element ---@nodiscard ---@param id element_id ---@return graphics_element - function public.get_child(id) return self.children[id] end + function public.get_child(id) return protected.children[id] end -- remove a child element ---@param id element_id function public.remove(id) - if self.children[id] ~= nil then - self.children[id].delete() - self.children[id] = nil + if protected.children[id] ~= nil then + protected.children[id].delete() + protected.children[id] = nil + protected.on_removed(id) end end @@ -374,13 +399,13 @@ function element.new(args) ---@param id element_id ---@return graphics_element|nil element function public.get_element_by_id(id) - if self.children[id] == nil then - for _, child in pairs(self.children) do + if protected.children[id] == nil then + for _, child in pairs(protected.children) do local elem = child.get_element_by_id(id) if elem ~= nil then return elem end end else - return self.children[id] + return protected.children[id] end return nil @@ -419,14 +444,14 @@ function element.new(args) -- get element width ---@nodiscard ---@return integer width - function public.width() + function public.get_width() return protected.frame.w end -- get element height ---@nodiscard ---@return integer height - function public.height() + function public.get_height() return protected.frame.h end @@ -501,7 +526,7 @@ function element.new(args) -- handle the mouse event then pass to children protected.handle_mouse(event_T) - for _, child in pairs(self.children) do child.handle_mouse(event_T) end + for _, child in pairs(protected.children) do child.handle_mouse(event_T) end end end @@ -536,7 +561,9 @@ function element.new(args) if animate ~= false then public.animate_all() end end - -- hide the element and disables animations + -- hide the element and disables animations
+ -- this alone does not cause an element to be fully hidden, it only prevents updates from being shown
+ ---@see graphics_element.content_redraw function public.hide() public.freeze_all() -- stop animations for efficiency/performance protected.window.setVisible(false) @@ -552,7 +579,7 @@ function element.new(args) function public.animate_all() if protected.window.isVisible() then public.animate() - for _, child in pairs(self.children) do child.animate_all() end + for _, child in pairs(protected.children) do child.animate_all() end end end @@ -564,7 +591,7 @@ function element.new(args) -- freeze animation(s) for this element and all its children function public.freeze_all() public.freeze() - for _, child in pairs(self.children) do child.freeze_all() end + for _, child in pairs(protected.children) do child.freeze_all() end end -- re-draw the element @@ -572,6 +599,14 @@ function element.new(args) protected.window.redraw() end + -- if a content window is set, clears it then re-draws all children + function public.content_redraw() + if protected.content_window ~= nil then + protected.content_window.clear() + for _, child in pairs(protected.children) do child.redraw() end + end + end + return protected end diff --git a/graphics/elements/animations/waiting.lua b/graphics/elements/animations/waiting.lua index 9d88c91..9dc089f 100644 --- a/graphics/elements/animations/waiting.lua +++ b/graphics/elements/animations/waiting.lua @@ -103,7 +103,7 @@ local function waiting(args) e.start_anim() - return e.get() + return e.complete() end return waiting diff --git a/graphics/elements/colormap.lua b/graphics/elements/colormap.lua index f494158..be92d83 100644 --- a/graphics/elements/colormap.lua +++ b/graphics/elements/colormap.lua @@ -28,7 +28,7 @@ local function colormap(args) e.window.setCursorPos(1, 1) e.window.blit(spaces, bkg, bkg) - return e.get() + return e.complete() end return colormap diff --git a/graphics/elements/controls/hazard_button.lua b/graphics/elements/controls/hazard_button.lua index 844a6c8..6ffe74d 100644 --- a/graphics/elements/controls/hazard_button.lua +++ b/graphics/elements/controls/hazard_button.lua @@ -199,7 +199,7 @@ local function hazard_button(args) -- initial draw of border draw_border(args.accent) - return e.get() + return e.complete() end return hazard_button diff --git a/graphics/elements/controls/multi_button.lua b/graphics/elements/controls/multi_button.lua index ca6600b..279c9a7 100644 --- a/graphics/elements/controls/multi_button.lua +++ b/graphics/elements/controls/multi_button.lua @@ -131,7 +131,7 @@ local function multi_button(args) -- initial draw draw() - return e.get() + return e.complete() end return multi_button diff --git a/graphics/elements/controls/push_button.lua b/graphics/elements/controls/push_button.lua index cfcd772..564ad3c 100644 --- a/graphics/elements/controls/push_button.lua +++ b/graphics/elements/controls/push_button.lua @@ -121,7 +121,7 @@ local function push_button(args) -- initial draw draw() - return e.get() + return e.complete() end return push_button diff --git a/graphics/elements/controls/radio_button.lua b/graphics/elements/controls/radio_button.lua index 6fc5d56..e3edf24 100644 --- a/graphics/elements/controls/radio_button.lua +++ b/graphics/elements/controls/radio_button.lua @@ -104,7 +104,7 @@ local function radio_button(args) -- initial draw draw() - return e.get() + return e.complete() end return radio_button diff --git a/graphics/elements/controls/sidebar.lua b/graphics/elements/controls/sidebar.lua index 7dae6ed..b3221b3 100644 --- a/graphics/elements/controls/sidebar.lua +++ b/graphics/elements/controls/sidebar.lua @@ -116,7 +116,7 @@ local function sidebar(args) -- initial draw draw(false) - return e.get() + return e.complete() end return sidebar diff --git a/graphics/elements/controls/spinbox_numeric.lua b/graphics/elements/controls/spinbox_numeric.lua index bcdc9e5..767d97b 100644 --- a/graphics/elements/controls/spinbox_numeric.lua +++ b/graphics/elements/controls/spinbox_numeric.lua @@ -189,7 +189,7 @@ local function spinbox(args) e.value = 0 set_digits() - return e.get() + return e.complete() end return spinbox diff --git a/graphics/elements/controls/switch_button.lua b/graphics/elements/controls/switch_button.lua index e02f506..6d2e09c 100644 --- a/graphics/elements/controls/switch_button.lua +++ b/graphics/elements/controls/switch_button.lua @@ -87,7 +87,7 @@ local function switch_button(args) draw_state() end - return e.get() + return e.complete() end return switch_button diff --git a/graphics/elements/controls/tabbar.lua b/graphics/elements/controls/tabbar.lua index e188174..da4738b 100644 --- a/graphics/elements/controls/tabbar.lua +++ b/graphics/elements/controls/tabbar.lua @@ -125,7 +125,7 @@ local function tabbar(args) -- initial draw draw() - return e.get() + return e.complete() end return tabbar diff --git a/graphics/elements/displaybox.lua b/graphics/elements/displaybox.lua index f6f520a..992f34b 100644 --- a/graphics/elements/displaybox.lua +++ b/graphics/elements/displaybox.lua @@ -17,7 +17,7 @@ local element = require("graphics.element") ---@param args displaybox_args local function displaybox(args) -- create new graphics element base object - return element.new(args).get() + return element.new(args).complete() end return displaybox diff --git a/graphics/elements/div.lua b/graphics/elements/div.lua index 53e3e84..4b6bd6a 100644 --- a/graphics/elements/div.lua +++ b/graphics/elements/div.lua @@ -19,7 +19,7 @@ local element = require("graphics.element") ---@return graphics_element element, element_id id local function div(args) -- create new graphics element base object - return element.new(args).get() + return element.new(args).complete() end return div diff --git a/graphics/elements/indicators/alight.lua b/graphics/elements/indicators/alight.lua index 2d933d6..ff9b1ad 100644 --- a/graphics/elements/indicators/alight.lua +++ b/graphics/elements/indicators/alight.lua @@ -109,7 +109,7 @@ local function alarm_indicator_light(args) e.on_update(1) e.window.write(args.label) - return e.get() + return e.complete() end return alarm_indicator_light diff --git a/graphics/elements/indicators/coremap.lua b/graphics/elements/indicators/coremap.lua index 05434a3..127a8a3 100644 --- a/graphics/elements/indicators/coremap.lua +++ b/graphics/elements/indicators/coremap.lua @@ -163,7 +163,7 @@ local function core_map(args) -- initial draw e.on_update(0) - return e.get() + return e.complete() end return core_map diff --git a/graphics/elements/indicators/data.lua b/graphics/elements/indicators/data.lua index a2b4ea9..6aa052a 100644 --- a/graphics/elements/indicators/data.lua +++ b/graphics/elements/indicators/data.lua @@ -97,7 +97,7 @@ local function data(args) -- initial value draw e.on_update(args.value) - return e.get() + return e.complete() end return data diff --git a/graphics/elements/indicators/hbar.lua b/graphics/elements/indicators/hbar.lua index f69374e..9bee59f 100644 --- a/graphics/elements/indicators/hbar.lua +++ b/graphics/elements/indicators/hbar.lua @@ -120,7 +120,7 @@ local function hbar(args) -- initialize to 0 e.on_update(0) - return e.get() + return e.complete() end return hbar diff --git a/graphics/elements/indicators/icon.lua b/graphics/elements/indicators/icon.lua index f079178..03c88fb 100644 --- a/graphics/elements/indicators/icon.lua +++ b/graphics/elements/indicators/icon.lua @@ -69,7 +69,7 @@ local function icon(args) -- initial icon draw e.on_update(args.value or 1) - return e.get() + return e.complete() end return icon diff --git a/graphics/elements/indicators/led.lua b/graphics/elements/indicators/led.lua index 6a6f829..077cab3 100644 --- a/graphics/elements/indicators/led.lua +++ b/graphics/elements/indicators/led.lua @@ -95,7 +95,7 @@ local function indicator_led(args) e.window.write(args.label) end - return e.get() + return e.complete() end return indicator_led diff --git a/graphics/elements/indicators/ledpair.lua b/graphics/elements/indicators/ledpair.lua index 94e6955..47c9a0a 100644 --- a/graphics/elements/indicators/ledpair.lua +++ b/graphics/elements/indicators/ledpair.lua @@ -109,7 +109,7 @@ local function indicator_led_pair(args) e.window.write(args.label) end - return e.get() + return e.complete() end return indicator_led_pair diff --git a/graphics/elements/indicators/ledrgb.lua b/graphics/elements/indicators/ledrgb.lua index b66d102..dbcb947 100644 --- a/graphics/elements/indicators/ledrgb.lua +++ b/graphics/elements/indicators/ledrgb.lua @@ -54,7 +54,7 @@ local function indicator_led_rgb(args) e.window.write(args.label) end - return e.get() + return e.complete() end return indicator_led_rgb diff --git a/graphics/elements/indicators/light.lua b/graphics/elements/indicators/light.lua index 8213439..d4e8b09 100644 --- a/graphics/elements/indicators/light.lua +++ b/graphics/elements/indicators/light.lua @@ -93,7 +93,7 @@ local function indicator_light(args) e.window.setCursorPos(3, 1) e.window.write(args.label) - return e.get() + return e.complete() end return indicator_light diff --git a/graphics/elements/indicators/power.lua b/graphics/elements/indicators/power.lua index b7137d7..323fe58 100644 --- a/graphics/elements/indicators/power.lua +++ b/graphics/elements/indicators/power.lua @@ -80,7 +80,7 @@ local function power(args) -- initial value draw e.on_update(args.value) - return e.get() + return e.complete() end return power diff --git a/graphics/elements/indicators/rad.lua b/graphics/elements/indicators/rad.lua index c843cf4..fc89044 100644 --- a/graphics/elements/indicators/rad.lua +++ b/graphics/elements/indicators/rad.lua @@ -85,7 +85,7 @@ local function rad(args) -- initial value draw e.on_update(types.new_zero_radiation_reading()) - return e.get() + return e.complete() end return rad diff --git a/graphics/elements/indicators/state.lua b/graphics/elements/indicators/state.lua index 3bb2831..d0e57b5 100644 --- a/graphics/elements/indicators/state.lua +++ b/graphics/elements/indicators/state.lua @@ -75,7 +75,7 @@ local function state_indicator(args) -- initial draw e.on_update(args.value or 1) - return e.get() + return e.complete() end return state_indicator diff --git a/graphics/elements/indicators/trilight.lua b/graphics/elements/indicators/trilight.lua index bbc7526..ef8a8b6 100644 --- a/graphics/elements/indicators/trilight.lua +++ b/graphics/elements/indicators/trilight.lua @@ -106,7 +106,7 @@ local function tristate_indicator_light(args) e.on_update(1) e.window.write(args.label) - return e.get() + return e.complete() end return tristate_indicator_light diff --git a/graphics/elements/indicators/vbar.lua b/graphics/elements/indicators/vbar.lua index 9c8a8f4..4cfb6e7 100644 --- a/graphics/elements/indicators/vbar.lua +++ b/graphics/elements/indicators/vbar.lua @@ -100,7 +100,7 @@ local function vbar(args) ---@param val number 0.0 to 1.0 function e.set_value(val) e.on_update(val) end - return e.get() + return e.complete() end return vbar diff --git a/graphics/elements/multipane.lua b/graphics/elements/multipane.lua index 20da7ed..790b595 100644 --- a/graphics/elements/multipane.lua +++ b/graphics/elements/multipane.lua @@ -37,7 +37,7 @@ local function multipane(args) e.set_value(1) - return e.get() + return e.complete() end return multipane diff --git a/graphics/elements/pipenet.lua b/graphics/elements/pipenet.lua index 8314fd2..5ca4745 100644 --- a/graphics/elements/pipenet.lua +++ b/graphics/elements/pipenet.lua @@ -142,7 +142,7 @@ local function pipenet(args) end - return e.get() + return e.complete() end return pipenet diff --git a/graphics/elements/rectangle.lua b/graphics/elements/rectangle.lua index b80b37c..72f9739 100644 --- a/graphics/elements/rectangle.lua +++ b/graphics/elements/rectangle.lua @@ -178,7 +178,7 @@ local function rectangle(args) end end - return e.get() + return e.complete() end return rectangle diff --git a/graphics/elements/textbox.lua b/graphics/elements/textbox.lua index 6e5717f..e72571b 100644 --- a/graphics/elements/textbox.lua +++ b/graphics/elements/textbox.lua @@ -65,7 +65,7 @@ local function textbox(args) display_text(val) end - return e.get() + return e.complete() end return textbox diff --git a/graphics/elements/tiling.lua b/graphics/elements/tiling.lua index 0dcaaf8..536ed45 100644 --- a/graphics/elements/tiling.lua +++ b/graphics/elements/tiling.lua @@ -82,7 +82,7 @@ local function tiling(args) if inner_width % 2 == 0 then alternator = not alternator end end - return e.get() + return e.complete() end return tiling diff --git a/pocket/startup.lua b/pocket/startup.lua index 9265558..c1a924c 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.3.3" +local POCKET_VERSION = "alpha-v0.3.4" local println = util.println local println_ts = util.println_ts diff --git a/pocket/ui/components/conn_waiting.lua b/pocket/ui/components/conn_waiting.lua index 9bbbfc0..114d165 100644 --- a/pocket/ui/components/conn_waiting.lua +++ b/pocket/ui/components/conn_waiting.lua @@ -25,7 +25,7 @@ local function init(parent, y, is_api) -- bounding box div local box = Div{parent=root,x=1,y=y,height=5} - local waiting_x = math.floor(parent.width() / 2) - 1 + local waiting_x = math.floor(parent.get_width() / 2) - 1 if is_api then WaitingAnim{parent=box,x=waiting_x,y=1,fg_bg=cpair(colors.blue,style.root.bkg)} diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 89b5b6d..687c022 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.3.3" +local R_PLC_VERSION = "v1.3.4" local println = util.println local println_ts = util.println_ts diff --git a/rtu/startup.lua b/rtu/startup.lua index 0994261..c7f3a66 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.2.3" +local RTU_VERSION = "v1.2.4" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 6dc7253..cf7c8fe 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -19,7 +19,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.16.3" +local SUPERVISOR_VERSION = "v0.16.4" local println = util.println local println_ts = util.println_ts From 4c35233289c52a847a25227d7dbc97f3805b30cd Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Tue, 30 May 2023 20:43:33 -0400 Subject: [PATCH 35/49] #243 changed rectangle to use content window, significant simplification of offset logic, improved delete rendering --- coordinator/startup.lua | 2 +- graphics/element.lua | 47 ++++++++------------------------ graphics/elements/displaybox.lua | 2 ++ graphics/elements/rectangle.lua | 18 ++++++++---- pocket/startup.lua | 2 +- reactor-plc/startup.lua | 2 +- rtu/startup.lua | 2 +- supervisor/startup.lua | 2 +- 8 files changed, 31 insertions(+), 46 deletions(-) diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 17fcc6f..0faf0fb 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.15.4" +local COORDINATOR_VERSION = "v0.15.5" local println = util.println local println_ts = util.println_ts diff --git a/graphics/element.lua b/graphics/element.lua index d0e6a3b..a775eb7 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -12,8 +12,6 @@ local element = {} ---@field id? string element id ---@field x? integer 1 if omitted ---@field y? integer next line if omitted ----@field offset_x? integer 0 if omitted ----@field offset_y? integer 0 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 @@ -103,10 +101,8 @@ function element.new(args) ------------------------- -- prepare the template - ---@param offset_x integer x offset - ---@param offset_y integer y offset ---@param next_y integer next line if no y was provided - function protected.prepare_template(offset_x, offset_y, next_y) + function protected.prepare_template(next_y) -- get frame coordinates/size if args.gframe ~= nil then protected.frame.x = args.gframe.x @@ -116,36 +112,18 @@ function element.new(args) else local w, h = self.p_window.getSize() protected.frame.x = args.x or 1 - - if args.parent ~= nil then - protected.frame.y = args.y or (next_y - offset_y) - else protected.frame.y = args.y or next_y - end - protected.frame.w = args.width or w protected.frame.h = args.height or h end - -- inner offsets - if args.offset_x ~= nil then self.child_offset.x = args.offset_x end - if args.offset_y ~= nil then self.child_offset.y = args.offset_y end - -- adjust window frame if applicable local f = protected.frame - local x = f.x - local y = f.y - - -- apply offsets if args.parent ~= nil then -- constrain to parent inner width/height local w, h = self.p_window.getSize() - f.w = math.min(f.w, w - ((2 * offset_x) + (f.x - 1))) - f.h = math.min(f.h, h - ((2 * offset_y) + (f.y - 1))) - - -- offset x/y - f.x = x + offset_x - f.y = y + offset_y + f.w = math.min(f.w, w - (f.x - 1)) + f.h = math.min(f.h, h - (f.y - 1)) end -- check frame @@ -304,7 +282,7 @@ function element.new(args) -- prepare the template if args.parent == nil then - protected.prepare_template(0, 0, 1) + protected.prepare_template(1) else self.id = args.parent.__add_child(args.id, protected) end @@ -319,14 +297,16 @@ function element.new(args) -- delete this element (hide and unsubscribe from PSIL) function public.delete() - -- grab parent fg/bg so we can clear cleanly + local fg_bg = protected.fg_bg + if args.parent ~= nil then - local fg_bg = args.parent.get_fg_bg() - protected.window.setBackgroundColor(fg_bg.bkg) - protected.window.setTextColor(fg_bg.fgd) + -- grab parent fg/bg so we can clear cleanly as a child element + fg_bg = args.parent.get_fg_bg() end -- clear, hide, and stop animations + protected.window.setBackgroundColor(fg_bg.bkg) + protected.window.setTextColor(fg_bg.fgd) protected.window.clear() public.hide() @@ -351,12 +331,7 @@ function element.new(args) ---@param child graphics_base ---@return integer|string key function public.__add_child(key, child) - -- offset first automatic placement - if self.next_y <= self.child_offset.y then - self.next_y = self.child_offset.y + 1 - end - - child.prepare_template(self.child_offset.x, self.child_offset.y, self.next_y) + child.prepare_template(self.next_y) self.next_y = child.frame.y + child.frame.h diff --git a/graphics/elements/displaybox.lua b/graphics/elements/displaybox.lua index 992f34b..3578a63 100644 --- a/graphics/elements/displaybox.lua +++ b/graphics/elements/displaybox.lua @@ -4,6 +4,7 @@ local element = require("graphics.element") ---@class displaybox_args ---@field window table +---@field id? string element id ---@field x? integer 1 if omitted ---@field y? integer 1 if omitted ---@field width? integer parent width if omitted @@ -15,6 +16,7 @@ local element = require("graphics.element") -- new root display box ---@nodiscard ---@param args displaybox_args +---@return graphics_element element, element_id id local function displaybox(args) -- create new graphics element base object return element.new(args).complete() diff --git a/graphics/elements/rectangle.lua b/graphics/elements/rectangle.lua index 72f9739..cd4b8cf 100644 --- a/graphics/elements/rectangle.lua +++ b/graphics/elements/rectangle.lua @@ -31,27 +31,35 @@ local function rectangle(args) end -- offset children + local offset_x = 0 + local offset_y = 0 if args.border ~= nil then - args.offset_x = args.border.width - args.offset_y = args.border.width + offset_x = args.border.width + offset_y = args.border.width -- slightly different y offset if the border is set to even if args.border.even then local width_x2 = (2 * args.border.width) - args.offset_y = math.floor(width_x2 / 3) + util.trinary(width_x2 % 3 > 0, 1, 0) + offset_y = math.floor(width_x2 / 3) + util.trinary(width_x2 % 3 > 0, 1, 0) end end -- create new graphics element base object local e = element.new(args) + -- create content window for child elements + e.content_window = window.create(e.window, 1 + offset_x, 1 + offset_y, e.frame.w - (2 * offset_x), e.frame.h - (2 * offset_y)) + e.content_window.setBackgroundColor(e.fg_bg.bkg) + e.content_window.setTextColor(e.fg_bg.fgd) + e.content_window.clear() + -- draw bordered box if requested -- element constructor will have drawn basic colored rectangle regardless if args.border ~= nil then e.window.setCursorPos(1, 1) - local border_width = args.offset_x - local border_height = args.offset_y + local border_width = offset_x + local border_height = offset_y local border_blit = colors.toBlit(args.border.color) local width_x2 = border_width * 2 local inner_width = e.frame.w - width_x2 diff --git a/pocket/startup.lua b/pocket/startup.lua index c1a924c..2a48042 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.3.4" +local POCKET_VERSION = "alpha-v0.3.5" local println = util.println local println_ts = util.println_ts diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 687c022..cf3b08a 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.3.4" +local R_PLC_VERSION = "v1.3.5" local println = util.println local println_ts = util.println_ts diff --git a/rtu/startup.lua b/rtu/startup.lua index c7f3a66..1ae38ed 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.2.4" +local RTU_VERSION = "v1.2.5" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE diff --git a/supervisor/startup.lua b/supervisor/startup.lua index cf7c8fe..6e2dd95 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -19,7 +19,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.16.4" +local SUPERVISOR_VERSION = "v0.16.5" local println = util.println local println_ts = util.println_ts From deec1ff1df61fd205f77a6f1b1c89b2af02ff0c8 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 31 May 2023 11:15:55 -0400 Subject: [PATCH 36/49] fix shields deploy --- .github/workflows/manifest.yml | 21 ++++++++------- .github/workflows/shields.yml | 47 ---------------------------------- imgen.py | 4 +-- 3 files changed, 12 insertions(+), 60 deletions(-) delete mode 100644 .github/workflows/shields.yml diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml index 29bd6b3..0d7d175 100644 --- a/.github/workflows/manifest.yml +++ b/.github/workflows/manifest.yml @@ -1,5 +1,5 @@ # Simple workflow for deploying static content to GitHub Pages -name: Deploy Installation Manifests +name: Deploy Installation Manifests and Component Versions on: workflow_dispatch: @@ -8,11 +8,6 @@ on: - main - latest - devel - pull_request: - branches: - - main - - latest - - devel # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages permissions: @@ -46,16 +41,20 @@ jobs: id: extract_branch - name: Create outputs folder shell: bash - run: mkdir temp; mkdir temp/manifests; mkdir temp/manifests/${{ steps.extract_branch.outputs.branch }} + run: mkdir deploy; mkdir deploy/manifests; mkdir temp/manifests/${{ steps.extract_branch.outputs.branch }} + - name: Generate manifest and shields for master + if: github.event.pull_request.base.ref == 'master' + run: python imgen.py gh_actions - name: Generate manifest - run: python imgen.py + if: github.event.pull_request.base.ref != 'master' + run: python imgen.p - name: Move manifest - run: mv install_manifest.json temp/manifests/${{ steps.extract_branch.outputs.branch }} - - name: Upload artifact + run: mv install_manifest.json deploy/manifests/${{ steps.extract_branch.outputs.branch }} + - name: Upload artifacts uses: actions/upload-pages-artifact@v1 with: # Upload manifest JSON - path: 'temp/' + path: 'deploy/' - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v2 diff --git a/.github/workflows/shields.yml b/.github/workflows/shields.yml deleted file mode 100644 index 50698af..0000000 --- a/.github/workflows/shields.yml +++ /dev/null @@ -1,47 +0,0 @@ -# Simple workflow for deploying static content to GitHub Pages -name: Deploy Component Versions - -on: - # Runs on pushes targeting the default branch - push: - branches: ["main"] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - # Single deploy job since we're just deploying - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Setup Pages - uses: actions/configure-pages@v3 - - name: Setup Python - uses: actions/setup-python@v3.1.3 - - run: mkdir shields - - run: python imgen.py shields - - name: Upload artifact - uses: actions/upload-pages-artifact@v1 - with: - # Upload 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 9a1e194..e52543c 100644 --- a/imgen.py +++ b/imgen.py @@ -108,10 +108,10 @@ f = open("install_manifest.json", "w") json.dump(final_manifest, f) f.close() -if len(sys.argv) > 1 and sys.argv[1] == "shields": +if len(sys.argv) > 1 and sys.argv[1] == "gh_actions": # write all the JSON files for shields.io for key, version in final_manifest["versions"].items(): - f = open("./shields/" + key + ".json", "w") + f = open("./deploy/" + key + ".json", "w") if version.find("alpha") >= 0: color = "yellow" From 494dc437a5ee77b3d9dcb30b2fea0c0a7daec341 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 31 May 2023 11:16:56 -0400 Subject: [PATCH 37/49] fixed error in manifest.yml --- .github/workflows/manifest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml index 0d7d175..0013626 100644 --- a/.github/workflows/manifest.yml +++ b/.github/workflows/manifest.yml @@ -41,7 +41,7 @@ jobs: id: extract_branch - name: Create outputs folder shell: bash - run: mkdir deploy; mkdir deploy/manifests; mkdir temp/manifests/${{ steps.extract_branch.outputs.branch }} + run: mkdir deploy; mkdir deploy/manifests; mkdir deploy/manifests/${{ steps.extract_branch.outputs.branch }} - name: Generate manifest and shields for master if: github.event.pull_request.base.ref == 'master' run: python imgen.py gh_actions From 86ad2a10690ed23aa088df20a53a1fa9d672ce66 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 31 May 2023 11:17:44 -0400 Subject: [PATCH 38/49] fixed a typo in manifest.yml --- .github/workflows/manifest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml index 0013626..10b4b33 100644 --- a/.github/workflows/manifest.yml +++ b/.github/workflows/manifest.yml @@ -47,7 +47,7 @@ jobs: run: python imgen.py gh_actions - name: Generate manifest if: github.event.pull_request.base.ref != 'master' - run: python imgen.p + run: python imgen.py - name: Move manifest run: mv install_manifest.json deploy/manifests/${{ steps.extract_branch.outputs.branch }} - name: Upload artifacts From 8f2e9fe31931a542786d71f6fd5662bc00166d00 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 31 May 2023 11:19:32 -0400 Subject: [PATCH 39/49] more manifest.yml fixes --- .github/workflows/manifest.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml index 10b4b33..d96b93e 100644 --- a/.github/workflows/manifest.yml +++ b/.github/workflows/manifest.yml @@ -1,5 +1,5 @@ # Simple workflow for deploying static content to GitHub Pages -name: Deploy Installation Manifests and Component Versions +name: Deploy Installation Manifests and Versions on: workflow_dispatch: @@ -42,11 +42,11 @@ jobs: - name: Create outputs folder shell: bash run: mkdir deploy; mkdir deploy/manifests; mkdir deploy/manifests/${{ steps.extract_branch.outputs.branch }} - - name: Generate manifest and shields for master - if: github.event.pull_request.base.ref == 'master' + - name: Generate manifest and shields for main branch + if: github.event.pull_request.base.ref == 'main' run: python imgen.py gh_actions - - name: Generate manifest - if: github.event.pull_request.base.ref != 'master' + - name: Generate only manifest for non-main branches + if: github.event.pull_request.base.ref != 'main' run: python imgen.py - name: Move manifest run: mv install_manifest.json deploy/manifests/${{ steps.extract_branch.outputs.branch }} From ef1ec220a40ea05fdeccd7dc0af7c6957e7bcf2f Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Wed, 31 May 2023 11:44:41 -0400 Subject: [PATCH 40/49] #184 initial draft of listbox element and associated supervisor front panel test example --- graphics/element.lua | 4 +- graphics/elements/listbox.lua | 190 +++++++++++++++++++++++++++++++ supervisor/panel/front_panel.lua | 17 ++- 3 files changed, 204 insertions(+), 7 deletions(-) create mode 100644 graphics/elements/listbox.lua diff --git a/graphics/element.lua b/graphics/element.lua index a775eb7..bfeb0a5 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -45,6 +45,7 @@ local element = {} ---|colormap_args ---|displaybox_args ---|div_args +---|listbox_args ---|multipane_args ---|pipenet_args ---|rectangle_args @@ -66,7 +67,6 @@ function element.new(args) define_completed = false, p_window = nil, ---@type table position = { x = 1, y = 1 }, ---@type coordinate_2d - child_offset = { x = 0, y = 0 }, ---@type coordinate_2d bounds = { x1 = 1, y1 = 1, x2 = 1, y2 = 1 }, ---@class element_bounds next_y = 1, subscriptions = {}, @@ -112,7 +112,7 @@ function element.new(args) else local w, h = self.p_window.getSize() protected.frame.x = args.x or 1 - protected.frame.y = args.y or next_y + protected.frame.y = args.y or next_y protected.frame.w = args.width or w protected.frame.h = args.height or h end diff --git a/graphics/elements/listbox.lua b/graphics/elements/listbox.lua new file mode 100644 index 0000000..105c3ee --- /dev/null +++ b/graphics/elements/listbox.lua @@ -0,0 +1,190 @@ +-- Scroll-able List Box Display Graphics Element + +-- local log = require("scada-common.log") + +local core = require("graphics.core") +local element = require("graphics.element") + +local CLICK_TYPE = core.events.CLICK_TYPE + +---@class listbox_args +---@field scroll_height integer height of internal scrolling container (must fit all elements vertically tiled) +---@field item_pad? integer spacing (lines) between items in the list (default 0) +---@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 +---@field hidden? boolean true to hide on initial draw + +---@class listbox_item +---@field id string|integer element ID +---@field e graphics_element element +---@field y integer y position +---@field h integer element height + +-- new listbox element +---@nodiscard +---@param args listbox_args +---@return graphics_element element, element_id id +local function listbox(args) + -- create new graphics element base object + local e = element.new(args) + + -- create content window for child elements + local scroll_frame = window.create(e.window, 1, 1, e.frame.w - 1, args.scroll_height, false) + e.content_window = scroll_frame + + -- item list and scroll management + local list = {} + local item_pad = args.item_pad or 0 + local scroll_offset = 0 + local content_height = 0 + local max_down_scroll = 0 + + -- bar control/tracking variables + local bar_height = 0 -- full height of bar + local bar_bounds = { 0, 0 } -- top and bottom of bar + local holding_bar = false -- bar is being held by mouse + local bar_grip_pos = 0 -- where the bar was gripped by mouse down + local mouse_last_y = 0 -- last reported y coordinate of drag + + -- draw up/down arrows + e.window.setCursorPos(e.frame.w, 1) + e.window.write("\x1e") + e.window.setCursorPos(e.frame.w, e.frame.h) + e.window.write("\x1f") + + -- render the scroll bar and re-cacluate height & bounds + local function draw_bar() + local offset = 2 + math.abs(scroll_offset) + + bar_height = math.max(math.min(e.frame.h - 2 + max_down_scroll, e.frame.h - 2), 1) + bar_bounds = { offset, (bar_height + offset) - 1 } + + for i = 2, e.frame.h - 1 do + if i >= offset and i < (bar_height + offset) then + e.window.setBackgroundColor(e.fg_bg.fgd) + else + e.window.setBackgroundColor(e.fg_bg.bkg) + end + + e.window.setCursorPos(e.frame.w, i) + e.window.write(" ") + end + + e.window.setBackgroundColor(e.fg_bg.bkg) + end + + -- update item y positions and move elements + local function update_positions() + local next_y = 1 + + scroll_frame.setVisible(false) + scroll_frame.setBackgroundColor(e.fg_bg.bkg) + scroll_frame.setTextColor(e.fg_bg.fgd) + scroll_frame.clear() + + for i = 1, #list do + local item = list[i] ---@type listbox_item + item.y = next_y + next_y = next_y + item.h + item_pad + item.e.reposition(1, item.y) + item.e.show() + end + + content_height = next_y + max_down_scroll = math.min(-1 * (content_height - (e.frame.h + 1 + item_pad)), 0) + if scroll_offset < max_down_scroll then scroll_offset = max_down_scroll end + + scroll_frame.reposition(1, 1 + scroll_offset) + scroll_frame.setVisible(true) + + draw_bar() + + -- log.info("content_height[" .. content_height .. "] max_down_scroll[" .. max_down_scroll .. "] scroll_offset[" .. scroll_offset .. "] bar_height[" .. bar_height .. "]") + end + + -- scroll down the list + local function scroll_down() + if scroll_offset > max_down_scroll then + scroll_offset = scroll_offset - 1 + update_positions() + end + end + + -- scroll up the list + local function scroll_up() + if scroll_offset < 0 then + scroll_offset = scroll_offset + 1 + update_positions() + end + end + + -- handle a child element having been added to the list + ---@param id string|integer element identifier + ---@param child graphics_element child element + function e.on_added(id, child) + table.insert(list, { id = id, e = child, y = 0, h = child.get_height() }) + update_positions() + end + + -- handle a child element having been removed from the list + ---@param id string|integer element identifier + function e.on_removed(id) + for idx, elem in ipairs(list) do + if elem.id == id then + table.remove(list, idx) + update_positions() + return + end + end + end + + -- handle mouse interaction + ---@param event mouse_interaction mouse event + function e.handle_mouse(event) + if e.enabled then + if event.type == CLICK_TYPE.TAP or event.type == CLICK_TYPE.DOWN then + if event.current.x == e.frame.w then + if event.current.y == 1 or event.current.y < bar_bounds[1] then + scroll_up() + elseif event.current.y == e.frame.h or event.current.y > bar_bounds[2] then + scroll_down() + else + -- clicked on bar + holding_bar = true + bar_grip_pos = event.current.y - bar_bounds[1] + mouse_last_y = event.current.y + end + end + elseif event.type == CLICK_TYPE.UP then + holding_bar = false + elseif event.type == CLICK_TYPE.DRAG then + if holding_bar then + -- if mouse is within vertical frame, including the grip point + if event.current.y > (1 + bar_grip_pos) and event.current.y <= ((e.frame.h - bar_height) + bar_grip_pos) then + if event.current.y < mouse_last_y then + scroll_up() + elseif event.current.y > mouse_last_y then + scroll_down() + end + + mouse_last_y = event.current.y + end + end + elseif event.type == CLICK_TYPE.SCROLL_DOWN then + scroll_down() + elseif event.type == CLICK_TYPE.SCROLL_UP then + scroll_up() + end + end + end + + return e.complete() +end + +return listbox diff --git a/supervisor/panel/front_panel.lua b/supervisor/panel/front_panel.lua index bf95c6b..940a116 100644 --- a/supervisor/panel/front_panel.lua +++ b/supervisor/panel/front_panel.lua @@ -74,7 +74,7 @@ local function init(panel) -- plc page - local plc_page = Div{parent=page_div,x=1,y=1} + local plc_page = Div{parent=page_div,x=1,y=1,hidden=true} local plc_list = Div{parent=plc_page,x=2,y=2,width=49} for i = 1, config.NUM_REACTORS do @@ -106,12 +106,19 @@ local function init(panel) -- rtu page - local rtu_page = Div{parent=page_div,x=1,y=1} - local rtu_list = Div{parent=rtu_page,x=2,y=2,width=49} + local rtu_page = Div{parent=page_div,x=1,y=1,hidden=true} + local rtu_list = ListBox{parent=rtu_page,x=2,y=2,height=15,width=49,scroll_height=1000,item_pad=1,fg_bg=cpair(colors.black,colors.white)} + + local item_1 = Div{parent=rtu_list,height=3,fg_bg=cpair(colors.black,colors.red),hidden=true} + local item_2 = Div{parent=rtu_list,height=3,fg_bg=cpair(colors.black,colors.orange),hidden=true} + local item_3 = Div{parent=rtu_list,height=3,fg_bg=cpair(colors.black,colors.yellow),hidden=true} + local item_4 = Div{parent=rtu_list,height=3,fg_bg=cpair(colors.black,colors.green),hidden=true} + local item_5 = Div{parent=rtu_list,height=3,fg_bg=cpair(colors.black,colors.blue),hidden=true} + local item_6 = Div{parent=rtu_list,height=3,fg_bg=cpair(colors.black,colors.purple),hidden=true} -- coordinator page - local crd_page = Div{parent=page_div,x=1,y=1} + local crd_page = Div{parent=page_div,x=1,y=1,hidden=true} local crd_box = Div{parent=crd_page,x=2,y=2,width=49,height=4,fg_bg=cpair(colors.black,colors.white)} local crd_conn = LED{parent=crd_box,x=2,y=2,label="CONNECTION",colors=cpair(colors.green,colors.green_off)} @@ -133,7 +140,7 @@ local function init(panel) -- pocket page - local pkt_page = Div{parent=page_div,x=1,y=1} + local pkt_page = Div{parent=page_div,x=1,y=1,hidden=true} local pkt_box = Div{parent=pkt_page,x=2,y=2,width=49} local panes = { main_page, plc_page, rtu_page, crd_page, pkt_page } From 153a83e5693557a253acb87ebafa634297ba0d8f Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Thu, 1 Jun 2023 13:00:45 -0400 Subject: [PATCH 41/49] listbox improvements --- graphics/element.lua | 22 +++-- graphics/elements/listbox.lua | 149 +++++++++++++++++++++++++++------- 2 files changed, 138 insertions(+), 33 deletions(-) diff --git a/graphics/element.lua b/graphics/element.lua index bfeb0a5..d537171 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -62,7 +62,7 @@ local element = {} ---@param args graphics_args arguments function element.new(args) local self = { - id = -1, + id = nil, ---@type element_id|nil elem_type = debug.getinfo(2).name, define_completed = false, p_window = nil, ---@type table @@ -179,13 +179,13 @@ function element.new(args) ---@diagnostic disable: unused-local, unused-vararg -- handle a child element having been added - ---@param id string|integer element identifier + ---@param id element_id element identifier ---@param child graphics_element child element function protected.on_added(id, child) end -- handle a child element having been removed - ---@param id string|integer element identifier + ---@param id element_id element identifier function protected.on_removed(id) end @@ -282,6 +282,7 @@ function element.new(args) -- prepare the template if args.parent == nil then + self.id = args.id or "__ROOT__" protected.prepare_template(1) else self.id = args.parent.__add_child(args.id, protected) @@ -321,6 +322,8 @@ function element.new(args) v.delete() protected.children[k] = nil end + + args.parent.__remove_child(self.id) end -- ELEMENT TREE -- @@ -346,8 +349,17 @@ function element.new(args) end end + -- remove a child element + ---@param key element_id id + function public.__remove_child(key) + if protected.children[key] ~= nil then + protected.on_removed(key) + protected.children[key] = nil + end + end + -- actions to take upon a child element becoming ready (initial draw/construction completed) - ---@param key string|integer id + ---@param key element_id id ---@param child graphics_element function public.__child_ready(key, child) protected.on_added(key, child) @@ -364,8 +376,8 @@ function element.new(args) function public.remove(id) if protected.children[id] ~= nil then protected.children[id].delete() - protected.children[id] = nil protected.on_removed(id) + protected.children[id] = nil end end diff --git a/graphics/elements/listbox.lua b/graphics/elements/listbox.lua index 105c3ee..a5d5f20 100644 --- a/graphics/elements/listbox.lua +++ b/graphics/elements/listbox.lua @@ -1,6 +1,6 @@ -- Scroll-able List Box Display Graphics Element --- local log = require("scada-common.log") +local tcd = require("scada-common.tcallbackdsp") local core = require("graphics.core") local element = require("graphics.element") @@ -10,6 +10,8 @@ local CLICK_TYPE = core.events.CLICK_TYPE ---@class listbox_args ---@field scroll_height integer height of internal scrolling container (must fit all elements vertically tiled) ---@field item_pad? integer spacing (lines) between items in the list (default 0) +---@field nav_fg_bg? cpair foreground/background colors for scroll arrows and bar area +---@field nav_active? cpair active colors for bar held down or arrow held down ---@field parent graphics_element ---@field id? string element id ---@field x? integer 1 if omitted @@ -39,37 +41,90 @@ local function listbox(args) e.content_window = scroll_frame -- item list and scroll management - local list = {} - local item_pad = args.item_pad or 0 - local scroll_offset = 0 - local content_height = 0 + local list = {} + local item_pad = args.item_pad or 0 + local scroll_offset = 0 + local content_height = 0 local max_down_scroll = 0 - -- bar control/tracking variables - local bar_height = 0 -- full height of bar - local bar_bounds = { 0, 0 } -- top and bottom of bar - local holding_bar = false -- bar is being held by mouse - local bar_grip_pos = 0 -- where the bar was gripped by mouse down - local mouse_last_y = 0 -- last reported y coordinate of drag + local max_bar_height = e.frame.h - 2 + local bar_height = 0 -- full height of bar + local bar_bounds = { 0, 0 } -- top and bottom of bar + local bar_is_scaled = false -- if the scrollbar doesn't have a 1:1 ratio with lines + local holding_bar = false -- bar is being held by mouse + local bar_grip_pos = 0 -- where the bar was gripped by mouse down + local mouse_last_y = 0 -- last reported y coordinate of drag - -- draw up/down arrows - e.window.setCursorPos(e.frame.w, 1) - e.window.write("\x1e") - e.window.setCursorPos(e.frame.w, e.frame.h) - e.window.write("\x1f") + -- draw scroll bar arrows, optionally showing one of them as pressed + ---@param pressed_arrow? integer arrow to show as pressed (1 = scroll up, 0 = neither, -1 = scroll down) + local function draw_arrows(pressed_arrow) + local nav_fg_bg = args.nav_fg_bg or e.fg_bg + local active_fg_bg = args.nav_active or nav_fg_bg + + -- draw up/down arrows + if pressed_arrow == 1 then + e.window.setTextColor(active_fg_bg.fgd) + e.window.setBackgroundColor(active_fg_bg.bkg) + e.window.setCursorPos(e.frame.w, 1) + e.window.write("\x1e") + e.window.setTextColor(nav_fg_bg.fgd) + e.window.setBackgroundColor(nav_fg_bg.bkg) + e.window.setCursorPos(e.frame.w, e.frame.h) + e.window.write("\x1f") + elseif pressed_arrow == -1 then + e.window.setTextColor(nav_fg_bg.fgd) + e.window.setBackgroundColor(nav_fg_bg.bkg) + e.window.setCursorPos(e.frame.w, 1) + e.window.write("\x1e") + e.window.setTextColor(active_fg_bg.fgd) + e.window.setBackgroundColor(active_fg_bg.bkg) + e.window.setCursorPos(e.frame.w, e.frame.h) + e.window.write("\x1f") + else + e.window.setTextColor(nav_fg_bg.fgd) + e.window.setBackgroundColor(nav_fg_bg.bkg) + e.window.setCursorPos(e.frame.w, 1) + e.window.write("\x1e") + e.window.setCursorPos(e.frame.w, e.frame.h) + e.window.write("\x1f") + end + + e.window.setTextColor(e.fg_bg.fgd) + e.window.setBackgroundColor(e.fg_bg.bkg) + end -- render the scroll bar and re-cacluate height & bounds local function draw_bar() local offset = 2 + math.abs(scroll_offset) - bar_height = math.max(math.min(e.frame.h - 2 + max_down_scroll, e.frame.h - 2), 1) + bar_height = math.min(max_bar_height + max_down_scroll, max_bar_height) + + if bar_height < 1 then + bar_is_scaled = true + -- can't do a 1:1 ratio + -- use minimum size bar with scaled offset + local scroll_progress = scroll_offset / max_down_scroll + offset = 2 + math.floor(scroll_progress * (max_bar_height - 1)) + bar_height = 1 + else + bar_is_scaled = false + end + bar_bounds = { offset, (bar_height + offset) - 1 } for i = 2, e.frame.h - 1 do - if i >= offset and i < (bar_height + offset) then - e.window.setBackgroundColor(e.fg_bg.fgd) + if (i >= offset and i < (bar_height + offset)) and (bar_height ~= max_bar_height) then + if args.nav_fg_bg ~= nil then + e.window.setBackgroundColor(args.nav_fg_bg.fgd) + else + e.window.setBackgroundColor(e.fg_bg.fgd) + end else - e.window.setBackgroundColor(e.fg_bg.bkg) + if args.nav_fg_bg ~= nil then + e.window.setBackgroundColor(args.nav_fg_bg.bkg) + else + e.window.setBackgroundColor(e.fg_bg.bkg) + end end e.window.setCursorPos(e.frame.w, i) @@ -104,22 +159,42 @@ local function listbox(args) scroll_frame.setVisible(true) draw_bar() + end - -- log.info("content_height[" .. content_height .. "] max_down_scroll[" .. max_down_scroll .. "] scroll_offset[" .. scroll_offset .. "] bar_height[" .. bar_height .. "]") + -- determine where to scroll to based on a scrollbar being dragged without a 1:1 relationship + ---@param direction -1|1 negative 1 to scroll up by one, positive 1 to scroll down by one + local function scaled_bar_scroll(direction) + local scroll_progress = scroll_offset / max_down_scroll + local bar_position = math.floor(scroll_progress * (max_bar_height - 1)) + + -- check what moving the scroll bar up or down would mean for the scroll progress + scroll_progress = (bar_position + direction) / (max_bar_height - 1) + + return math.max(math.floor(scroll_progress * max_down_scroll), max_down_scroll) end -- scroll down the list - local function scroll_down() + local function scroll_down(scaled) if scroll_offset > max_down_scroll then - scroll_offset = scroll_offset - 1 + if scaled then + scroll_offset = scaled_bar_scroll(1) + else + scroll_offset = scroll_offset - 1 + end + update_positions() end end -- scroll up the list - local function scroll_up() + local function scroll_up(scaled) if scroll_offset < 0 then - scroll_offset = scroll_offset + 1 + if scaled then + scroll_offset = scaled_bar_scroll(-1) + else + scroll_offset = scroll_offset + 1 + end + update_positions() end end @@ -148,11 +223,25 @@ local function listbox(args) ---@param event mouse_interaction mouse event function e.handle_mouse(event) if e.enabled then - if event.type == CLICK_TYPE.TAP or event.type == CLICK_TYPE.DOWN then + if event.type == CLICK_TYPE.TAP then if event.current.x == e.frame.w then if event.current.y == 1 or event.current.y < bar_bounds[1] then + draw_arrows(1) + scroll_up() + if args.nav_active ~= nil then tcd.dispatch(0.25, function () draw_arrows(0) end) end + elseif event.current.y == e.frame.h or event.current.y > bar_bounds[2] then + draw_arrows(-1) + scroll_down() + if args.nav_active ~= nil then tcd.dispatch(0.25, function () draw_arrows(0) end) end + end + end + elseif event.type == CLICK_TYPE.DOWN then + if event.current.x == e.frame.w then + if event.current.y == 1 or event.current.y < bar_bounds[1] then + draw_arrows(1) scroll_up() elseif event.current.y == e.frame.h or event.current.y > bar_bounds[2] then + draw_arrows(-1) scroll_down() else -- clicked on bar @@ -163,14 +252,15 @@ local function listbox(args) end elseif event.type == CLICK_TYPE.UP then holding_bar = false + draw_arrows(0) elseif event.type == CLICK_TYPE.DRAG then if holding_bar then -- if mouse is within vertical frame, including the grip point if event.current.y > (1 + bar_grip_pos) and event.current.y <= ((e.frame.h - bar_height) + bar_grip_pos) then if event.current.y < mouse_last_y then - scroll_up() + scroll_up(bar_is_scaled) elseif event.current.y > mouse_last_y then - scroll_down() + scroll_down(bar_is_scaled) end mouse_last_y = event.current.y @@ -184,6 +274,9 @@ local function listbox(args) end end + draw_arrows(0) + draw_bar() + return e.complete() end From 69df5edbeb0f77f87d0ebacce881a48ba6bae59c Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 3 Jun 2023 14:33:08 -0400 Subject: [PATCH 42/49] #184 RTU and pocket lists on supervisor front panel, element delete() bugfix --- coordinator/startup.lua | 2 +- graphics/element.lua | 5 +- pocket/startup.lua | 2 +- reactor-plc/startup.lua | 2 +- rtu/startup.lua | 2 +- supervisor/databus.lua | 75 ++++++++++++++++++-- supervisor/panel/components/pdg_entry.lua | 48 +++++++++++++ supervisor/panel/components/rtu_entry.lua | 52 ++++++++++++++ supervisor/panel/front_panel.lua | 26 ++++--- supervisor/panel/pgi.lua | 85 +++++++++++++++++++++++ supervisor/session/pocket.lua | 26 ++++--- supervisor/session/rtu.lua | 10 +++ supervisor/session/svsessions.lua | 44 ++++++------ supervisor/startup.lua | 6 +- supervisor/supervisor.lua | 4 +- 15 files changed, 335 insertions(+), 54 deletions(-) create mode 100644 supervisor/panel/components/pdg_entry.lua create mode 100644 supervisor/panel/components/rtu_entry.lua create mode 100644 supervisor/panel/pgi.lua diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 0faf0fb..c0addf1 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.15.5" +local COORDINATOR_VERSION = "v0.15.6" local println = util.println local println_ts = util.println_ts diff --git a/graphics/element.lua b/graphics/element.lua index d537171..ae2daee 100644 --- a/graphics/element.lua +++ b/graphics/element.lua @@ -323,7 +323,10 @@ function element.new(args) protected.children[k] = nil end - args.parent.__remove_child(self.id) + if args.parent ~= nil then + -- remove self from parent + args.parent.__remove_child(self.id) + end end -- ELEMENT TREE -- diff --git a/pocket/startup.lua b/pocket/startup.lua index 2a48042..50862d1 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.3.5" +local POCKET_VERSION = "alpha-v0.3.6" local println = util.println local println_ts = util.println_ts diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index cf3b08a..3e8861b 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.3.5" +local R_PLC_VERSION = "v1.3.6" local println = util.println local println_ts = util.println_ts diff --git a/rtu/startup.lua b/rtu/startup.lua index 1ae38ed..86c3db2 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.2.5" +local RTU_VERSION = "v1.2.6" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE diff --git a/supervisor/databus.lua b/supervisor/databus.lua index 082a71e..88e4ed3 100644 --- a/supervisor/databus.lua +++ b/supervisor/databus.lua @@ -4,15 +4,13 @@ local psil = require("scada-common.psil") +local pgi = require("supervisor.panel.pgi") + local databus = {} -- databus PSIL databus.ps = psil.create() -local dbus_iface = { - session_entries = { rtu = {}, diag = {} } -} - -- call to toggle heartbeat signal function databus.heartbeat() databus.ps.toggle("heartbeat") end @@ -65,6 +63,44 @@ function databus.tx_plc_rtt(reactor_id, rtt) end end +-- transmit RTU firmware version and session connection state +---@param session_id integer RTU session +---@param fw string firmware version +---@param channel integer RTU remote port +function databus.tx_rtu_connected(session_id, fw, channel) + databus.ps.publish("rtu_" .. session_id .. "_fw", fw) + databus.ps.publish("rtu_" .. session_id .. "_chan", tostring(channel)) + pgi.create_rtu_entry(session_id) +end + +-- transmit RTU disconnected +---@param session_id integer RTU session +function databus.tx_rtu_disconnected(session_id) + pgi.delete_rtu_entry(session_id) +end + +-- transmit RTU session RTT +---@param session_id integer RTU session +---@param rtt integer round trip time +function databus.tx_rtu_rtt(session_id, rtt) + databus.ps.publish("rtu_" .. session_id .. "_rtt", rtt) + + if rtt > 700 then + databus.ps.publish("rtu_" .. session_id .. "_rtt_color", colors.red) + elseif rtt > 300 then + databus.ps.publish("rtu_" .. session_id .. "_rtt_color", colors.yellow_hc) + else + databus.ps.publish("rtu_" .. session_id .. "_rtt_color", colors.green) + end +end + +-- transmit RTU session unit count +---@param session_id integer RTU session +---@param units integer unit count +function databus.tx_rtu_units(session_id, units) + databus.ps.publish("rtu_" .. session_id .. "_units", units) +end + -- transmit coordinator firmware version and session connection state ---@param fw string firmware version ---@param channel integer coordinator remote port @@ -97,6 +133,37 @@ function databus.tx_crd_rtt(rtt) end end +-- transmit PDG firmware version and session connection state +---@param session_id integer PDG session +---@param fw string firmware version +---@param channel integer PDG remote port +function databus.tx_pdg_connected(session_id, fw, channel) + databus.ps.publish("pdg_" .. session_id .. "_fw", fw) + databus.ps.publish("pdg_" .. session_id .. "_chan", tostring(channel)) + pgi.create_pdg_entry(session_id) +end + +-- transmit PDG disconnected +---@param session_id integer PDG session +function databus.tx_pdg_disconnected(session_id) + pgi.delete_pdg_entry(session_id) +end + +-- transmit PDG session RTT +---@param session_id integer PDG session +---@param rtt integer round trip time +function databus.tx_pdg_rtt(session_id, rtt) + databus.ps.publish("pdg_" .. session_id .. "_rtt", rtt) + + if rtt > 700 then + databus.ps.publish("pdg_" .. session_id .. "_rtt_color", colors.red) + elseif rtt > 300 then + databus.ps.publish("pdg_" .. session_id .. "_rtt_color", colors.yellow_hc) + else + databus.ps.publish("pdg_" .. session_id .. "_rtt_color", colors.green) + end +end + -- link a function to receive data from the bus ---@param field string field name ---@param func function function to link diff --git a/supervisor/panel/components/pdg_entry.lua b/supervisor/panel/components/pdg_entry.lua new file mode 100644 index 0000000..94cd385 --- /dev/null +++ b/supervisor/panel/components/pdg_entry.lua @@ -0,0 +1,48 @@ +-- +-- Pocket Diagnostics Connection Entry +-- + +local util = require("scada-common.util") + +local databus = require("supervisor.databus") + +local core = require("graphics.core") + +local Div = require("graphics.elements.div") +local TextBox = require("graphics.elements.textbox") + +local DataIndicator = require("graphics.elements.indicators.data") + +local TEXT_ALIGN = core.TEXT_ALIGN + +local cpair = core.cpair + +-- create a pocket diagnostics list entry +---@param parent graphics_element parent +---@param id integer PDG session ID +local function init(parent, id) + -- root div + local root = Div{parent=parent,x=2,y=2,height=4,width=parent.get_width()-2,hidden=true} + local entry = Div{parent=root,x=2,y=1,height=3,fg_bg=cpair(colors.black,colors.white)} + + local ps_prefix = "pdg_" .. id .. "_" + + TextBox{parent=entry,x=1,y=1,text="",width=8,height=1,fg_bg=cpair(colors.black,colors.lightGray)} + local pdg_chan = TextBox{parent=entry,x=1,y=2,text=" :00000",alignment=TEXT_ALIGN.CENTER,width=8,height=1,fg_bg=cpair(colors.black,colors.lightGray),nav_active=cpair(colors.gray,colors.black)} + TextBox{parent=entry,x=1,y=3,text="",width=8,height=1,fg_bg=cpair(colors.black,colors.lightGray)} + pdg_chan.register(databus.ps, ps_prefix .. "chan", function (channel) pdg_chan.set_value(util.sprintf(" :%05d", channel)) end) + + TextBox{parent=entry,x=10,y=2,text="FW:",width=3,height=1} + local pdg_fw_v = TextBox{parent=entry,x=14,y=2,text=" ------- ",width=20,height=1,fg_bg=cpair(colors.lightGray,colors.white)} + pdg_fw_v.register(databus.ps, ps_prefix .. "fw", pdg_fw_v.set_value) + + TextBox{parent=entry,x=35,y=2,text="RTT:",width=4,height=1} + local pdg_rtt = DataIndicator{parent=entry,x=40,y=2,label="",unit="",format="%5d",value=0,width=5,fg_bg=cpair(colors.lightGray,colors.white)} + TextBox{parent=entry,x=46,y=2,text="ms",width=4,height=1,fg_bg=cpair(colors.lightGray,colors.white)} + pdg_rtt.register(databus.ps, ps_prefix .. "rtt", pdg_rtt.update) + pdg_rtt.register(databus.ps, ps_prefix .. "rtt_color", pdg_rtt.recolor) + + return root +end + +return init diff --git a/supervisor/panel/components/rtu_entry.lua b/supervisor/panel/components/rtu_entry.lua new file mode 100644 index 0000000..a4a5a4e --- /dev/null +++ b/supervisor/panel/components/rtu_entry.lua @@ -0,0 +1,52 @@ +-- +-- RTU Connection Entry +-- + +local util = require("scada-common.util") + +local databus = require("supervisor.databus") + +local core = require("graphics.core") + +local Div = require("graphics.elements.div") +local TextBox = require("graphics.elements.textbox") + +local DataIndicator = require("graphics.elements.indicators.data") + +local TEXT_ALIGN = core.TEXT_ALIGN + +local cpair = core.cpair + +-- create an RTU list entry +---@param parent graphics_element parent +---@param id integer RTU session ID +local function init(parent, id) + -- root div + local root = Div{parent=parent,x=2,y=2,height=4,width=parent.get_width()-2,hidden=true} + local entry = Div{parent=root,x=2,y=1,height=3,fg_bg=cpair(colors.black,colors.white)} + + local ps_prefix = "rtu_" .. id .. "_" + + TextBox{parent=entry,x=1,y=1,text="",width=8,height=1,fg_bg=cpair(colors.black,colors.lightGray)} + local rtu_chan = TextBox{parent=entry,x=1,y=2,text=" :00000",alignment=TEXT_ALIGN.CENTER,width=8,height=1,fg_bg=cpair(colors.black,colors.lightGray),nav_active=cpair(colors.gray,colors.black)} + TextBox{parent=entry,x=1,y=3,text="",width=8,height=1,fg_bg=cpair(colors.black,colors.lightGray)} + rtu_chan.register(databus.ps, ps_prefix .. "chan", function (channel) rtu_chan.set_value(util.sprintf(" :%05d", channel)) end) + + TextBox{parent=entry,x=10,y=2,text="UNITS:",width=7,height=1} + local unit_count = DataIndicator{parent=entry,x=17,y=2,label="",unit="",format="%2d",value=0,width=2,fg_bg=cpair(colors.gray,colors.white)} + unit_count.register(databus.ps, ps_prefix .. "units", unit_count.set_value) + + TextBox{parent=entry,x=21,y=2,text="FW:",width=3,height=1} + local rtu_fw_v = TextBox{parent=entry,x=25,y=2,text=" ------- ",width=9,height=1,fg_bg=cpair(colors.lightGray,colors.white)} + rtu_fw_v.register(databus.ps, ps_prefix .. "fw", rtu_fw_v.set_value) + + TextBox{parent=entry,x=36,y=2,text="RTT:",width=4,height=1} + local rtu_rtt = DataIndicator{parent=entry,x=40,y=2,label="",unit="",format="%5d",value=0,width=5,fg_bg=cpair(colors.lightGray,colors.white)} + TextBox{parent=entry,x=46,y=2,text="ms",width=4,height=1,fg_bg=cpair(colors.lightGray,colors.white)} + rtu_rtt.register(databus.ps, ps_prefix .. "rtt", rtu_rtt.update) + rtu_rtt.register(databus.ps, ps_prefix .. "rtt_color", rtu_rtt.recolor) + + return root +end + +return init diff --git a/supervisor/panel/front_panel.lua b/supervisor/panel/front_panel.lua index 940a116..86d9839 100644 --- a/supervisor/panel/front_panel.lua +++ b/supervisor/panel/front_panel.lua @@ -7,8 +7,12 @@ local util = require("scada-common.util") local config = require("supervisor.config") local databus = require("supervisor.databus") +local pgi = require("supervisor.panel.pgi") local style = require("supervisor.panel.style") +local pdg_entry = require("supervisor.panel.components.pdg_entry") +local rtu_entry = require("supervisor.panel.components.rtu_entry") + local core = require("graphics.core") local Div = require("graphics.elements.div") @@ -45,7 +49,7 @@ local function init(panel) local system = Div{parent=main_page,width=14,height=17,x=2,y=2} - local on = LED{parent=system,label="POWER",colors=cpair(colors.green,colors.red)} + local on = LED{parent=system,label="STATUS",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() @@ -107,14 +111,8 @@ local function init(panel) -- rtu page local rtu_page = Div{parent=page_div,x=1,y=1,hidden=true} - local rtu_list = ListBox{parent=rtu_page,x=2,y=2,height=15,width=49,scroll_height=1000,item_pad=1,fg_bg=cpair(colors.black,colors.white)} - - local item_1 = Div{parent=rtu_list,height=3,fg_bg=cpair(colors.black,colors.red),hidden=true} - local item_2 = Div{parent=rtu_list,height=3,fg_bg=cpair(colors.black,colors.orange),hidden=true} - local item_3 = Div{parent=rtu_list,height=3,fg_bg=cpair(colors.black,colors.yellow),hidden=true} - local item_4 = Div{parent=rtu_list,height=3,fg_bg=cpair(colors.black,colors.green),hidden=true} - local item_5 = Div{parent=rtu_list,height=3,fg_bg=cpair(colors.black,colors.blue),hidden=true} - local item_6 = Div{parent=rtu_list,height=3,fg_bg=cpair(colors.black,colors.purple),hidden=true} + local rtu_list = ListBox{parent=rtu_page,x=1,y=1,height=17,width=51,scroll_height=1000,fg_bg=cpair(colors.black,colors.ivory),nav_fg_bg=cpair(colors.gray,colors.lightGray),nav_active=cpair(colors.black,colors.gray)} + local _ = Div{parent=rtu_list,height=1,hidden=true} -- padding -- coordinator page @@ -138,10 +136,13 @@ local function init(panel) crd_rtt.register(databus.ps, "crd_rtt", crd_rtt.update) crd_rtt.register(databus.ps, "crd_rtt_color", crd_rtt.recolor) - -- pocket page + -- pocket diagnostics page local pkt_page = Div{parent=page_div,x=1,y=1,hidden=true} - local pkt_box = Div{parent=pkt_page,x=2,y=2,width=49} + local pdg_list = ListBox{parent=pkt_page,x=1,y=1,height=17,width=51,scroll_height=1000,fg_bg=cpair(colors.black,colors.ivory),nav_fg_bg=cpair(colors.gray,colors.lightGray),nav_active=cpair(colors.black,colors.gray)} + local _ = Div{parent=pdg_list,height=1,hidden=true} -- padding + + -- assemble page panes local panes = { main_page, plc_page, rtu_page, crd_page, pkt_page } @@ -156,6 +157,9 @@ local function init(panel) } TabBar{parent=panel,y=2,tabs=tabs,min_width=9,callback=page_pane.set_value,fg_bg=cpair(colors.black,colors.white)} + + -- link RTU/PDG list management to PGI + pgi.link_elements(rtu_list, rtu_entry, pdg_list, pdg_entry) end return init diff --git a/supervisor/panel/pgi.lua b/supervisor/panel/pgi.lua new file mode 100644 index 0000000..4126dee --- /dev/null +++ b/supervisor/panel/pgi.lua @@ -0,0 +1,85 @@ +-- +-- Protected Graphics Interface +-- + +local log = require("scada-common.log") +local util = require("scada-common.util") + +local pgi = {} + +local data = { + rtu_list = nil, ---@type nil|graphics_element + pdg_list = nil, ---@type nil|graphics_element + rtu_entry = nil, ---@type function + pdg_entry = nil, ---@type function + -- session entries + s_entries = { rtu = {}, pdg = {} } +} + +-- link list boxes +---@param rtu_list graphics_element RTU list element +---@param rtu_entry function RTU entry constructor +---@param pdg_list graphics_element pocket diagnostics list element +---@param pdg_entry function pocket diagnostics entry constructor +function pgi.link_elements(rtu_list, rtu_entry, pdg_list, pdg_entry) + data.rtu_list = rtu_list + data.pdg_list = pdg_list + data.rtu_entry = rtu_entry + data.pdg_entry = pdg_entry +end + +-- add an RTU entry to the RTU list +---@param session_id integer RTU session +function pgi.create_rtu_entry(session_id) + if data.rtu_list ~= nil and data.rtu_entry ~= nil then + local success, result = pcall(data.rtu_entry, data.rtu_list, session_id) + + if success then + data.s_entries.rtu[session_id] = result + else + log.error(util.c("PGI: failed to create RTU entry (", result, ")"), true) + end + end +end + +-- delete an RTU entry from the RTU list +---@param session_id integer RTU session +function pgi.delete_rtu_entry(session_id) + if data.s_entries.rtu[session_id] ~= nil then + local success, result = pcall(data.s_entries.rtu[session_id].delete) + data.s_entries.rtu[session_id] = nil + + if not success then + log.error(util.c("PGI: failed to delete RTU entry (", result, ")"), true) + end + end +end + +-- add a PDG entry to the PDG list +---@param session_id integer pocket diagnostics session +function pgi.create_pdg_entry(session_id) + if data.pdg_list ~= nil and data.pdg_entry ~= nil then + local success, result = pcall(data.pdg_entry, data.pdg_list, session_id) + + if success then + data.s_entries.pdg[session_id] = result + else + log.error(util.c("PGI: failed to create PDG entry (", result, ")"), true) + end + end +end + +-- delete a PDG entry from the PDG list +---@param session_id integer pocket diagnostics session +function pgi.delete_pdg_entry(session_id) + if data.s_entries.pdg[session_id] ~= nil then + local success, result = pcall(data.s_entries.pdg[session_id].delete) + data.s_entries.pdg[session_id] = nil + + if not success then + log.error(util.c("PGI: failed to delete PDG entry (", result, ")"), true) + end + end +end + +return pgi diff --git a/supervisor/session/pocket.lua b/supervisor/session/pocket.lua index 5693e02..175a235 100644 --- a/supervisor/session/pocket.lua +++ b/supervisor/session/pocket.lua @@ -1,7 +1,8 @@ -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 databus = require("supervisor.databus") local pocket = {} @@ -35,7 +36,7 @@ local PERIODICS = { ---@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 log_header = "pdg_session(" .. id .. "): " local self = { -- connection properties @@ -56,18 +57,19 @@ function pocket.new_session(id, in_queue, out_queue, timeout) acks = { }, -- session database - ---@class diag_db + ---@class pdg_db sDB = { } } - ---@class diag_session + ---@class pdg_session local public = {} -- mark this diagnostics session as closed, stop watchdog local function _close() self.conn_watchdog.cancel() self.connected = false + databus.tx_pdg_disconnected(id) end -- send a SCADA management packet @@ -107,16 +109,18 @@ function pocket.new_session(id, in_queue, out_queue, timeout) -- keep alive reply if pkt.length == 2 then local srv_start = pkt.data[1] - -- local diag_send = pkt.data[2] + -- local pdg_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)") + log.warning(log_header .. "PDG 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") + -- log.debug(log_header .. "PDG RTT = " .. self.last_rtt .. "ms") + -- log.debug(log_header .. "PDG TT = " .. (srv_now - pdg_send) .. "ms") + + databus.tx_pdg_rtt(id, self.last_rtt) else log.debug(log_header .. "SCADA keep alive packet length mismatch") end diff --git a/supervisor/session/rtu.lua b/supervisor/session/rtu.lua index a38e240..40b47ed 100644 --- a/supervisor/session/rtu.lua +++ b/supervisor/session/rtu.lua @@ -4,6 +4,8 @@ local mqueue = require("scada-common.mqueue") local types = require("scada-common.types") local util = require("scada-common.util") +local databus = require("supervisor.databus") + local svqtypes = require("supervisor.session.svqtypes") -- supervisor rtu sessions (svrs) @@ -67,6 +69,8 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili -- parse the recorded advertisement and create unit sub-sessions local function _handle_advertisement() + local unit_count = 0 + _reset_config() for i = 1, #self.fac_units do @@ -173,18 +177,22 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili if unit ~= nil then self.units[i] = unit + unit_count = unit_count + 1 elseif u_type ~= RTU_UNIT_TYPE.VIRTUAL then _reset_config() log.error(util.c(log_header, "bad advertisement: error occured while creating a unit (type is ", type_string, ")")) break end end + + databus.tx_rtu_units(id, unit_count) end -- mark this RTU session as closed, stop watchdog local function _close() self.conn_watchdog.cancel() self.connected = false + databus.tx_rtu_disconnected(id) -- mark all RTU unit sessions as closed so the reactor unit knows for _, unit in pairs(self.units) do unit.close() end @@ -255,6 +263,8 @@ function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facili -- log.debug(log_header .. "RTU RTT = " .. self.last_rtt .. "ms") -- log.debug(log_header .. "RTU TT = " .. (srv_now - rtu_send) .. "ms") + + databus.tx_rtu_rtt(id, self.last_rtt) else log.debug(log_header .. "SCADA keep alive packet length mismatch") end diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index 8c56419..ecd8928 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -28,7 +28,7 @@ local SESSION_TYPE = { RTU_SESSION = 0, -- RTU gateway PLC_SESSION = 1, -- reactor PLC COORD_SESSION = 2, -- coordinator - DIAG_SESSION = 3 -- pocket diagnostics + PDG_SESSION = 3 -- pocket diagnostics } svsessions.SESSION_TYPE = SESSION_TYPE @@ -37,11 +37,11 @@ local self = { modem = nil, ---@type table|nil num_reactors = 0, facility = nil, ---@type facility|nil - sessions = { rtu = {}, plc = {}, coord = {}, diag = {} }, - next_ids = { rtu = 0, plc = 0, coord = 0, diag = 0 } + sessions = { rtu = {}, plc = {}, coord = {}, pdg = {} }, + next_ids = { rtu = 0, plc = 0, coord = 0, pdg = 0 } } ----@alias sv_session_structs plc_session_struct|rtu_session_struct|coord_session_struct|diag_session_struct +---@alias sv_session_structs plc_session_struct|rtu_session_struct|coord_session_struct|pdg_session_struct -- PRIVATE FUNCTIONS -- @@ -251,14 +251,14 @@ end -- find a coordinator or diagnostic access session by the remote port ---@nodiscard ---@param remote_port integer ----@return coord_session_struct|diag_session_struct|nil +---@return coord_session_struct|pdg_session_struct|nil function svsessions.find_svctl_session(remote_port) -- check coordinator sessions local session = _find_session(self.sessions.coord, remote_port) -- 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 + if session == nil then session = _find_session(self.sessions.pdg, remote_port) end + ---@cast session coord_session_struct|pdg_session_struct|nil return session end @@ -316,10 +316,10 @@ function svsessions.establish_plc_session(local_port, remote_port, 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_ids.plc = self.next_ids.plc + 1 - databus.tx_plc_connected(for_reactor, version, remote_port) + self.next_ids.plc = self.next_ids.plc + 1 + -- success return plc_s.instance.get_id() else @@ -353,6 +353,8 @@ function svsessions.establish_rtu_session(local_port, remote_port, advertisement log.debug("established new RTU session to " .. remote_port .. " with ID " .. self.next_ids.rtu) + databus.tx_rtu_connected(self.next_ids.rtu, version, remote_port) + self.next_ids.rtu = self.next_ids.rtu + 1 -- success @@ -384,10 +386,10 @@ function svsessions.establish_coord_session(local_port, remote_port, version) log.debug("established new coordinator session to " .. remote_port .. " with ID " .. self.next_ids.coord) - self.next_ids.coord = self.next_ids.coord + 1 - databus.tx_crd_connected(version, remote_port) + self.next_ids.coord = self.next_ids.coord + 1 + -- success return coord_s.instance.get_id() else @@ -402,9 +404,9 @@ end ---@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 = { +function svsessions.establish_pdg_session(local_port, remote_port, version) + ---@class pdg_session_struct + local pdg_s = { s_type = "pkt", open = true, version = version, @@ -412,18 +414,20 @@ function svsessions.establish_diag_session(local_port, remote_port, version) r_port = remote_port, in_queue = mqueue.new(), out_queue = mqueue.new(), - instance = nil ---@type diag_session + instance = nil ---@type pdg_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) + pdg_s.instance = pocket.new_session(self.next_ids.pdg, pdg_s.in_queue, pdg_s.out_queue, config.PKT_TIMEOUT) + table.insert(self.sessions.pdg, pdg_s) - log.debug("established new pocket diagnostics session to " .. remote_port .. " with ID " .. self.next_ids.diag) + log.debug("established new pocket diagnostics session to " .. remote_port .. " with ID " .. self.next_ids.pdg) - self.next_ids.diag = self.next_ids.diag + 1 + databus.tx_pdg_connected(self.next_ids.pdg, version, remote_port) + + self.next_ids.pdg = self.next_ids.pdg + 1 -- success - return diag_s.instance.get_id() + return pdg_s.instance.get_id() end -- attempt to identify which session's watchdog timer fired diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 6e2dd95..cdae63e 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -8,6 +8,7 @@ local crash = require("scada-common.crash") local comms = require("scada-common.comms") local log = require("scada-common.log") local ppm = require("scada-common.ppm") +local tcd = require("scada-common.tcallbackdsp") local util = require("scada-common.util") local core = require("graphics.core") @@ -19,7 +20,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.16.5" +local SUPERVISOR_VERSION = "v0.16.6" local println = util.println local println_ts = util.println_ts @@ -169,6 +170,9 @@ local function main() elseif event == "timer" then -- a non-clock timer event, check watchdogs svsessions.check_all_watchdogs(param1) + + -- notify timer callback dispatcher + tcd.handle(param1) elseif event == "modem_message" then -- got a packet local packet = superv_comms.parse_packet(param1, param2, param3, param4, param5) diff --git a/supervisor/supervisor.lua b/supervisor/supervisor.lua index 4fba85c..0424b53 100644 --- a/supervisor/supervisor.lua +++ b/supervisor/supervisor.lua @@ -305,9 +305,9 @@ function supervisor.comms(_version, num_reactors, cooling_conf, modem, dev_liste 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) + local s_id = svsessions.establish_pdg_session(l_port, r_port, firmware_v) - println(util.c("PKT (", firmware_v, ") [:", r_port, "] \xbb connected")) + println(util.c("PDG (", 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 }) From 529371a0fda1341b622ce45d8340cd16acb1881b Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 3 Jun 2023 15:45:48 -0400 Subject: [PATCH 43/49] #184 support supervisor running without front panel, halved heartbeat blink rate --- install_manifest.json | 1 + supervisor/panel/front_panel.lua | 5 - supervisor/panel/pgi.lua | 8 ++ supervisor/renderer.lua | 4 + supervisor/session/coordinator.lua | 9 +- supervisor/session/plc.lua | 9 +- supervisor/session/pocket.lua | 9 +- supervisor/session/rtu.lua | 9 +- supervisor/session/svsessions.lua | 25 ++-- supervisor/startup.lua | 181 +++++++++++++++-------------- supervisor/supervisor.lua | 13 ++- 11 files changed, 152 insertions(+), 121 deletions(-) create mode 100644 install_manifest.json diff --git a/install_manifest.json b/install_manifest.json new file mode 100644 index 0000000..819e6ee --- /dev/null +++ b/install_manifest.json @@ -0,0 +1 @@ +{"versions": {"installer": "v1.2", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.3.6", "rtu": "v1.2.6", "supervisor": "v0.16.6", "coordinator": "v0.15.6", "pocket": "alpha-v0.3.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/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.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/tabbar.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/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.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/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_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": 5775, "system": 1991, "common": 91102, "graphics": 144089, "lockbox": 100797, "reactor-plc": 95896, "rtu": 100988, "supervisor": 310870, "coordinator": 197544, "pocket": 36338}} \ No newline at end of file diff --git a/supervisor/panel/front_panel.lua b/supervisor/panel/front_panel.lua index 86d9839..8ebc448 100644 --- a/supervisor/panel/front_panel.lua +++ b/supervisor/panel/front_panel.lua @@ -18,21 +18,16 @@ local core = require("graphics.core") local Div = require("graphics.elements.div") local ListBox = require("graphics.elements.listbox") local MultiPane = require("graphics.elements.multipane") -local Rectangle = require("graphics.elements.rectangle") local TextBox = require("graphics.elements.textbox") -local PushButton = require("graphics.elements.controls.push_button") local TabBar = require("graphics.elements.controls.tabbar") local LED = require("graphics.elements.indicators.led") -local LEDPair = require("graphics.elements.indicators.ledpair") -local RGBLED = require("graphics.elements.indicators.ledrgb") local DataIndicator = require("graphics.elements.indicators.data") local TEXT_ALIGN = core.TEXT_ALIGN local cpair = core.cpair -local border = core.border -- create new main view ---@param panel graphics_element main displaybox diff --git a/supervisor/panel/pgi.lua b/supervisor/panel/pgi.lua index 4126dee..9065f72 100644 --- a/supervisor/panel/pgi.lua +++ b/supervisor/panel/pgi.lua @@ -28,6 +28,14 @@ function pgi.link_elements(rtu_list, rtu_entry, pdg_list, pdg_entry) data.pdg_entry = pdg_entry end +-- unlink all fields, disabling the PGI +function pgi.unlink() + data.rtu_list = nil + data.pdg_list = nil + data.rtu_entry = nil + data.pdg_entry = nil +end + -- add an RTU entry to the RTU list ---@param session_id integer RTU session function pgi.create_rtu_entry(session_id) diff --git a/supervisor/renderer.lua b/supervisor/renderer.lua index 5dfb7d1..1bc70a4 100644 --- a/supervisor/renderer.lua +++ b/supervisor/renderer.lua @@ -3,6 +3,7 @@ -- local panel_view = require("supervisor.panel.front_panel") +local pgi = require("supervisor.panel.pgi") local style = require("supervisor.panel.style") local flasher = require("graphics.flasher") @@ -44,6 +45,9 @@ function renderer.close_ui() -- stop blinking indicators flasher.clear() + -- disable PGI + pgi.unlink() + -- hide to stop animation callbacks ui.display.hide() diff --git a/supervisor/session/coordinator.lua b/supervisor/session/coordinator.lua index 03a579d..36a5241 100644 --- a/supervisor/session/coordinator.lua +++ b/supervisor/session/coordinator.lua @@ -20,9 +20,6 @@ local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local SV_Q_DATA = svqtypes.SV_Q_DATA --- local println = util.println -local println = function (str) end - -- retry time constants in ms -- local INITIAL_WAIT = 1500 local RETRY_PERIOD = 1000 @@ -52,7 +49,11 @@ local PERIODICS = { ---@param out_queue mqueue out message queue ---@param timeout number communications timeout ---@param facility facility facility data table -function coordinator.new_session(id, in_queue, out_queue, timeout, facility) +---@param fp_ok boolean if the front panel UI is running +function coordinator.new_session(id, in_queue, out_queue, timeout, facility, fp_ok) + -- print a log message to the terminal as long as the UI isn't running + local function println(message) if not fp_ok then util.println_ts(message) end end + local log_header = "crdn_session(" .. id .. "): " local self = { diff --git a/supervisor/session/plc.lua b/supervisor/session/plc.lua index 0fb987a..1436534 100644 --- a/supervisor/session/plc.lua +++ b/supervisor/session/plc.lua @@ -16,9 +16,6 @@ local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE local PLC_AUTO_ACK = comms.PLC_AUTO_ACK local UNIT_COMMAND = comms.UNIT_COMMAND --- local println = util.println -local println = function (str) end - -- retry time constants in ms local INITIAL_WAIT = 1500 local INITIAL_AUTO_WAIT = 1000 @@ -52,7 +49,11 @@ local PERIODICS = { ---@param in_queue mqueue in message queue ---@param out_queue mqueue out message queue ---@param timeout number communications timeout -function plc.new_session(id, reactor_id, in_queue, out_queue, timeout) +---@param fp_ok boolean if the front panel UI is running +function plc.new_session(id, reactor_id, in_queue, out_queue, timeout, fp_ok) + -- print a log message to the terminal as long as the UI isn't running + local function println(message) if not fp_ok then util.println_ts(message) end end + local log_header = "plc_session(" .. id .. "): " local self = { diff --git a/supervisor/session/pocket.lua b/supervisor/session/pocket.lua index 175a235..ba6d179 100644 --- a/supervisor/session/pocket.lua +++ b/supervisor/session/pocket.lua @@ -9,9 +9,6 @@ local pocket = {} local PROTOCOL = comms.PROTOCOL local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE --- local println = util.println -local println = function (str) end - -- retry time constants in ms -- local INITIAL_WAIT = 1500 -- local RETRY_PERIOD = 1000 @@ -35,7 +32,11 @@ local PERIODICS = { ---@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) +---@param fp_ok boolean if the front panel UI is running +function pocket.new_session(id, in_queue, out_queue, timeout, fp_ok) + -- print a log message to the terminal as long as the UI isn't running + local function println(message) if not fp_ok then util.println_ts(message) end end + local log_header = "pdg_session(" .. id .. "): " local self = { diff --git a/supervisor/session/rtu.lua b/supervisor/session/rtu.lua index 40b47ed..2f7091c 100644 --- a/supervisor/session/rtu.lua +++ b/supervisor/session/rtu.lua @@ -24,9 +24,6 @@ local PROTOCOL = comms.PROTOCOL local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE --- local println = util.println -local println = function (str) end - local PERIODICS = { KEEP_ALIVE = 2000 } @@ -39,7 +36,11 @@ local PERIODICS = { ---@param timeout number communications timeout ---@param advertisement table RTU device advertisement ---@param facility facility facility data table -function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facility) +---@param fp_ok boolean if the front panel UI is running +function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facility, fp_ok) + -- print a log message to the terminal as long as the UI isn't running + local function println(message) if not fp_ok then util.println_ts(message) end end + local log_header = "rtu_session(" .. id .. "): " local self = { diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index ecd8928..a41658a 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -35,6 +35,7 @@ svsessions.SESSION_TYPE = SESSION_TYPE local self = { modem = nil, ---@type table|nil + fp_ok = false, num_reactors = 0, facility = nil, ---@type facility|nil sessions = { rtu = {}, plc = {}, coord = {}, pdg = {} }, @@ -196,11 +197,13 @@ end -- PUBLIC FUNCTIONS -- -- initialize svsessions ----@param modem table ----@param num_reactors integer ----@param cooling_conf table -function svsessions.init(modem, num_reactors, cooling_conf) +---@param modem table modem device +---@param fp_ok boolean front panel active +---@param num_reactors integer number of reactors +---@param cooling_conf table cooling configuration definition +function svsessions.init(modem, fp_ok, num_reactors, cooling_conf) self.modem = modem + self.fp_ok = fp_ok self.num_reactors = num_reactors self.facility = facility.new(num_reactors, cooling_conf) end @@ -308,13 +311,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_ids.plc, for_reactor, plc_s.in_queue, plc_s.out_queue, config.PLC_TIMEOUT) + plc_s.instance = plc.new_session(self.next_ids.plc, for_reactor, plc_s.in_queue, plc_s.out_queue, + config.PLC_TIMEOUT, self.fp_ok) 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_ids.plc, " 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)) databus.tx_plc_connected(for_reactor, version, remote_port) @@ -348,7 +353,8 @@ function svsessions.establish_rtu_session(local_port, remote_port, advertisement instance = nil ---@type rtu_session } - rtu_s.instance = rtu.new_session(self.next_ids.rtu, rtu_s.in_queue, rtu_s.out_queue, config.RTU_TIMEOUT, advertisement, self.facility) + rtu_s.instance = rtu.new_session(self.next_ids.rtu, rtu_s.in_queue, rtu_s.out_queue, config.RTU_TIMEOUT, advertisement, + self.facility, self.fp_ok) table.insert(self.sessions.rtu, rtu_s) log.debug("established new RTU session to " .. remote_port .. " with ID " .. self.next_ids.rtu) @@ -381,7 +387,8 @@ function svsessions.establish_coord_session(local_port, remote_port, version) instance = nil ---@type coord_session } - coord_s.instance = coordinator.new_session(self.next_ids.coord, coord_s.in_queue, coord_s.out_queue, config.CRD_TIMEOUT, self.facility) + coord_s.instance = coordinator.new_session(self.next_ids.coord, coord_s.in_queue, coord_s.out_queue, config.CRD_TIMEOUT, + self.facility, self.fp_ok) table.insert(self.sessions.coord, coord_s) log.debug("established new coordinator session to " .. remote_port .. " with ID " .. self.next_ids.coord) @@ -417,7 +424,7 @@ function svsessions.establish_pdg_session(local_port, remote_port, version) instance = nil ---@type pdg_session } - pdg_s.instance = pocket.new_session(self.next_ids.pdg, pdg_s.in_queue, pdg_s.out_queue, config.PKT_TIMEOUT) + pdg_s.instance = pocket.new_session(self.next_ids.pdg, pdg_s.in_queue, pdg_s.out_queue, config.PKT_TIMEOUT, self.fp_ok) table.insert(self.sessions.pdg, pdg_s) log.debug("established new pocket diagnostics session to " .. remote_port .. " with ID " .. self.next_ids.pdg) diff --git a/supervisor/startup.lua b/supervisor/startup.lua index cdae63e..d0f95a8 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -108,93 +108,104 @@ local function main() println_ts(util.c("UI error: ", message)) log.error(util.c("GUI crashed with error ", message)) else - -- 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_CTL_LISTEN, config.TRUSTED_RANGE) - - -- base loop clock (6.67Hz, 3 ticks) - local MAIN_CLOCK = 0.15 - local loop_clock = util.new_clock(MAIN_CLOCK) - - -- start clock - loop_clock.start() - - -- event loop - while true do - local event, param1, param2, param3, param4, param5 = util.pull_event() - - -- handle event - if event == "peripheral_detach" then - local type, device = ppm.handle_unmount(param1) - - if type ~= nil and device ~= nil then - if type == "modem" then - -- we only care if this is our wireless modem - if device == modem then - log.warning("comms modem disconnected") - databus.tx_hw_modem(false) - else - log.warning("non-comms modem disconnected") - end - end - end - elseif event == "peripheral" then - local type, device = ppm.mount(param1) - - if type ~= nil and device ~= nil then - if type == "modem" then - if device.isWireless() then - -- reconnected modem - modem = device - superv_comms.reconnect_modem(modem) - - log.info("comms modem reconnected") - - databus.tx_hw_modem(true) - else - log.info("wired modem reconnected") - end - end - end - elseif event == "timer" and loop_clock.is_clock(param1) then - -- main loop tick - databus.heartbeat() - - -- iterate sessions - svsessions.iterate_all() - - -- free any closed sessions - svsessions.free_all_closed() - - loop_clock.start() - elseif event == "timer" then - -- a non-clock timer event, check watchdogs - svsessions.check_all_watchdogs(param1) - - -- notify timer callback dispatcher - tcd.handle(param1) - elseif event == "modem_message" then - -- got a packet - local packet = superv_comms.parse_packet(param1, param2, param3, param4, param5) - superv_comms.handle_packet(packet) - elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" then - -- handle a mouse event - renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3)) - end - - -- check for termination request - if event == "terminate" or ppm.should_terminate() then - log.info("terminate requested, closing sessions...") - svsessions.close_all() - log.info("sessions closed") - break - end - end - - renderer.close_ui() + -- redefine println_ts local to not print as we have the front panel running + println_ts = function (_) end end - println_ts("exited") + -- 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_CTL_LISTEN, config.TRUSTED_RANGE, fp_ok) + + -- base loop clock (6.67Hz, 3 ticks) + local MAIN_CLOCK = 0.15 + local loop_clock = util.new_clock(MAIN_CLOCK) + + -- start clock + loop_clock.start() + + -- halve the rate heartbeat LED flash + local heartbeat_toggle = true + + -- event loop + while true do + local event, param1, param2, param3, param4, param5 = util.pull_event() + + -- handle event + if event == "peripheral_detach" then + local type, device = ppm.handle_unmount(param1) + + if type ~= nil and device ~= nil then + if type == "modem" then + -- we only care if this is our wireless modem + if device == 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 + end + end + elseif event == "peripheral" then + local type, device = ppm.mount(param1) + + if type ~= nil and device ~= nil then + if type == "modem" then + if device.isWireless() then + -- reconnected modem + modem = device + superv_comms.reconnect_modem(modem) + + println_ts("wireless modem reconnected.") + log.info("comms modem reconnected") + + databus.tx_hw_modem(true) + else + log.info("wired modem reconnected") + end + end + end + elseif event == "timer" and loop_clock.is_clock(param1) then + -- main loop tick + + if heartbeat_toggle then databus.heartbeat() end + heartbeat_toggle = not heartbeat_toggle + + -- iterate sessions + svsessions.iterate_all() + + -- free any closed sessions + svsessions.free_all_closed() + + loop_clock.start() + elseif event == "timer" then + -- a non-clock timer event, check watchdogs + svsessions.check_all_watchdogs(param1) + + -- notify timer callback dispatcher + tcd.handle(param1) + elseif event == "modem_message" then + -- got a packet + local packet = superv_comms.parse_packet(param1, param2, param3, param4, param5) + superv_comms.handle_packet(packet) + elseif event == "mouse_click" or event == "mouse_up" or event == "mouse_drag" or event == "mouse_scroll" then + -- handle a mouse event + renderer.handle_mouse(core.events.new_mouse_event(event, param1, param2, param3)) + end + + -- check for termination request + if event == "terminate" or ppm.should_terminate() then + println_ts("closing sesssions...") + log.info("terminate requested, closing sessions...") + svsessions.close_all() + log.info("sessions closed") + break + end + end + + renderer.close_ui() + + util.println_ts("exited") log.info("exited") end diff --git a/supervisor/supervisor.lua b/supervisor/supervisor.lua index 0424b53..6a27c0e 100644 --- a/supervisor/supervisor.lua +++ b/supervisor/supervisor.lua @@ -11,9 +11,6 @@ local DEVICE_TYPE = comms.DEVICE_TYPE local ESTABLISH_ACK = comms.ESTABLISH_ACK local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE --- local println = util.println -local println = function (str) end - -- supervisory controller communications ---@nodiscard ---@param _version string supervisor version @@ -23,8 +20,12 @@ local println = function (str) end ---@param dev_listen integer listening port for PLC/RTU devices ---@param svctl_listen integer listening port for supervisor access ---@param range integer trusted device connection range +---@param fp_ok boolean if the front panel UI is running ---@diagnostic disable-next-line: unused-local -function supervisor.comms(_version, num_reactors, cooling_conf, modem, dev_listen, svctl_listen, range) +function supervisor.comms(_version, num_reactors, cooling_conf, modem, dev_listen, svctl_listen, range, fp_ok) + -- print a log message to the terminal as long as the UI isn't running + local function println(message) if not fp_ok then util.println_ts(message) end end + local self = { last_est_acks = {} } @@ -42,8 +43,8 @@ function supervisor.comms(_version, num_reactors, cooling_conf, modem, dev_liste _conf_channels() - -- link modem to svsessions - svsessions.init(modem, num_reactors, cooling_conf) + -- pass modem, status, and config data to svsessions + svsessions.init(modem, fp_ok, num_reactors, cooling_conf) -- send an establish request response to a PLC/RTU ---@param dest integer From 24a72755439f94e5eecc3267642195a30fc5a064 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 3 Jun 2023 15:50:44 -0400 Subject: [PATCH 44/49] fixed trailing whitespace --- supervisor/panel/front_panel.lua | 2 +- supervisor/session/svsessions.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/supervisor/panel/front_panel.lua b/supervisor/panel/front_panel.lua index 8ebc448..8cdcf76 100644 --- a/supervisor/panel/front_panel.lua +++ b/supervisor/panel/front_panel.lua @@ -56,7 +56,7 @@ local function init(panel) modem.register(databus.ps, "has_modem", modem.update) - -- + -- -- about footer -- diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index a41658a..5d22e3d 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -318,7 +318,7 @@ function svsessions.establish_plc_session(local_port, remote_port, for_reactor, 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_ids.plc, + log.debug(util.c("established new PLC session to ", remote_port, " with ID ", self.next_ids.plc, " for reactor ", for_reactor)) databus.tx_plc_connected(for_reactor, version, remote_port) From b4932b33b6854b2c45b142da751717b176935004 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 3 Jun 2023 17:31:06 -0400 Subject: [PATCH 45/49] code cleanup --- graphics/elements/indicators/data.lua | 7 +++---- graphics/elements/listbox.lua | 6 +++--- install_manifest.json | 2 +- supervisor/databus.lua | 14 +++++++------- supervisor/startup.lua | 2 +- supervisor/supervisor.lua | 2 +- 6 files changed, 16 insertions(+), 17 deletions(-) diff --git a/graphics/elements/indicators/data.lua b/graphics/elements/indicators/data.lua index 6aa052a..9282a03 100644 --- a/graphics/elements/indicators/data.lua +++ b/graphics/elements/indicators/data.lua @@ -44,8 +44,9 @@ local function data(args) e.window.setCursorPos(1, 1) e.window.write(args.label) - local label_len = string.len(args.label) - local data_start = 1 + local value_color = e.fg_bg.fgd + local label_len = string.len(args.label) + local data_start = 1 local clear_width = args.width if label_len > 0 then @@ -53,8 +54,6 @@ local function data(args) clear_width = args.width - (label_len + 1) end - local value_color = e.fg_bg.fgd - -- on state change ---@param value any new value function e.on_update(value) diff --git a/graphics/elements/listbox.lua b/graphics/elements/listbox.lua index a5d5f20..87a274d 100644 --- a/graphics/elements/listbox.lua +++ b/graphics/elements/listbox.lua @@ -56,7 +56,7 @@ local function listbox(args) local mouse_last_y = 0 -- last reported y coordinate of drag -- draw scroll bar arrows, optionally showing one of them as pressed - ---@param pressed_arrow? integer arrow to show as pressed (1 = scroll up, 0 = neither, -1 = scroll down) + ---@param pressed_arrow? 1|0|-1 arrow to show as pressed (1 = scroll up, 0 = neither, -1 = scroll down) local function draw_arrows(pressed_arrow) local nav_fg_bg = args.nav_fg_bg or e.fg_bg local active_fg_bg = args.nav_active or nav_fg_bg @@ -200,7 +200,7 @@ local function listbox(args) end -- handle a child element having been added to the list - ---@param id string|integer element identifier + ---@param id element_id element identifier ---@param child graphics_element child element function e.on_added(id, child) table.insert(list, { id = id, e = child, y = 0, h = child.get_height() }) @@ -208,7 +208,7 @@ local function listbox(args) end -- handle a child element having been removed from the list - ---@param id string|integer element identifier + ---@param id element_id element identifier function e.on_removed(id) for idx, elem in ipairs(list) do if elem.id == id then diff --git a/install_manifest.json b/install_manifest.json index 819e6ee..a2f4b51 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.2", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.3.6", "rtu": "v1.2.6", "supervisor": "v0.16.6", "coordinator": "v0.15.6", "pocket": "alpha-v0.3.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/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.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/tabbar.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/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.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/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_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": 5775, "system": 1991, "common": 91102, "graphics": 144089, "lockbox": 100797, "reactor-plc": 95896, "rtu": 100988, "supervisor": 310870, "coordinator": 197544, "pocket": 36338}} \ No newline at end of file +{"versions": {"installer": "v1.2", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.3.6", "rtu": "v1.2.6", "supervisor": "v0.16.6", "coordinator": "v0.15.6", "pocket": "alpha-v0.3.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/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.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/tabbar.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/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.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/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_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": 5775, "system": 1991, "common": 91102, "graphics": 144082, "lockbox": 100797, "reactor-plc": 95896, "rtu": 100988, "supervisor": 310851, "coordinator": 197544, "pocket": 36338}} \ No newline at end of file diff --git a/supervisor/databus.lua b/supervisor/databus.lua index 88e4ed3..a1e947e 100644 --- a/supervisor/databus.lua +++ b/supervisor/databus.lua @@ -15,10 +15,10 @@ databus.ps = psil.create() function databus.heartbeat() databus.ps.toggle("heartbeat") end -- transmit firmware versions across the bus ----@param plc_v string supervisor version +---@param sv_v string supervisor version ---@param comms_v string comms version -function databus.tx_versions(plc_v, comms_v) - databus.ps.publish("version", plc_v) +function databus.tx_versions(sv_v, comms_v) + databus.ps.publish("version", sv_v) databus.ps.publish("comms_version", comms_v) end @@ -38,7 +38,7 @@ function databus.tx_plc_connected(reactor_id, fw, channel) databus.ps.publish("plc_" .. reactor_id .. "_chan", tostring(channel)) end --- transmit PLC session connection state +-- transmit PLC disconnected ---@param reactor_id integer reactor unit ID function databus.tx_plc_disconnected(reactor_id) databus.ps.publish("plc_" .. reactor_id .. "_fw", " ------- ") @@ -110,7 +110,7 @@ function databus.tx_crd_connected(fw, channel) databus.ps.publish("crd_chan", tostring(channel)) end --- transmit coordinator session connection state +-- transmit coordinator disconnected function databus.tx_crd_disconnected() databus.ps.publish("crd_fw", " ------- ") databus.ps.publish("crd_conn", false) @@ -133,7 +133,7 @@ function databus.tx_crd_rtt(rtt) end end --- transmit PDG firmware version and session connection state +-- transmit PKT firmware version and PDG session connection state ---@param session_id integer PDG session ---@param fw string firmware version ---@param channel integer PDG remote port @@ -143,7 +143,7 @@ function databus.tx_pdg_connected(session_id, fw, channel) pgi.create_pdg_entry(session_id) end --- transmit PDG disconnected +-- transmit PDG session disconnected ---@param session_id integer PDG session function databus.tx_pdg_disconnected(session_id) pgi.delete_pdg_entry(session_id) diff --git a/supervisor/startup.lua b/supervisor/startup.lua index d0f95a8..06853ef 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -195,7 +195,7 @@ local function main() -- check for termination request if event == "terminate" or ppm.should_terminate() then - println_ts("closing sesssions...") + println_ts("closing sessions...") log.info("terminate requested, closing sessions...") svsessions.close_all() log.info("sessions closed") diff --git a/supervisor/supervisor.lua b/supervisor/supervisor.lua index 6a27c0e..874aaa9 100644 --- a/supervisor/supervisor.lua +++ b/supervisor/supervisor.lua @@ -308,7 +308,7 @@ function supervisor.comms(_version, num_reactors, cooling_conf, modem, dev_liste -- this is an attempt to establish a new pocket diagnostic session local s_id = svsessions.establish_pdg_session(l_port, r_port, firmware_v) - println(util.c("PDG (", firmware_v, ") [:", r_port, "] \xbb connected")) + 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 }) From 8d248408d42ea3d9f783e0cdfc878223cc1dbb42 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 3 Jun 2023 17:40:57 -0400 Subject: [PATCH 46/49] #247 renamed tcallbackdsp to tcd and added handler to RTU --- coordinator/startup.lua | 28 ++++++++++---------- coordinator/ui/components/processctl.lua | 2 +- graphics/elements/animations/waiting.lua | 2 +- graphics/elements/controls/hazard_button.lua | 2 +- graphics/elements/controls/push_button.lua | 2 +- graphics/elements/controls/sidebar.lua | 2 +- graphics/elements/listbox.lua | 2 +- graphics/flasher.lua | 2 +- install_manifest.json | 2 +- pocket/startup.lua | 24 ++++++++--------- reactor-plc/startup.lua | 2 +- reactor-plc/threads.lua | 18 ++++++------- rtu/startup.lua | 2 +- rtu/threads.lua | 4 +++ scada-common/{tcallbackdsp.lua => tcd.lua} | 14 +++++----- supervisor/startup.lua | 4 +-- 16 files changed, 58 insertions(+), 54 deletions(-) rename scada-common/{tcallbackdsp.lua => tcd.lua} (91%) diff --git a/coordinator/startup.lua b/coordinator/startup.lua index c0addf1..a95b30c 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -4,23 +4,23 @@ require("/initenv").init_env() -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 crash = require("scada-common.crash") +local log = require("scada-common.log") +local ppm = require("scada-common.ppm") +local tcd = require("scada-common.tcd") +local util = require("scada-common.util") -local core = require("graphics.core") +local core = require("graphics.core") -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 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 apisessions = require("coordinator.session.apisessions") +local apisessions = require("coordinator.session.apisessions") -local COORDINATOR_VERSION = "v0.15.6" +local COORDINATOR_VERSION = "v0.15.7" local println = util.println local println_ts = util.println_ts @@ -334,7 +334,7 @@ local function main() apisessions.check_all_watchdogs(param1) -- notify timer callback dispatcher - tcallbackdsp.handle(param1) + tcd.handle(param1) end elseif event == "modem_message" then -- got a packet diff --git a/coordinator/ui/components/processctl.lua b/coordinator/ui/components/processctl.lua index 7e0016a..eaeb8ab 100644 --- a/coordinator/ui/components/processctl.lua +++ b/coordinator/ui/components/processctl.lua @@ -1,4 +1,4 @@ -local tcd = require("scada-common.tcallbackdsp") +local tcd = require("scada-common.tcd") local util = require("scada-common.util") local iocontrol = require("coordinator.iocontrol") diff --git a/graphics/elements/animations/waiting.lua b/graphics/elements/animations/waiting.lua index 9dc089f..286c82e 100644 --- a/graphics/elements/animations/waiting.lua +++ b/graphics/elements/animations/waiting.lua @@ -1,6 +1,6 @@ -- Loading/Waiting Animation Graphics Element -local tcd = require("scada-common.tcallbackdsp") +local tcd = require("scada-common.tcd") local element = require("graphics.element") diff --git a/graphics/elements/controls/hazard_button.lua b/graphics/elements/controls/hazard_button.lua index 6ffe74d..4745f4f 100644 --- a/graphics/elements/controls/hazard_button.lua +++ b/graphics/elements/controls/hazard_button.lua @@ -1,6 +1,6 @@ -- Hazard-bordered Button Graphics Element -local tcd = require("scada-common.tcallbackdsp") +local tcd = require("scada-common.tcd") local util = require("scada-common.util") local core = require("graphics.core") diff --git a/graphics/elements/controls/push_button.lua b/graphics/elements/controls/push_button.lua index 564ad3c..e6f4920 100644 --- a/graphics/elements/controls/push_button.lua +++ b/graphics/elements/controls/push_button.lua @@ -1,6 +1,6 @@ -- Button Graphics Element -local tcd = require("scada-common.tcallbackdsp") +local tcd = require("scada-common.tcd") local core = require("graphics.core") local element = require("graphics.element") diff --git a/graphics/elements/controls/sidebar.lua b/graphics/elements/controls/sidebar.lua index b3221b3..d43317a 100644 --- a/graphics/elements/controls/sidebar.lua +++ b/graphics/elements/controls/sidebar.lua @@ -1,6 +1,6 @@ -- Sidebar Graphics Element -local tcd = require("scada-common.tcallbackdsp") +local tcd = require("scada-common.tcd") local core = require("graphics.core") local element = require("graphics.element") diff --git a/graphics/elements/listbox.lua b/graphics/elements/listbox.lua index 87a274d..e37a772 100644 --- a/graphics/elements/listbox.lua +++ b/graphics/elements/listbox.lua @@ -1,6 +1,6 @@ -- Scroll-able List Box Display Graphics Element -local tcd = require("scada-common.tcallbackdsp") +local tcd = require("scada-common.tcd") local core = require("graphics.core") local element = require("graphics.element") diff --git a/graphics/flasher.lua b/graphics/flasher.lua index 0a3d9ea..520fba7 100644 --- a/graphics/flasher.lua +++ b/graphics/flasher.lua @@ -2,7 +2,7 @@ -- Indicator Light Flasher -- -local tcd = require("scada-common.tcallbackdsp") +local tcd = require("scada-common.tcd") local flasher = {} diff --git a/install_manifest.json b/install_manifest.json index a2f4b51..249b201 100644 --- a/install_manifest.json +++ b/install_manifest.json @@ -1 +1 @@ -{"versions": {"installer": "v1.2", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.3.6", "rtu": "v1.2.6", "supervisor": "v0.16.6", "coordinator": "v0.15.6", "pocket": "alpha-v0.3.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/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.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/tabbar.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/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.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/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_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": 5775, "system": 1991, "common": 91102, "graphics": 144082, "lockbox": 100797, "reactor-plc": 95896, "rtu": 100988, "supervisor": 310851, "coordinator": 197544, "pocket": 36338}} \ No newline at end of file +{"versions": {"installer": "v1.2", "bootloader": "0.2", "comms": "1.4.1", "reactor-plc": "v1.3.7", "rtu": "v1.2.7", "supervisor": "v0.16.7", "coordinator": "v0.15.7", "pocket": "alpha-v0.3.7"}, "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/rsio.lua", "scada-common/constants.lua", "scada-common/mqueue.lua", "scada-common/tcd.lua", "scada-common/crash.lua", "scada-common/log.lua", "scada-common/types.lua", "scada-common/util.lua"], "graphics": ["graphics/element.lua", "graphics/events.lua", "graphics/flasher.lua", "graphics/core.lua", "graphics/elements/listbox.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/tabbar.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/renderer.lua", "supervisor/databus.lua", "supervisor/supervisor.lua", "supervisor/unit.lua", "supervisor/config.lua", "supervisor/startup.lua", "supervisor/unitlogic.lua", "supervisor/facility.lua", "supervisor/panel/pgi.lua", "supervisor/panel/front_panel.lua", "supervisor/panel/style.lua", "supervisor/panel/components/rtu_entry.lua", "supervisor/panel/components/pdg_entry.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/conn_waiting.lua", "pocket/ui/pages/turbine_page.lua", "pocket/ui/pages/reactor_page.lua", "pocket/ui/pages/home_page.lua", "pocket/ui/pages/unit_page.lua", "pocket/ui/pages/boiler_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": 5766, "system": 1991, "common": 91039, "graphics": 144028, "lockbox": 100797, "reactor-plc": 95846, "rtu": 101207, "supervisor": 310842, "coordinator": 197505, "pocket": 36280}} \ No newline at end of file diff --git a/pocket/startup.lua b/pocket/startup.lua index 50862d1..32d4737 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -4,20 +4,20 @@ require("/initenv").init_env() -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 crash = require("scada-common.crash") +local log = require("scada-common.log") +local ppm = require("scada-common.ppm") +local tcd = require("scada-common.tcd") +local util = require("scada-common.util") -local core = require("graphics.core") +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") +local config = require("pocket.config") +local coreio = require("pocket.coreio") +local pocket = require("pocket.pocket") +local renderer = require("pocket.renderer") -local POCKET_VERSION = "alpha-v0.3.6" +local POCKET_VERSION = "alpha-v0.3.7" local println = util.println local println_ts = util.println_ts @@ -145,7 +145,7 @@ local function main() else -- a non-clock/main watchdog timer event -- notify timer callback dispatcher - tcallbackdsp.handle(param1) + tcd.handle(param1) end elseif event == "modem_message" then -- got a packet diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 3e8861b..812ed45 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.3.6" +local R_PLC_VERSION = "v1.3.7" local println = util.println local println_ts = util.println_ts diff --git a/reactor-plc/threads.lua b/reactor-plc/threads.lua index 8dbea6d..b9c986d 100644 --- a/reactor-plc/threads.lua +++ b/reactor-plc/threads.lua @@ -1,13 +1,13 @@ -local log = require("scada-common.log") -local mqueue = require("scada-common.mqueue") -local ppm = require("scada-common.ppm") -local tcallbackdsp = require("scada-common.tcallbackdsp") -local util = require("scada-common.util") +local log = require("scada-common.log") +local mqueue = require("scada-common.mqueue") +local ppm = require("scada-common.ppm") +local tcd = require("scada-common.tcd") +local util = require("scada-common.util") -local databus = require("reactor-plc.databus") -local renderer = require("reactor-plc.renderer") +local databus = require("reactor-plc.databus") +local renderer = require("reactor-plc.renderer") -local core = require("graphics.core") +local core = require("graphics.core") local threads = {} @@ -157,7 +157,7 @@ function threads.thread__main(smem, init) smem.q.mq_rps.push_command(MQ__RPS_CMD.TRIP_TIMEOUT) elseif event == "timer" then -- notify timer callback dispatcher if no other timer case claimed this event - tcallbackdsp.handle(param1) + tcd.handle(param1) elseif event == "peripheral_detach" then -- peripheral disconnect local type, device = ppm.handle_unmount(param1) diff --git a/rtu/startup.lua b/rtu/startup.lua index 86c3db2..451a06d 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.2.6" +local RTU_VERSION = "v1.2.7" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE diff --git a/rtu/threads.lua b/rtu/threads.lua index 046525c..fdb82b3 100644 --- a/rtu/threads.lua +++ b/rtu/threads.lua @@ -1,6 +1,7 @@ local log = require("scada-common.log") local mqueue = require("scada-common.mqueue") local ppm = require("scada-common.ppm") +local tcd = require("scada-common.tcd") local types = require("scada-common.types") local util = require("scada-common.util") @@ -82,6 +83,9 @@ function threads.thread__main(smem) elseif event == "timer" and conn_watchdog.is_timer(param1) then -- haven't heard from server recently? unlink rtu_comms.unlink(rtu_state) + elseif event == "timer" then + -- notify timer callback dispatcher if no other timer case claimed this event + tcd.handle(param1) elseif event == "peripheral_detach" then -- handle loss of a device local type, device = ppm.handle_unmount(param1) diff --git a/scada-common/tcallbackdsp.lua b/scada-common/tcd.lua similarity index 91% rename from scada-common/tcallbackdsp.lua rename to scada-common/tcd.lua index 3f8f07a..f5ff0e5 100644 --- a/scada-common/tcallbackdsp.lua +++ b/scada-common/tcd.lua @@ -5,14 +5,14 @@ local log = require("scada-common.log") local util = require("scada-common.util") -local tcallbackdsp = {} +local tcd = {} local registry = {} -- request a function to be called after the specified time ---@param time number seconds ---@param f function callback function -function tcallbackdsp.dispatch(time, f) +function tcd.dispatch(time, f) local timer = util.start_timer(time) registry[timer] = { callback = f, @@ -24,7 +24,7 @@ end -- request a function to be called after the specified time, aborting any registered instances of that function reference ---@param time number seconds ---@param f function callback function -function tcallbackdsp.dispatch_unique(time, f) +function tcd.dispatch_unique(time, f) -- cancel if already registered for timer, entry in pairs(registry) do if entry.callback == f then @@ -47,7 +47,7 @@ end -- abort a requested callback ---@param f function callback function -function tcallbackdsp.abort(f) +function tcd.abort(f) for timer, entry in pairs(registry) do if entry.callback == f then -- cancel event and remove from registry (even if it fires it won't call) @@ -59,7 +59,7 @@ end -- lookup a timer event and execute the callback if found ---@param event integer timer event timer ID -function tcallbackdsp.handle(event) +function tcd.handle(event) if registry[event] ~= nil then local callback = registry[event].callback -- clear first so that dispatch_unique call from inside callback won't throw a debug message @@ -70,7 +70,7 @@ end -- identify any overdo callbacks
-- prints to log debug output -function tcallbackdsp.diagnostics() +function tcd.diagnostics() for timer, entry in pairs(registry) do if entry.expiry < util.time_s() then local overtime = util.time_s() - entry.expiry @@ -82,4 +82,4 @@ function tcallbackdsp.diagnostics() end end -return tcallbackdsp +return tcd diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 06853ef..c3f28ad 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -8,7 +8,7 @@ local crash = require("scada-common.crash") local comms = require("scada-common.comms") local log = require("scada-common.log") local ppm = require("scada-common.ppm") -local tcd = require("scada-common.tcallbackdsp") +local tcd = require("scada-common.tcd") local util = require("scada-common.util") local core = require("graphics.core") @@ -20,7 +20,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.16.6" +local SUPERVISOR_VERSION = "v0.16.7" local println = util.println local println_ts = util.println_ts From 351842c9a1e731f20560264bc4b47d4549f53522 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 3 Jun 2023 17:44:32 -0400 Subject: [PATCH 47/49] updated RTU to say STATUS instead of POWER on first LED --- rtu/panel/front_panel.lua | 2 +- rtu/startup.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rtu/panel/front_panel.lua b/rtu/panel/front_panel.lua index 4c4aa78..606abbb 100644 --- a/rtu/panel/front_panel.lua +++ b/rtu/panel/front_panel.lua @@ -44,7 +44,7 @@ local function init(panel, units) 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 on = LED{parent=system,label="STATUS",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() diff --git a/rtu/startup.lua b/rtu/startup.lua index 451a06d..4cb90ac 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.2.7" +local RTU_VERSION = "v1.2.8" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE From 0b939be412b1a1064d2494b351a985ba40199e93 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 3 Jun 2023 17:59:20 -0400 Subject: [PATCH 48/49] #231 renamed unit a_ functions to auto_ --- supervisor/facility.lua | 14 +++++++------- supervisor/startup.lua | 2 +- supervisor/unit.lua | 16 ++++++++-------- supervisor/unitlogic.lua | 2 +- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/supervisor/facility.lua b/supervisor/facility.lua index f37de26..e3b8059 100644 --- a/supervisor/facility.lua +++ b/supervisor/facility.lua @@ -128,7 +128,7 @@ function facility.new(num_reactors, cooling_conf) for i = 1, #self.prio_defs do local units = self.prio_defs[i] for u = 1, #units do - all_ramped = all_ramped and units[u].a_ramp_complete() + all_ramped = all_ramped and units[u].auto_ramp_complete() end end @@ -159,7 +159,7 @@ function facility.new(num_reactors, cooling_conf) local u = units[id] ---@type reactor_unit local ctl = u.get_control_inf() - local lim_br100 = u.a_get_effective_limit() + local lim_br100 = u.auto_get_effective_limit() if abort_on_fault and (lim_br100 ~= ctl.lim_br100) then -- effective limit differs from set limit, unit is degraded @@ -183,7 +183,7 @@ function facility.new(num_reactors, cooling_conf) unallocated = math.max(0, unallocated - ctl.br100) - if last ~= ctl.br100 then u.a_commit_br100(ramp) end + if last ~= ctl.br100 then u.auto_commit_br100(ramp) end end end end @@ -320,7 +320,7 @@ function facility.new(num_reactors, cooling_conf) self.start_fail = START_STATUS.BLADE_MISMATCH end - if self.start_fail == START_STATUS.OK then u.a_engage() end + if self.start_fail == START_STATUS.OK then u.auto_engage() end self.max_burn_combined = self.max_burn_combined + (u.get_control_inf().lim_br100 / 100.0) end @@ -340,7 +340,7 @@ function facility.new(num_reactors, cooling_conf) -- use manual SCRAM since inactive was requested, and automatic SCRAM trips an alarm for _, u in pairs(self.prio_defs[i]) do u.scram() - u.a_disengage() + u.auto_disengage() end end @@ -601,7 +601,7 @@ function facility.new(num_reactors, cooling_conf) -- SCRAM all units for i = 1, #self.prio_defs do for _, u in pairs(self.prio_defs[i]) do - u.a_scram() + u.auto_scram() end end @@ -653,7 +653,7 @@ function facility.new(num_reactors, cooling_conf) -- reset PLC RPS trips if we should for i = 1, #self.units do local u = self.units[i] ---@type reactor_unit - u.a_cond_rps_reset() + u.auto_cond_rps_reset() end end end diff --git a/supervisor/startup.lua b/supervisor/startup.lua index c3f28ad..ff4a4fe 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -20,7 +20,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.16.7" +local SUPERVISOR_VERSION = "v0.16.8" local println = util.println local println_ts = util.println_ts diff --git a/supervisor/unit.lua b/supervisor/unit.lua index 0cccc48..0d7246a 100644 --- a/supervisor/unit.lua +++ b/supervisor/unit.lua @@ -506,7 +506,7 @@ function unit.new(reactor_id, num_boilers, num_turbines) --#region -- engage automatic control - function public.a_engage() + function public.auto_engage() self.auto_engaged = true if self.plc_i ~= nil then self.plc_i.auto_lock(true) @@ -514,7 +514,7 @@ function unit.new(reactor_id, num_boilers, num_turbines) end -- disengage automatic control - function public.a_disengage() + function public.auto_disengage() self.auto_engaged = false if self.plc_i ~= nil then self.plc_i.auto_lock(false) @@ -526,7 +526,7 @@ function unit.new(reactor_id, num_boilers, num_turbines) -- if it is degraded or not ready, the limit will be 0 ---@nodiscard ---@return integer lim_br100 - function public.a_get_effective_limit() + function public.auto_get_effective_limit() if (not self.db.control.ready) or self.db.control.degraded or self.plc_cache.rps_trip then self.db.control.br100 = 0 return 0 @@ -537,7 +537,7 @@ function unit.new(reactor_id, num_boilers, num_turbines) -- set the automatic burn rate based on the last set burn rate in 100ths ---@param ramp boolean true to ramp to rate, false to set right away - function public.a_commit_br100(ramp) + function public.auto_commit_br100(ramp) if self.auto_engaged then if self.plc_i ~= nil then self.plc_i.auto_set_burn(self.db.control.br100 / 100, ramp) @@ -550,16 +550,16 @@ function unit.new(reactor_id, num_boilers, num_turbines) -- check if ramping is complete (burn rate is same as target) ---@nodiscard ---@return boolean complete - function public.a_ramp_complete() + function public.auto_ramp_complete() if self.plc_i ~= nil then return self.plc_i.is_ramp_complete() or (self.plc_i.get_status().act_burn_rate == 0 and self.db.control.br100 == 0) or - public.a_get_effective_limit() == 0 + public.auto_get_effective_limit() == 0 else return true end end -- perform an automatic SCRAM - function public.a_scram() + function public.auto_scram() if self.plc_s ~= nil then self.db.control.br100 = 0 self.plc_s.in_queue.push_command(PLC_S_CMDS.ASCRAM) @@ -567,7 +567,7 @@ function unit.new(reactor_id, num_boilers, num_turbines) end -- queue a command to clear timeout/auto-scram if set - function public.a_cond_rps_reset() + function public.auto_cond_rps_reset() if self.plc_s ~= nil and self.plc_i ~= nil and (not self.auto_was_alarmed) and (not self.emcool_opened) then local rps = self.plc_i.get_rps() if rps.timeout or rps.automatic then diff --git a/supervisor/unitlogic.lua b/supervisor/unitlogic.lua index ca97181..fab67f3 100644 --- a/supervisor/unitlogic.lua +++ b/supervisor/unitlogic.lua @@ -549,7 +549,7 @@ function logic.update_auto_safety(public, self) end if alarmed and not self.plc_cache.rps_status.automatic then - public.a_scram() + public.auto_scram() end self.auto_was_alarmed = alarmed From 38fc7189ba7c3faa9cab74dc5e32a73ad38d5892 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sat, 3 Jun 2023 18:51:59 -0400 Subject: [PATCH 49/49] #245 fixed coordinator missing pocket packets and connection timeouts --- coordinator/coordinator.lua | 7 ++++--- coordinator/session/api.lua | 2 -- coordinator/startup.lua | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/coordinator/coordinator.lua b/coordinator/coordinator.lua index d7e58f7..55c6356 100644 --- a/coordinator/coordinator.lua +++ b/coordinator/coordinator.lua @@ -335,12 +335,13 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range tick_dmesg_waiting(math.max(0, timeout_s - (util.time_s() - start))) _send_establish() clock.start() + elseif event == "timer" then + -- keep checking watchdog timers + apisessions.check_all_watchdogs(p1) elseif event == "modem_message" then -- handle message local packet = public.parse_packet(p1, p2, p3, p4, p5) - if packet ~= nil and packet.type == SCADA_MGMT_TYPE.ESTABLISH then - public.handle_packet(packet) - end + public.handle_packet(packet) elseif event == "terminate" then terminated = true break diff --git a/coordinator/session/api.lua b/coordinator/session/api.lua index 8f21483..4ba7383 100644 --- a/coordinator/session/api.lua +++ b/coordinator/session/api.lua @@ -117,8 +117,6 @@ function api.new_session(id, in_queue, out_queue, timeout) -- 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 diff --git a/coordinator/startup.lua b/coordinator/startup.lua index a95b30c..4a08166 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.15.7" +local COORDINATOR_VERSION = "v0.15.8" local println = util.println local println_ts = util.println_ts