From 25207f39c06e299e6e4b152c7592aef0e58c0b44 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Fri, 7 Nov 2025 17:43:12 +0000 Subject: [PATCH] #634 moved most monitor connect handling to the backplane and made display indicators on the front panel 3-state --- coordinator/backplane.lua | 61 ++++++++++++++++++++++----- coordinator/iocontrol.lua | 1 + coordinator/renderer.lua | 48 +++++---------------- coordinator/threads.lua | 6 +-- coordinator/ui/layout/front_panel.lua | 16 +++---- 5 files changed, 71 insertions(+), 61 deletions(-) diff --git a/coordinator/backplane.lua b/coordinator/backplane.lua index 4134b14..f0f7313 100644 --- a/coordinator/backplane.lua +++ b/coordinator/backplane.lua @@ -80,7 +80,7 @@ function backplane.init_displays(config) log.info("BKPLN: DISPLAY LINK_" .. util.trinary(disp, "UP", "DOWN") .. " MAIN/" .. iface) - iocontrol.fp_monitor_state("main", disp ~= nil) + iocontrol.fp_monitor_state("main", util.trinary(disp, 2, 1)) if not disp then return false, "Main monitor is not connected." @@ -103,7 +103,7 @@ function backplane.init_displays(config) log.info("BKPLN: DISPLAY LINK_" .. util.trinary(disp, "UP", "DOWN") .. " FLOW/" .. iface) - iocontrol.fp_monitor_state("flow", disp ~= nil) + iocontrol.fp_monitor_state("flow", util.trinary(disp, 2, 1)) if not disp then return false, "Flow monitor is not connected." @@ -127,7 +127,7 @@ function backplane.init_displays(config) log.info("BKPLN: DISPLAY LINK_" .. util.trinary(disp, "UP", "DOWN") .. " UNIT_" .. i .. "/" .. iface) - iocontrol.fp_monitor_state(i, disp ~= nil) + iocontrol.fp_monitor_state(i, util.trinary(disp, 2, 1)) if not disp then return false, "Unit " .. i .. " monitor is not connected." @@ -297,7 +297,46 @@ function backplane.attach(type, device, iface) end elseif type == "monitor" then ---@cast device Monitor - _bp.smem.q.mq_render.push_data(MQ__RENDER_DATA.MON_CONNECT, { name = iface, device = device }) + + local is_used = false + + log.info("BKPLN: DISPLAY LINK_UP " .. iface) + + if _bp.displays.main_iface == iface then + is_used = true + + _bp.displays.main = device + + log.info("BKPLN: main display connected") + iocontrol.fp_monitor_state("main", 2) + elseif _bp.displays.flow_iface == iface then + is_used = true + + _bp.displays.flow = device + + log.info("BKPLN: flow display connected") + iocontrol.fp_monitor_state("flow", 2) + else + for idx, monitor in ipairs(_bp.displays.unit_ifaces) do + if monitor == iface then + is_used = true + + _bp.displays.unit_displays[idx] = device + + log.info("BKPLN: unit " .. idx .. " display connected") + iocontrol.fp_monitor_state(idx, 2) + break + end + end + end + + -- notify renderer if it is using it + if is_used then + log_sys(util.c("configured monitor ", iface, " connected")) + _bp.smem.q.mq_render.push_data(MQ__RENDER_DATA.MON_CONNECT, iface) + else + log_sys(util.c("unused monitor ", iface, " connected")) + end elseif type == "speaker" then ---@cast device Speaker log_sys("alarm sounder speaker reconnected") @@ -393,25 +432,25 @@ function backplane.detach(type, device, iface) local is_used = false - log.info("BKPLN: MONITOR LINK_DOWN " .. iface) + log.info("BKPLN: DISPLAY LINK_DOWN " .. iface) if _bp.displays.main == device then is_used = true - log.info("BKPLN: lost the main display") - iocontrol.fp_monitor_state("main", false) + log.info("BKPLN: main display disconnected") + iocontrol.fp_monitor_state("main", 1) elseif _bp.displays.flow == device then is_used = true - log.info("BKPLN: lost the flow display") - iocontrol.fp_monitor_state("flow", false) + log.info("BKPLN: flow display disconnected") + iocontrol.fp_monitor_state("flow", 1) else for idx, monitor in pairs(_bp.displays.unit_displays) do if monitor == device then is_used = true - log.info("BKPLN: lost the unit " .. idx .. " display") - iocontrol.fp_monitor_state(idx, false) + log.info("BKPLN: unit " .. idx .. " display disconnected") + iocontrol.fp_monitor_state(idx, 1) break end end diff --git a/coordinator/iocontrol.lua b/coordinator/iocontrol.lua index 305dff5..dd15b17 100644 --- a/coordinator/iocontrol.lua +++ b/coordinator/iocontrol.lua @@ -308,6 +308,7 @@ function iocontrol.fp_link_state(state) io.fp.ps.publish("link_state", state) en -- report monitor connection state ---@param id string|integer unit ID for unit monitor, "main" for main monitor, or "flow" for flow monitor +---@param connected 1|2|3 1 for disconnected, 2 for connected but no view (may not fit), 3 for connected with view shown function iocontrol.fp_monitor_state(id, connected) local name = nil diff --git a/coordinator/renderer.lua b/coordinator/renderer.lua index f9dd9bd..7d32a2c 100644 --- a/coordinator/renderer.lua +++ b/coordinator/renderer.lua @@ -308,39 +308,10 @@ end -- handle a monitor peripheral being reconnected ---@param name string monitor name ----@param device Monitor monitor ----@return boolean is_used if the monitor is one of the configured monitors -function renderer.handle_reconnect(name, device) - local is_used = false - - if not engine.monitors then return false end - +function renderer.handle_reconnect(name) -- note: handle_resize is a more adaptive way of re-initializing a connected monitor -- since it can handle a monitor being reconnected that isn't the right size - - if engine.monitors.main_iface == name then - is_used = true - engine.monitors.main = device - - renderer.handle_resize(name) - elseif engine.monitors.flow_iface == name then - is_used = true - engine.monitors.flow = device - - renderer.handle_resize(name) - else - for idx, monitor in ipairs(engine.monitors.unit_ifaces) do - if monitor == name then - is_used = true - engine.monitors.unit_displays[idx] = device - - renderer.handle_resize(name) - break - end - end - end - - return is_used + renderer.handle_resize(name) end -- handle a monitor being resized
@@ -372,7 +343,7 @@ function renderer.handle_resize(name) ui.main_display = nil end - iocontrol.fp_monitor_state("main", true) + iocontrol.fp_monitor_state("main", 2) engine.dmesg_window.setVisible(not engine.ui_ready) @@ -384,6 +355,8 @@ function renderer.handle_resize(name) end) if ok then + iocontrol.fp_monitor_state("main", 3) + log_render("main view re-draw completed in " .. (util.time_ms() - draw_start) .. "ms") else if ui.main_display then @@ -393,7 +366,6 @@ function renderer.handle_resize(name) _print_too_small(device) - iocontrol.fp_monitor_state("main", false) is_ok = false end else engine.dmesg_window.redraw() end @@ -410,7 +382,7 @@ function renderer.handle_resize(name) ui.flow_display = nil end - iocontrol.fp_monitor_state("flow", true) + iocontrol.fp_monitor_state("flow", 2) if engine.ui_ready then local draw_start = util.time_ms() @@ -420,6 +392,8 @@ function renderer.handle_resize(name) end) if ok then + iocontrol.fp_monitor_state("flow", 3) + log_render("flow view re-draw completed in " .. (util.time_ms() - draw_start) .. "ms") else if ui.flow_display then @@ -429,7 +403,6 @@ function renderer.handle_resize(name) _print_too_small(device) - iocontrol.fp_monitor_state("flow", false) is_ok = false end end @@ -448,7 +421,7 @@ function renderer.handle_resize(name) ui.unit_displays[idx] = nil end - iocontrol.fp_monitor_state(idx, true) + iocontrol.fp_monitor_state(idx, 2) if engine.ui_ready then local draw_start = util.time_ms() @@ -458,6 +431,8 @@ function renderer.handle_resize(name) end) if ok then + iocontrol.fp_monitor_state(idx, 3) + log_render("unit " .. idx .. " view re-draw completed in " .. (util.time_ms() - draw_start) .. "ms") else if ui.unit_displays[idx] then @@ -467,7 +442,6 @@ function renderer.handle_resize(name) _print_too_small(device) - iocontrol.fp_monitor_state(idx, false) is_ok = false end end diff --git a/coordinator/threads.lua b/coordinator/threads.lua index 6e27b46..dc7f3f2 100644 --- a/coordinator/threads.lua +++ b/coordinator/threads.lua @@ -257,11 +257,7 @@ function threads.thread__render(smem) if cmd.key == MQ__RENDER_DATA.MON_CONNECT then -- monitor connected - if renderer.handle_reconnect(cmd.val.name, cmd.val.device) then - log_sys(util.c("configured monitor ", cmd.val.name, " reconnected")) - else - log_sys(util.c("unused monitor ", cmd.val.name, " connected")) - end + renderer.handle_reconnect(cmd.val) elseif cmd.key == MQ__RENDER_DATA.MON_DISCONNECT then -- monitor disconnected renderer.handle_disconnect(cmd.val) diff --git a/coordinator/ui/layout/front_panel.lua b/coordinator/ui/layout/front_panel.lua index 1b32501..5fcb7fc 100644 --- a/coordinator/ui/layout/front_panel.lua +++ b/coordinator/ui/layout/front_panel.lua @@ -114,19 +114,19 @@ local function init(panel, num_units) local comp_id = util.sprintf("(%d)", os.getComputerID()) TextBox{parent=system,x=9,y=4,width=6,text=comp_id,fg_bg=style.fp.disabled_fg} - local monitors = Div{parent=main_page,width=16,height=17,x=18,y=2} + local displays = Div{parent=main_page,width=16,height=17,x=18,y=2} - local main_monitor = LED{parent=monitors,label="MAIN MONITOR",colors=led_grn} - main_monitor.register(ps, "main_monitor", main_monitor.update) + local main_disp = LEDPair{parent=displays,label="MAIN DISPLAY",off=style.fp_ind_bkg,c1=colors.red,c2=colors.green} + main_disp.register(ps, "main_monitor", main_disp.update) - local flow_monitor = LED{parent=monitors,label="FLOW MONITOR",colors=led_grn} - flow_monitor.register(ps, "flow_monitor", flow_monitor.update) + local flow_disp = LEDPair{parent=displays,label="FLOW DISPLAY",off=style.fp_ind_bkg,c1=colors.red,c2=colors.green} + flow_disp.register(ps, "flow_monitor", flow_disp.update) - monitors.line_break() + displays.line_break() for i = 1, num_units do - local unit_monitor = LED{parent=monitors,label="UNIT "..i.." MONITOR",colors=led_grn} - unit_monitor.register(ps, "unit_monitor_" .. i, unit_monitor.update) + local unit_disp = LEDPair{parent=displays,label="UNIT "..i.." DISPLAY",off=style.fp_ind_bkg,c1=colors.red,c2=colors.green} + unit_disp.register(ps, "unit_monitor_" .. i, unit_disp.update) end --