addresed monitor disconnect to-do, changed monitor requirement to minimum, fixed up connect/reconnect for #92

This commit is contained in:
Mikayla Fischler 2022-09-13 16:07:21 -04:00
parent 265368f9b2
commit c47e0044b1
3 changed files with 103 additions and 43 deletions

View File

@ -58,7 +58,7 @@ function coordinator.configure_monitors(num_units)
end end
-- we need a certain number of monitors (1 per unit + 1 primary display) -- we need a certain number of monitors (1 per unit + 1 primary display)
if #names ~= num_units + 1 then if #names < num_units + 1 then
println("not enough monitors connected (need " .. num_units + 1 .. ")") println("not enough monitors connected (need " .. num_units + 1 .. ")")
log.warning("insufficient monitors present (need " .. num_units + 1 .. ")") log.warning("insufficient monitors present (need " .. num_units + 1 .. ")")
return false return false
@ -258,6 +258,7 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, sv_wa
-- close the connection to the server -- close the connection to the server
function public.close() function public.close()
sv_watchdog.cancel() sv_watchdog.cancel()
self.sv_linked = false
_send_sv(PROTOCOLS.SCADA_MGMT, SCADA_MGMT_TYPES.CLOSE, {}) _send_sv(PROTOCOLS.SCADA_MGMT, SCADA_MGMT_TYPES.CLOSE, {})
end end

View File

@ -54,6 +54,25 @@ function renderer.set_displays(monitors)
engine.monitors = monitors engine.monitors = monitors
end end
-- check if the renderer is configured to use a given monitor peripheral
---@param periph table peripheral
---@return boolean is_used
function renderer.is_monitor_used(periph)
if engine.monitors ~= nil then
if engine.monitors.primary == periph then
return true
else
for i = 1, #engine.monitors.unit_displays do
if engine.monitors.unit_displays[i] == periph then
return true
end
end
end
end
return false
end
-- reset all displays in use by the renderer -- reset all displays in use by the renderer
---@param recolor? boolean true to use color palette from style ---@param recolor? boolean true to use color palette from style
function renderer.reset(recolor) function renderer.reset(recolor)
@ -76,40 +95,44 @@ end
-- start the coordinator GUI -- start the coordinator GUI
function renderer.start_ui() function renderer.start_ui()
-- hide dmesg if not engine.ui_ready then
engine.dmesg_window.setVisible(false) -- hide dmesg
engine.dmesg_window.setVisible(false)
-- show main view on main monitor -- show main view on main monitor
ui.main_layout = main_view(engine.monitors.primary) ui.main_layout = main_view(engine.monitors.primary)
-- show unit views on unit displays -- show unit views on unit displays
for id, monitor in pairs(engine.monitors.unit_displays) do for id, monitor in pairs(engine.monitors.unit_displays) do
table.insert(ui.unit_layouts, unit_view(monitor, id)) table.insert(ui.unit_layouts, unit_view(monitor, id))
end
-- report ui as ready
engine.ui_ready = true
end end
-- report ui as ready
engine.ui_ready = true
end end
-- close out the UI -- close out the UI
function renderer.close_ui() function renderer.close_ui()
-- report ui as not ready if engine.ui_ready then
engine.ui_ready = false -- report ui as not ready
engine.ui_ready = false
-- hide to stop animation callbacks -- hide to stop animation callbacks
ui.main_layout.hide() ui.main_layout.hide()
for i = 1, #ui.unit_layouts do for i = 1, #ui.unit_layouts do
ui.unit_layouts[i].hide() ui.unit_layouts[i].hide()
engine.monitors.unit_displays[i].clear() engine.monitors.unit_displays[i].clear()
end
-- clear root UI elements
ui.main_layout = nil
ui.unit_layouts = {}
-- re-draw dmesg
engine.dmesg_window.setVisible(true)
engine.dmesg_window.redraw()
end end
-- clear root UI elements
ui.main_layout = nil
ui.unit_layouts = {}
-- re-draw dmesg
engine.dmesg_window.setVisible(true)
engine.dmesg_window.redraw()
end end
-- is the UI ready? -- is the UI ready?

View File

