From bdc91177e2c5b1664527c52c5fdb988daefe463d Mon Sep 17 00:00:00 2001 From: serversdown Date: Tue, 9 Jun 2026 19:28:55 +0000 Subject: [PATCH] feat(admin): per-unit live-monitoring (keepalive) toggle on /admin/slmm Adds a "Live Monitoring (keepalive)" card listing each SLMM device with its monitor_enabled state and an Enable/Disable toggle. Reads from /api/slmm/roster (now includes monitor_enabled) and POSTs to /api/slmm/{unit}/monitor/{start,stop}, which persist the flag in SLMM (survives restarts; auto-started on boot). Shows a reachability dot + 24/7 ON/OFF badge. Co-Authored-By: Claude Opus 4.8 (1M context) --- templates/admin_slmm.html | 67 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/templates/admin_slmm.html b/templates/admin_slmm.html index c9056b1..2b88dcd 100644 --- a/templates/admin_slmm.html +++ b/templates/admin_slmm.html @@ -42,6 +42,18 @@ + +
+

Live Monitoring (keepalive)

+

+ Keepalive runs the 1 Hz DOD feed 24/7 (even with no viewer), which powers the live-chart + trail and continuous threshold alerts. Toggling persists and survives restarts. +

+
+

Loading…

+
+
+

Raw API Tester

@@ -132,7 +144,60 @@ async function sendRaw() { } } +async function loadMonitors() { + const el = document.getElementById('monitor-list'); + try { + const r = await fetch('/api/slmm/roster'); + if (!r.ok) throw new Error('HTTP ' + r.status); + const d = await r.json(); + const devices = d.devices || []; + if (!devices.length) { + el.innerHTML = '

No devices configured.

'; + return; + } + el.innerHTML = devices.map(dev => { + const on = !!dev.monitor_enabled; + const reach = dev.status ? dev.status.is_reachable : null; + const reachDot = reach === false + ? '' + : ''; + return ` +
+
+ ${reachDot} + ${_esc(dev.unit_id)} + ${_esc(dev.host)}:${_esc(dev.tcp_port)} +
+
+ ${on ? '24/7 ON' : 'OFF'} + +
+
`; + }).join(''); + } catch (e) { + el.innerHTML = `

Failed to load devices: ${_esc(e.message)}

`; + } +} + +async function toggleMonitor(unitId, enable) { + const action = enable ? 'start' : 'stop'; + try { + const r = await fetch(`/api/slmm/${encodeURIComponent(unitId)}/monitor/${action}`, { method: 'POST' }); + if (!r.ok) throw new Error('HTTP ' + r.status); + await loadMonitors(); + } catch (e) { + alert('Toggle failed: ' + e.message); + } +} + loadSlmmOverview(); -setInterval(loadSlmmOverview, 30000); +loadMonitors(); +setInterval(() => { loadSlmmOverview(); loadMonitors(); }, 30000); {% endblock %}