mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
#184 supervisor graphics updates for new system, added PLC and CRD pages on supervisor front panel
This commit is contained in:
parent
4aba79f232
commit
ece7c0fe9a
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 },
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user