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
-- 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 .. ")")
log.warning("insufficient monitors present (need " .. num_units + 1 .. ")")
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
function public.close()
sv_watchdog.cancel()
self.sv_linked = false
_send_sv(PROTOCOLS.SCADA_MGMT, SCADA_MGMT_TYPES.CLOSE, {})
end

View File

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

View File

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