- Heartbeat: if nothing has been broadcast in MONITOR_HEARTBEAT_S (default
25s) — e.g. device offline and silent — send a non-cached keepalive frame
so a reverse proxy (NPM) doesn't drop the idle WS. New subscribers still
get the last real frame, not a heartbeat.
- Poller-skip: the 60s background poller now skips any unit with a running
monitor (MonitorManager.is_active). The monitor already polls it ~1Hz and
keeps the status cache fresh, so the background poll was redundant and just
added load/lock-contention on the device's single connection (and churn,
which matters for the cellular wedge). Trade-off: the FTP start-time sync
(only in the poller) doesn't run while a unit is actively monitored — fine,
since reports take the authoritative start time from the FTP .rnd data.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lets an instance stop occupying a device's single TCP connection slot so
another instance (e.g. prod) can take over.
Per-unit:
- POST /api/nl43/{unit_id}/deactivate — poll_enabled=False (persisted) +
drop the connection (waits up to 10s for in-flight ops via the device
lock, then discards). Unit stays dormant across restarts.
- POST /api/nl43/{unit_id}/activate — re-enable polling.
Global standby:
- POST /api/nl43/_system/standby — poller idles and releases ALL
connections; the loop keeps re-releasing so the instance holds no slots.
- POST /api/nl43/_system/resume — resume polling.
- GET /api/nl43/_system/status — active vs standby + active_connections.
- SLMM_POLLING_ENABLED=false starts an instance in standby (persistent
way to keep a dev box from latching onto a prod-owned device).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- db cache dump on diagnostics request.
- individual device logs, db and files.
-Device logs api endpoints and diagnostics UI.
Fix:
- slmm standalone now uses local TZ (was UTC only before)
- fixed measurement start time logic.