router-status: replace Cockpit's Van Router plugin with MQTT -> Home Assistant

Cockpit's login was unreliable (Firefox rejected sometimes, Android failed
outright with a TLS handshake error) and it was a resource hog on this Pi.
van-router-mqtt publishes the same AP/client/WAN/Starlink/modem status and
accepts the same control actions (AP/modem restart, WAN connect/disconnect,
prefer) via MQTT with HA discovery, using the local Mosquitto broker already
running here. It republishes van-failover/van-thermal's own state.json files
verbatim rather than modifying either daemon (van-thermal is deliberately
stdlib-only; van-failover's control loop wasn't worth an added dependency).

Adds a Lovelace dashboard (ha/dashboards/van-router.yaml) consuming those
entities. Cockpit's plugin is left deployed for now, not yet retired.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S2tpeaiHUriQbbnQ4SCbkf
This commit is contained in:
Andreas Wrede
2026-09-14 16:28:01 -04:00
co-authored by Claude Sonnet 5
parent 918003d2e3
commit ec5130ea7d
6 changed files with 772 additions and 1 deletions
+42
View File
@@ -114,6 +114,16 @@ This directory is the source of truth. The live system files live under `/etc`,
### `cockpit/vanrouter/` — web UI
`manifest.json`, `index.html`, `vanrouter.css`, `vanrouter.js` → `/usr/share/cockpit/vanrouter/`.
Being superseded by `router-status/` below (Cockpit's PAM+TLS login was unreliable
— rejected Firefox sometimes, failed outright from Android — and it was a resource
hog); left in place until the Home Assistant dashboard fully covers its actions.
### `router-status/` — same status/actions, via MQTT -> Home Assistant
| file | → installs to | purpose |
|---|---|---|
| `van-router-mqtt` | `/usr/local/sbin/van-router-mqtt` | status+control daemon (Python, paho-mqtt): AP/clients/Starlink/WAN/modem, HA MQTT discovery; republishes van-failover/van-thermal/van-battery's own state.json verbatim rather than recomputing them |
| `config.json` | `/etc/van-router-mqtt/config.json` | broker + interface identifiers (`@TOKEN@` templated like `failover/config.json` — no secrets, rendered fresh every deploy) |
| `van-router-mqtt.service` | `/etc/systemd/system/van-router-mqtt.service` | `Restart=always` |
### `power/` — never sleep + thermal monitor
| file | → installs to | purpose |
@@ -161,6 +171,16 @@ supply (laptop UPS-style monitor), unrelated hardware and purpose.
The `homeassistant` LAN name comes from `ap/van-ap-dnsmasq.conf` (`host-record` →
`10.42.0.1`). The retired HAOS VM's domain XML (`ha_van.xml`) lives in git history.
`custom_components/` and `dashboards/` are **not deployed by `deploy.sh`** — HA's
`/srv/homeassistant` is hand-managed live config (it has other integrations installed
via HACS that were never in this repo, e.g. `mbapi2020`); these two are kept here purely
as a reference/backup copy of the hand-authored pieces. `dashboards/van-router.yaml` is
the Lovelace dashboard for `van-router-mqtt`'s entities — the live copy is
`/srv/homeassistant/dashboards/van-router.yaml`, wired in via a `lovelace: dashboards:`
block manually added to `/srv/homeassistant/configuration.yaml` (also not repo-tracked;
see that file's own comment). After editing the dashboard, copy both places and
`systemctl restart homeassistant` (or use HA's own "reload" for lovelace-only changes).
---
## 3. Components & how to operate
@@ -303,6 +323,28 @@ script's docstring for the full field layout.
- The Access Points card shows both bands (5GHz `hostapd`, 2.4GHz `hostapd-2g`) with per-band client lists and **Restart** buttons; the radio list lives in `vanrouter.js` (`const APS`).
- **Prefer** sets the manual WAN preference (see *Manual preference* above); **Up/Down** connect/disconnect the NM device.
### Router status via MQTT (`van-router-mqtt`) — replacing Cockpit above
- Publishes the same status Cockpit's plugin showed, and accepts the same actions, over
MQTT with Home Assistant discovery — no web server/login of its own; HA (already running
on this Pi) owns the UI. Broker is the local Mosquitto on `127.0.0.1:1883` (already used by
HA itself and by `van-gps-owntracks`/`li3`); it currently allows anonymous connections, so
`config.json` carries no credentials.
- State topics (`van/router/...`): `ap/5g`, `ap/2g`, `clients`, `starlink`, `wan`,
`deploywarn`, plus verbatim republishes of `van-failover`'s and `van-thermal`'s own
`/run/van-*/state.json` (those two daemons were **not** modified — `van-thermal` is
deliberately stdlib-only for boot resilience, and `van-failover`'s control loop wasn't
touched). `van/router/battery` only appears if `power/van-battery` (documented in this
README, not actually deployed on this host) ever starts writing its state file.
- Command topics (`vanlink/cmd/...`): `ap/{5g,2g}/restart`, `modem/restart`,
`wan/{wifi,starlink,cellular}/set` (`connect`/`disconnect`), `wan/prefer`
(`auto`/`wifi`/`starlink`/`cellular` — writes the same `/run/van-failover/prefer` file
Cockpit's "Prefer" button did). Wi-Fi scan/connect (wlan0 as a WAN) was **not** ported —
it's an interactive password-prompt flow that doesn't map to MQTT/HA entities well and is
only used during initial setup; use `nmcli` directly for that.
- Verify: `journalctl -u van-router-mqtt -f`, `mosquitto_sub -h localhost -t 'van/router/#' -v`.
Entities should appear in HA under the "Van Router" device once the integration picks up
the retained discovery messages (Settings → Devices & Services → MQTT).
### Home Assistant (native Podman container)
- HA Container runs on the host via a **Podman Quadlet** (`ha/homeassistant.container` →
`/etc/containers/systemd/`; systemd generates `homeassistant.service`). **Host network**: