Files
MIKROTIK-RMM/backend/src/services/mikrotik/__tests__
2GT-RichandClaude Opus 5 2625fea8de feat(lte): cellular telemetry, band details and roaming history (v0.23.12-beta)
Adds LTE support, requested in discussion #85 by a contributor running a
MikroTik ATL 18 on a fixed antenna. Cellular was previously a blank page: the
only occurrence of "lte" in the tree excluded LTE interfaces from DHCP binding.

Built against two real field captures rather than documentation, which
disagreed with the hardware in several places — the modem reports `data-class`
not `access-technology`, `iccid` not `uicc`, `status: running` not `connected`,
embeds units inside values (`-97dBm`, `17dB`), and omits `registration-status`,
`pin-status` and `lac`/`tac` entirely. What an LTE interface reports depends on
the modem chipset, not on RouterOS, so every field is optional by construction.

Fixes a latent bug in the API client while it was in reach. A sentence carrying
the same attribute twice kept only the last value, and a Cat-18 modem reports
one `ca-band` per aggregated carrier. On the contributor's 4-carrier capture
that yielded B3 + B20 — 30 MHz — on a device actually running 70 MHz, because
the narrowest carrier happens to arrive last. Repeats are now preserved
alongside the flat value, so existing callers are byte-for-byte unaffected.

Signal quality is graded rather than merely displayed. RSRP alone misleads: the
capture shows −97 dBm, nominally "fair", on a link running 256QAM at CQI 15 with
two spatial streams. SINR leads the grade and RSRP moderates it.

Surfaces the uplink anchor, which no MikroTik UI shows. Left on automatic a
modem anchors to whichever band it hears loudest, often a narrow one, and
aggregates wider bands for downlink only — but uplink rides the primary carrier
alone, so upload stays capped. This is the contributor's actual reason for
locking bands, and it reframes band selection as anchor control rather than
coverage.

Band changes, tower handovers and re-registrations are reconstructed by
comparing consecutive polls, since scanning interrupts service and finds nothing
at a site served by a single base station. Observed bands accumulate as the
evidence a future band lock will be checked against.

Band selection itself is deliberately absent: it needs Change Guard plus a
free-space check, as the target hardware has 1.1 MB free of 16 MB flash.

Also fixes an unrelated display bug in the RF Health channel map. The 2.4 GHz
axis is labelled by channel, but ticks at 2400 and 2480 fall outside the channel
plan and fell back to printing raw frequencies — and the 2400 label sat at
exactly 0% with a centring transform, hanging half its width outside the card.
2.4 GHz is the only band with a tick at an edge. Unlabelled ticks are now
dropped and edge labels anchor inward.

  - backend/src/utils/lte.ts — parsing, quality, change detection (59 tests)
  - RouterOSClient — repeated attributes preserved (6 tests)
  - lte_interfaces, lte_cell_history, lte_observed_bands
  - GET /devices/:id/lte, /lte/history, /lte/metrics
  - LteTab, gated on has_lte from the interface list
  - scripts/seed-lte-fixture.sql — a cellular device for local development

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 13:06:28 -07:00
..