The shim holds 10.0.50.47/24, which gives two equal connected 10.0.50.0/24 routes, and ens18's wins. Host-to-HA traffic therefore left via the macvlan parent and was dropped. HA lost MQTT to the broker on this host on 2026-08-19, 2026-09-21 and 2026-09-25 (the last lasted two days). This adds an ifupdown if-up.d hook that routes 10.0.50.46/32 via macvlan-shim; /etc/network/interfaces is not edited. Verified: the route resolves via the shim, the host pings HA, HA reaches :1883, and HA reconnected to the broker. Diagnosis by ha-dev. Also corrects the zigbee2mqtt acceptance note, which had wrongly reported HA as connected.
71 lines
4.4 KiB
Markdown
71 lines
4.4 KiB
Markdown
# zigbee2mqtt
|
|
|
|
The **house Zigbee stack** on esh-docker-vm, replacing Home Assistant's ZHA. It was
|
|
requested by ha-dev and approved by Prime on 2026-09-27. It started greenfield: the
|
|
Zigbee network had no devices, so nothing was migrated.
|
|
|
|
| | |
|
|
|---|---|
|
|
| **Frontend** | `http://10.0.50.45:8099`, protected by an auth token (vault `esh-docker-vm/zigbee2mqtt-frontend-token`) |
|
|
| **Image** | `koenkk/zigbee2mqtt:2.14.1@sha256:fef0de76…` (`.env` `IMAGE`, digest-pinned) |
|
|
| **Radio** | SLZB-MR1U `10.0.90.10` (VLAN 90), chip 0 = EFR32MG21 / EmberZNet 8.0.2, `tcp://10.0.90.10:6638`, adapter `ember`. Chip 1 (CC2652P7, :6639) is unused. |
|
|
| **Network** | channel 25, PAN ID **0xCFF4** (53236), extended PAN ID `0xd0cbe1735919b497`, coordinator IEEE `0x187a3efffe99a487`. Formed fresh on 2026-09-27 (the EFR32 left the abandoned ZHA network: channel 25, PAN 0xF09F). |
|
|
| **MQTT** | `mqtt://mosquitto:1883` over `traefik-net`, as broker user `zigbee2mqtt` (vault `esh-docker-vm/zigbee2mqtt-mqtt-password`). Base topic `zigbee2mqtt`, HA discovery on `homeassistant/`. |
|
|
| **State** | `/opt/docker/data/zigbee2mqtt` (root 0700): `configuration.yaml`, `secret.yaml`, `coordinator_backup.json`, `database.db`. Backed up by the host's restic (`/opt/docker`). |
|
|
|
|
## ⚠ The network key
|
|
|
|
`secret.yaml` holds the Zigbee **network key**, which encrypts the whole mesh. The same
|
|
key is in the vault as `esh-docker-vm/zigbee2mqtt-network-key`. If it is lost, every
|
|
device must be re-paired. It must never be in git. That is why this repo holds only
|
|
`compose.yaml`, `.env.example` and this README; the data dir is host-only and
|
|
`deploy-stack.sh` never touches it. `configuration.yaml` refers to the secrets as
|
|
`'!secret.yaml <key>'`.
|
|
|
|
## Notes
|
|
|
|
- **One client per radio socket.** HA's ZHA must stay disabled or deleted while Z2M
|
|
owns 6638.
|
|
- **Configured by IP.** Containers here cannot resolve `*.internal`. The SLZB's mDNS
|
|
TXT record advertises `radio_type znp` for 6638, which is wrong: 6638 speaks EZSP/Ember.
|
|
- **Pairing is timed.** Z2M 2.x has no `permit_join` setting. Joining is opened from
|
|
the frontend or over MQTT, and closes on a timer.
|
|
- The broker user was added with `mosquitto_passwd` + `SIGHUP`; the password file's
|
|
owner and mode are unchanged (1883, 0600). The broker still has
|
|
`allow_anonymous true`, a pre-existing setting that is not this stack's to change.
|
|
|
|
## Acceptance (2026-09-27, first start at 1240)
|
|
|
|
- Z2M 2.14.1 on EmberZNet 8.0.2 (EZSP 14). herdsman reported "Adapter network does not match
|
|
config. Leaving network...", found no backup, and formed a new network on channel 25:
|
|
PAN 0xCFF4. It wrote `coordinator_backup.json`.
|
|
- `zigbee2mqtt/bridge/state` = `{"state":"online"}`, and the bridge's 8 HA discovery configs are
|
|
retained under `homeassistant/+/1221051039810110150109113116116_0x187a3efffe99a487/…`. Whether
|
|
the device shows up in HA is ha-dev's to confirm.
|
|
- On startup Z2M migrated the settings to `version: 5`. All three `!secret.yaml` references
|
|
survived the rewrite, so no key is in plaintext in `configuration.yaml`. The pre-migration file
|
|
is kept as `configuration_backup_v4.yaml`.
|
|
- Frontend: HTTP 200. The websocket accepts the vault token, and closes with `4401 Unauthorized`
|
|
on a wrong token or no token.
|
|
- Broker: the new user is accepted, and a wrong password is refused. ⚠ **Correction (1250):** I first
|
|
reported HA's MQTT client as connected. It was not. HA had lost the broker at 2026-09-25 06:13,
|
|
because host→HA traffic left via ens18 instead of the macvlan shim (ha-dev diagnosed it). The
|
|
third "client" I counted was my own probe. Fixed by `playbooks/esh-docker-vm-macvlan-shim-route.yaml`,
|
|
a /32 route to 10.0.50.46 over macvlan-shim. HA reconnected at 1249. The Tasmotas
|
|
`consoletree`, `fireplacetree` and `mantlelights` show LWT `Offline`, but they have not connected
|
|
at any point in the broker's current log (back to 2026-09-09), so that predates this change.
|
|
|
|
## Deploy
|
|
|
|
```bash
|
|
scripts/deploy-stack.sh esh-docker-vm zigbee2mqtt --compose
|
|
# on the host, first time only:
|
|
# /opt/docker/compose/zigbee2mqtt is lkraven:docker 2755, so infra-ops cannot `cp` into it
|
|
cd /opt/docker/compose/zigbee2mqtt && sudo -n install -o lkraven -g docker -m 644 .env.example .env \
|
|
&& docker compose config -q && docker compose up -d
|
|
```
|
|
|
|
To upgrade, change `IMAGE` in the host `.env` to a new `tag@digest`, then run
|
|
`docker compose up -d`. Read the release notes first: an adapter or firmware change can
|
|
require re-pairing.
|