Lays down Zigbee2MQTT (Z2M) in the home-assistant namespace as the eventual replacement for the ZHA integration. Z2M is wired to drive the same coordinator ZHA uses today — SMLIGHT SLZB-06 / TI CC2652 (zstack/zigpy-znp) at tcp://slzb-zigbee.renner.uno:6638.
No re-pairing. Devices are joined to the network stored on the coordinator chip. If Z2M starts configured with the existing network parameters (pan_id, ext_pan_id, network_key, channel), zigbee-herdsmanadopts that network instead of forming a new one — every device stays joined. Getting those parameters wrong (or leaving them default) makes Z2M form a new network and drop every device; two interlocks prevent that (below).
Safe to merge — ships inert
The Deployment is replicas: 0. Reconciling this PR starts nothing and does not touch the running Zigbee network.
The ZHA network parameters come from the zigbee2mqtt-networkExternalSecret (OpenBao), populated only at cutover. Until then it's NotReady, the Secret is absent, and the pod cannot start — so it can never accidentally form a new network.
Going live is a manual, documented, reversible procedure: see zigbee2mqtt-migration-runbook.md.
Contents
File
Purpose
zigbee2mqtt-deployment.yaml
Z2M @ 2.12.1, replicas: 0. Init container renders /app/data/secret.yaml from Secrets each start and seeds configuration.yaml once.
zigbee2mqtt-config.yaml
Seed-only config template. Secrets pulled via Z2M !secret → the network key never touches git or the ConfigMap.
zigbee2mqtt-pvc.yaml / -service.yaml
1Gi RWO state PVC; ClusterIP Service on 8080 (frontend).
zigbee2mqtt-network-externalsecret.yaml
OpenBao-backed network params, populated at cutover from a ZHA network backup.
New zigbee2mqtt broker user (bootstrap Job + passwd/ACL/env), scoped to zigbee2mqtt/# + write homeassistant/# for HA MQTT discovery.
zigbee2mqtt-migration-runbook.md
Cutover + rollback procedure.
Notes / decisions
No new egress CiliumNetworkPolicy. The namespace-wide default-deny policy already grants every pod same-namespace (mosquitto), DNS, and world (the IoT-VLAN coordinator). A scoped policy would be documentation only (Cilium is additive).
Secrets via !secret, not ZIGBEE2MQTT_CONFIG_* env overrides — the env path mis-splits keys that contain underscores (network_key, ext_pan_id), which is exactly where a silent mismatch → network re-form would hurt.
Validated: kubectl kustomize builds; all new objects pass kubectl apply --dry-run=server.
Follow-ups (not blocking)
homeassistant repo PR — re-point automations/dashboards/scripts from ZHA entity IDs (*_texas_instruments_coordinator_*) to the new Z2M MQTT-discovery entities. This is the real bulk of the migration effort (new unique_ids ⇒ new entities). Precedent: the prior ZHA→Matter cover migration.
Gated ingress for the frontend (Authentik outpost, like esphome/shelly-manager); Flux image-automation policy for the tag.
## What & why
Lays down **Zigbee2MQTT (Z2M)** in the `home-assistant` namespace as the eventual replacement for the **ZHA** integration. Z2M is wired to drive the **same coordinator ZHA uses today** — SMLIGHT SLZB-06 / TI CC2652 (`zstack`/`zigpy-znp`) at `tcp://slzb-zigbee.renner.uno:6638`.
**No re-pairing.** Devices are joined to the network stored on the coordinator chip. If Z2M starts configured with the *existing* network parameters (`pan_id`, `ext_pan_id`, `network_key`, `channel`), `zigbee-herdsman` **adopts** that network instead of forming a new one — every device stays joined. Getting those parameters wrong (or leaving them default) makes Z2M **form a new network** and drop every device; two interlocks prevent that (below).
## Safe to merge — ships inert
- The Deployment is **`replicas: 0`**. Reconciling this PR starts nothing and does not touch the running Zigbee network.
- The ZHA network parameters come from the `zigbee2mqtt-network` **ExternalSecret** (OpenBao), populated **only at cutover**. Until then it's NotReady, the Secret is absent, and the pod **cannot** start — so it can never accidentally form a new network.
Going live is a **manual, documented, reversible** procedure: see `zigbee2mqtt-migration-runbook.md`.
## Contents
| File | Purpose |
|---|---|
| `zigbee2mqtt-deployment.yaml` | Z2M @ `2.12.1`, `replicas: 0`. Init container renders `/app/data/secret.yaml` from Secrets each start and seeds `configuration.yaml` once. |
| `zigbee2mqtt-config.yaml` | Seed-only config template. Secrets pulled via Z2M `!secret` → the network key never touches git or the ConfigMap. |
| `zigbee2mqtt-pvc.yaml` / `-service.yaml` | 1Gi RWO state PVC; ClusterIP Service on 8080 (frontend). |
| `zigbee2mqtt-network-externalsecret.yaml` | OpenBao-backed network params, populated at cutover from a ZHA network backup. |
| `mosquitto-bootstrap.yaml` / `mosquitto-deployment.yaml` | New `zigbee2mqtt` broker user (bootstrap Job + passwd/ACL/env), scoped to `zigbee2mqtt/#` + write `homeassistant/#` for HA MQTT discovery. |
| `zigbee2mqtt-migration-runbook.md` | Cutover + rollback procedure. |
## Notes / decisions
- **No new egress CiliumNetworkPolicy.** The namespace-wide default-deny policy already grants every pod same-namespace (mosquitto), DNS, and `world` (the IoT-VLAN coordinator). A scoped policy would be documentation only (Cilium is additive).
- **Secrets via `!secret`, not `ZIGBEE2MQTT_CONFIG_*` env overrides** — the env path mis-splits keys that contain underscores (`network_key`, `ext_pan_id`), which is exactly where a silent mismatch → network re-form would hurt.
- Validated: `kubectl kustomize` builds; all new objects pass `kubectl apply --dry-run=server`.
## Follow-ups (not blocking)
- **`homeassistant` repo PR** — re-point automations/dashboards/scripts from ZHA entity IDs (`*_texas_instruments_coordinator_*`) to the new Z2M MQTT-discovery entities. This is the real bulk of the migration effort (new `unique_id`s ⇒ new entities). Precedent: the prior ZHA→Matter cover migration.
- Gated ingress for the frontend (Authentik outpost, like `esphome`/`shelly-manager`); Flux image-automation policy for the tag.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Lay down Zigbee2MQTT (Z2M) in the home-assistant namespace as the eventual
replacement for the ZHA integration, wired to drive the SAME coordinator ZHA
uses today (SMLIGHT SLZB-06 / TI CC2652, tcp://slzb-zigbee.renner.uno:6638).
Devices are joined to the network on the coordinator chip, so if Z2M comes up
with the existing network parameters (pan_id, ext_pan_id, network_key, channel)
zigbee-herdsman ADOPTS that network instead of forming a new one — every device
stays joined, no re-pairing.
Ships INERT and safe to merge:
- Deployment is replicas: 0. Reconciling this PR starts nothing.
- The ZHA network params come from the `zigbee2mqtt-network` ExternalSecret
(OpenBao), populated only at cutover. Until then the ExternalSecret is
NotReady and the pod cannot start, so it can never accidentally form a new
network (which would drop every device).
The cutover is a manual, documented, reversible procedure — see
zigbee2mqtt-migration-runbook.md.
Contents:
- zigbee2mqtt-{pvc,config,deployment,service}.yaml — the app. Config template
is seeded to the PVC once; secrets (mqtt password + ZHA network params) are
injected via /app/data/secret.yaml (rendered each start by an init
container) and referenced with Z2M `!secret`, keeping the network key out
of git and out of the ConfigMap.
- zigbee2mqtt-network-externalsecret.yaml — OpenBao-backed network params,
populated at cutover from a ZHA network backup.
- New `zigbee2mqtt` Mosquitto broker user: bootstrap Job
(mosquitto-bootstrap.yaml) + passwd/ACL/env (mosquitto-deployment.yaml),
scoped to zigbee2mqtt/# plus write homeassistant/# for HA MQTT discovery.
- zigbee2mqtt-migration-runbook.md — the cutover + rollback procedure.
No new egress CiliumNetworkPolicy is needed: the namespace-wide default-deny
policy already grants same-namespace (mosquitto), DNS, and world (the IoT-VLAN
coordinator) to every pod.
Follow-up (separate homeassistant-repo PR): re-point automations/dashboards
from ZHA entity ids to the new Z2M MQTT-discovery entities.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
claude-bot
marked the pull request as ready for review 2026-07-23 09:49:56 +00:00
Pull the live ZHA device registry (31 devices + coordinator) and pre-seed each
device's friendly_name in the Z2M config, keyed by IEEE. Devices then come up as
"EG Küche Tischlampe Oben" instead of "0x001788010856bb17" the moment Z2M
re-interviews them on the adopted network — which is what keeps the HA-side
entity reconciliation small and mechanical. Two devices that were both bare
"Deckenlampe" in ZHA are disambiguated by area (Z2M requires unique friendly
names): EG Galerie (Hue LTC001) and DG Lager (LUMI N1 switch).
Add zigbee2mqtt-entity-reconciliation.md: an audit of exactly which ZHA entities
the git-tracked config references, so the cutover knows what must be re-pointed.
Key result — the HA-side change is FAR smaller than "rewire everything":
- 216 ZHA entities exist, but only 16 distinct entity_ids are referenced in
the repo (200 are unreferenced diagnostics/config entities).
- 14 of the 16 are physical-device entities, all mapping cleanly into the
31-device inventory (no orphans).
- The remaining 2 are the `light.texas_instruments_coordinator_*` entities —
now identified as ZHA *groups* on the coordinator (not physical devices),
accounting for 14 references. These don't come from Z2M device discovery and
must be re-created as Z2M groups and re-pointed by hand.
Scope note captured in the doc: only git-tracked YAML/JSON was audited; live
.storage Lovelace dashboards and UI-created automations/helpers must be
reconciled separately.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What & why
Lays down Zigbee2MQTT (Z2M) in the
home-assistantnamespace as the eventual replacement for the ZHA integration. Z2M is wired to drive the same coordinator ZHA uses today — SMLIGHT SLZB-06 / TI CC2652 (zstack/zigpy-znp) attcp://slzb-zigbee.renner.uno:6638.No re-pairing. Devices are joined to the network stored on the coordinator chip. If Z2M starts configured with the existing network parameters (
pan_id,ext_pan_id,network_key,channel),zigbee-herdsmanadopts that network instead of forming a new one — every device stays joined. Getting those parameters wrong (or leaving them default) makes Z2M form a new network and drop every device; two interlocks prevent that (below).Safe to merge — ships inert
replicas: 0. Reconciling this PR starts nothing and does not touch the running Zigbee network.zigbee2mqtt-networkExternalSecret (OpenBao), populated only at cutover. Until then it's NotReady, the Secret is absent, and the pod cannot start — so it can never accidentally form a new network.Going live is a manual, documented, reversible procedure: see
zigbee2mqtt-migration-runbook.md.Contents
zigbee2mqtt-deployment.yaml2.12.1,replicas: 0. Init container renders/app/data/secret.yamlfrom Secrets each start and seedsconfiguration.yamlonce.zigbee2mqtt-config.yaml!secret→ the network key never touches git or the ConfigMap.zigbee2mqtt-pvc.yaml/-service.yamlzigbee2mqtt-network-externalsecret.yamlmosquitto-bootstrap.yaml/mosquitto-deployment.yamlzigbee2mqttbroker user (bootstrap Job + passwd/ACL/env), scoped tozigbee2mqtt/#+ writehomeassistant/#for HA MQTT discovery.zigbee2mqtt-migration-runbook.mdNotes / decisions
world(the IoT-VLAN coordinator). A scoped policy would be documentation only (Cilium is additive).!secret, notZIGBEE2MQTT_CONFIG_*env overrides — the env path mis-splits keys that contain underscores (network_key,ext_pan_id), which is exactly where a silent mismatch → network re-form would hurt.kubectl kustomizebuilds; all new objects passkubectl apply --dry-run=server.Follow-ups (not blocking)
homeassistantrepo PR — re-point automations/dashboards/scripts from ZHA entity IDs (*_texas_instruments_coordinator_*) to the new Z2M MQTT-discovery entities. This is the real bulk of the migration effort (newunique_ids ⇒ new entities). Precedent: the prior ZHA→Matter cover migration.esphome/shelly-manager); Flux image-automation policy for the tag.🤖 Generated with Claude Code
Lay down Zigbee2MQTT (Z2M) in the home-assistant namespace as the eventual replacement for the ZHA integration, wired to drive the SAME coordinator ZHA uses today (SMLIGHT SLZB-06 / TI CC2652, tcp://slzb-zigbee.renner.uno:6638). Devices are joined to the network on the coordinator chip, so if Z2M comes up with the existing network parameters (pan_id, ext_pan_id, network_key, channel) zigbee-herdsman ADOPTS that network instead of forming a new one — every device stays joined, no re-pairing. Ships INERT and safe to merge: - Deployment is replicas: 0. Reconciling this PR starts nothing. - The ZHA network params come from the `zigbee2mqtt-network` ExternalSecret (OpenBao), populated only at cutover. Until then the ExternalSecret is NotReady and the pod cannot start, so it can never accidentally form a new network (which would drop every device). The cutover is a manual, documented, reversible procedure — see zigbee2mqtt-migration-runbook.md. Contents: - zigbee2mqtt-{pvc,config,deployment,service}.yaml — the app. Config template is seeded to the PVC once; secrets (mqtt password + ZHA network params) are injected via /app/data/secret.yaml (rendered each start by an init container) and referenced with Z2M `!secret`, keeping the network key out of git and out of the ConfigMap. - zigbee2mqtt-network-externalsecret.yaml — OpenBao-backed network params, populated at cutover from a ZHA network backup. - New `zigbee2mqtt` Mosquitto broker user: bootstrap Job (mosquitto-bootstrap.yaml) + passwd/ACL/env (mosquitto-deployment.yaml), scoped to zigbee2mqtt/# plus write homeassistant/# for HA MQTT discovery. - zigbee2mqtt-migration-runbook.md — the cutover + rollback procedure. No new egress CiliumNetworkPolicy is needed: the namespace-wide default-deny policy already grants same-namespace (mosquitto), DNS, and world (the IoT-VLAN coordinator) to every pod. Follow-up (separate homeassistant-repo PR): re-point automations/dashboards from ZHA entity ids to the new Z2M MQTT-discovery entities. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>Pull the live ZHA device registry (31 devices + coordinator) and pre-seed each device's friendly_name in the Z2M config, keyed by IEEE. Devices then come up as "EG Küche Tischlampe Oben" instead of "0x001788010856bb17" the moment Z2M re-interviews them on the adopted network — which is what keeps the HA-side entity reconciliation small and mechanical. Two devices that were both bare "Deckenlampe" in ZHA are disambiguated by area (Z2M requires unique friendly names): EG Galerie (Hue LTC001) and DG Lager (LUMI N1 switch). Add zigbee2mqtt-entity-reconciliation.md: an audit of exactly which ZHA entities the git-tracked config references, so the cutover knows what must be re-pointed. Key result — the HA-side change is FAR smaller than "rewire everything": - 216 ZHA entities exist, but only 16 distinct entity_ids are referenced in the repo (200 are unreferenced diagnostics/config entities). - 14 of the 16 are physical-device entities, all mapping cleanly into the 31-device inventory (no orphans). - The remaining 2 are the `light.texas_instruments_coordinator_*` entities — now identified as ZHA *groups* on the coordinator (not physical devices), accounting for 14 references. These don't come from Z2M device discovery and must be re-created as Z2M groups and re-pointed by hand. Scope note captured in the doc: only git-tracked YAML/JSON was audited; live .storage Lovelace dashboards and UI-created automations/helpers must be reconciled separately. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>