@ -16,7 +16,7 @@ local config = require("coordinator.config")
local coordinator = require("coordinator.coordinator") local coordinator = require("coordinator.coordinator")
local renderer = require("coordinator.renderer") local renderer = require("coordinator.renderer")
local COORDINATOR_VERSION = "alpha-v0.4.10" local COORDINATOR_VERSION = "alpha-v0.4.11"
local print = util.print local print = util.print
local println = util.println local println = util.println
@ -58,7 +58,7 @@ log.info("========================================")
println(">> SCADA Coordinator " .. COORDINATOR_VERSION .. " <<") println(">> SCADA Coordinator " .. COORDINATOR_VERSION .. " <<")
---------------------------------------- ----------------------------------------
-- startup -- system startup
---------------------------------------- ----------------------------------------
-- mount connected devices -- mount connected devices
@ -83,6 +83,10 @@ log_graphics("displays connected and reset")
log_sys("system start on " .. os.date("%c")) log_sys("system start on " .. os.date("%c"))
log_boot("starting " .. COORDINATOR_VERSION) log_boot("starting " .. COORDINATOR_VERSION)
----------------------------------------
-- setup communications
----------------------------------------
-- get the communications modem -- get the communications modem
local modem = ppm.get_wireless_modem() local modem = ppm.get_wireless_modem()
if modem == nil then if modem == nil then
@ -108,6 +112,10 @@ log_comms("comms initialized")
local MAIN_CLOCK = 0.5 local MAIN_CLOCK = 0.5
local loop_clock = util.new_clock(MAIN_CLOCK) local loop_clock = util.new_clock(MAIN_CLOCK)
----------------------------------------
-- connect to the supervisor
----------------------------------------
-- attempt to connect to the supervisor or exit -- attempt to connect to the supervisor or exit
local function init_connect_sv() local function init_connect_sv()
local tick_waiting, task_done = log_comms_connecting("attempting to connect to configured supervisor on channel " .. config.SCADA_SV_PORT) local tick_waiting, task_done = log_comms_connecting("attempting to connect to configured supervisor on channel " .. config.SCADA_SV_PORT)
@ -115,14 +123,20 @@ local function init_connect_sv()
-- attempt to establish a connection with the supervisory computer -- attempt to establish a connection with the supervisory computer
if not coord_comms.sv_connect(60, tick_waiting, task_done) then if not coord_comms.sv_connect(60, tick_waiting, task_done) then
log_comms("supervisor connection failed") log_comms("supervisor connection failed")
println("boot> failed to connect to supervisor")
log.fatal("failed to connect to supervisor") log.fatal("failed to connect to supervisor")
log_sys("system shutdown") return false
return
end end
return true
end end
init_connect_sv() if not init_connect_sv() then
println("boot> failed to connect to supervisor")
log_sys("system shutdown")
return
else
log_sys("supervisor connected, proceeding to UI start")
end
---------------------------------------- ----------------------------------------
-- start the UI -- start the UI
@ -158,10 +172,14 @@ local ui_ok = init_start_ui()
-- main event loop -- main event loop
---------------------------------------- ----------------------------------------
local no_modem = false
-- start connection watchdog -- start connection watchdog
conn_watchdog.feed() conn_watchdog.feed()
log.debug("boot> conn watchdog started") log.debug("boot> conn watchdog started")
log_sys("system started successfully")
-- event loop -- event loop
-- ui_ok will never change in this loop, same as while true or exit if UI start failed -- ui_ok will never change in this loop, same as while true or exit if UI start failed
while ui_ok do while ui_ok do
@ -175,18 +193,28 @@ while ui_ok do
if type == "modem" then if type == "modem" then
-- we only really care if this is our wireless modem -- we only really care if this is our wireless modem
if device == modem then if device == modem then
no_modem = true
log_sys("comms modem disconnected") log_sys("comms modem disconnected")
println_ts("wireless modem disconnected!") println_ts("wireless modem disconnected!")
log.error("comms modem disconnected!") log.error("comms modem disconnected!")
-- close out UI -- close out UI
renderer.close_ui() renderer.close_ui()
-- alert user to status
log_sys("awaiting comms modem reconnect...")
else else
log_sys("non-comms modem disconnected") log_sys("non-comms modem disconnected")
log.warning("non-comms modem disconnected") log.warning("non-comms modem disconnected")
end end
elseif type == "monitor" then elseif type == "monitor" then
---@todo: handle monitor loss if renderer.is_monitor_used(device) then
-- "halt and catch fire" style handling
log_sys("lost a configured monitor, system will now exit")
break
else
log_sys("lost unused monitor, ignoring")
end
end end
end end
elseif event == "peripheral" then elseif event == "peripheral" then
@ -196,6 +224,7 @@ while ui_ok do
if type == "modem" then if type == "modem" then
if device.isWireless() then if device.isWireless() then
-- reconnected modem -- reconnected modem
no_modem = false
modem = device modem = device
coord_comms.reconnect_modem(modem) coord_comms.reconnect_modem(modem)
@ -203,13 +232,13 @@ while ui_ok do
println_ts("wireless modem reconnected.") println_ts("wireless modem reconnected.")
-- re-init system -- re-init system
init_connect_sv() if not init_connect_sv() then break end
ui_ok = init_start_ui() ui_ok = init_start_ui()
else else
log_sys("wired modem reconnected") log_sys("wired modem reconnected")
end end
elseif type == "monitor" then elseif type == "monitor" then
---@todo: handle monitor reconnect -- not supported, system will exit on loss of in-use monitors
end end
end end
elseif event == "timer" then elseif event == "timer" then
@ -231,9 +260,11 @@ while ui_ok do
coord_comms.close() coord_comms.close()
renderer.close_ui() renderer.close_ui()
-- try to re-connect to the supervisor if not no_modem then
init_connect_sv() -- try to re-connect to the supervisor
ui_ok = init_start_ui() if not init_connect_sv() then break end
ui_ok = init_start_ui()
end
else else
-- a non-clock/main watchdog timer event -- a non-clock/main watchdog timer event
@ -250,13 +281,17 @@ while ui_ok do
-- check if it was a disconnect -- check if it was a disconnect
if not coord_comms.is_linked() then if not coord_comms.is_linked() then
log_comms("supervisor closed connection")
-- close connection and UI -- close connection and UI
coord_comms.close() coord_comms.close()
renderer.close_ui() renderer.close_ui()
-- try to re-connect to the supervisor if not no_modem then
init_connect_sv() -- try to re-connect to the supervisor
ui_ok = init_start_ui() if not init_connect_sv() then break end
ui_ok = init_start_ui()
end
end end
elseif event == "monitor_touch" then elseif event == "monitor_touch" then
-- handle a monitor touch event -- handle a monitor touch event
@ -265,10 +300,11 @@ while ui_ok do
-- check for termination request -- check for termination request
if event == "terminate" or ppm.should_terminate() then if event == "terminate" or ppm.should_terminate() then
log_comms("terminate requested, closing supervisor connection") println_ts("terminate requested, closing connections...")
log_comms("terminate requested, closing supervisor connection...")
coord_comms.close() coord_comms.close()
log_comms("supervisor connection closed")
log_comms("closing api sessions...") log_comms("closing api sessions...")
println_ts("closing api sessions...")
apisessions.close_all() apisessions.close_all()
log_comms("api sessions closed") log_comms("api sessions closed")
break break