--- okf: "0.1" type: node visibility: private status: active updated: 2026-05-27 links: - ../runbooks/chelsty-deploy-recovery.md --- # CHELSTY Runtime This document describes the runtime environment and deployment flow for CHELSTY, an offline-capable home automation edge node split across two VMs. | Node | Role | Services | |------|------|----------| | `chelsty-infra` | LTE edge hypervisor | Mosquitto, Zigbee2MQTT, stability-agent, node-agent | | `chelsty-ha` | Home Assistant VM | homeassistant (no node-agent — see below) | Both nodes share an LTE uplink and must function fully offline (Zigbee, MQTT, HA automations) without any connectivity to SATURN, VPS, or Forgejo. ## Runtime Layout ``` /opt/homelab/ ├── config/ # Service-specific configs and secrets (not in Git) │ ├── mosquitto/ │ └── zigbee2mqtt/ ├── data/ # Persistent service data │ ├── mosquitto/ # Persistence DB, password file │ └── zigbee2mqtt/ │ └── data/ # z2m config, coordinator backup, network key └── logs/ ``` ## SLZB-06U Integration CHELSTY uses a SMLIGHT SLZB-06U Zigbee coordinator connected over Ethernet/TCP. - **Coordinator IP**: `192.168.1.105` - **Port**: `6638` - **Adapter**: `ezsp` (deprecated — migration to `ember` recommended, requires only changing `adapter: ember` in `configuration.yaml`) - **Zigbee2MQTT config key**: `serial.port: tcp://192.168.1.105:6638` ⚠️ Never use `/dev/ttyUSB0` — the coordinator is always TCP-only on this site. ## Networking Constraints ### Mosquitto — `network_mode: host` Mosquitto runs with `network_mode: host` so that all containers on the same host can reach it at `localhost:1883`. **Do not change this.** ### Zigbee2MQTT — bridge network + extra_hosts Zigbee2MQTT runs in a bridge-networked container (needed for port mapping compatibility with docker-compose v1). To reach the host-networked Mosquitto: ```yaml # hosts/chelsty-infra/runtime/zigbee2mqtt/docker-compose.override.yml services: zigbee2mqtt: extra_hosts: - "mosquitto:host-gateway" ``` This maps the `mosquitto` hostname inside the z2m container to the Docker host gateway IP, so `mqtt://mosquitto:1883` reaches the host-networked Mosquitto process. **Why not `network_mode: host` for z2m?** chelsty-infra runs docker-compose v1 (1.29.2). In v1, `network_mode: host` cannot coexist with `ports:` declared in the base `docker-compose.yml` — raises `InvalidArgument`. The `extra_hosts` approach avoids this. ## Zigbee2MQTT Config Location The `configuration.yaml` **must be writable** — z2m migrates and rewrites it on startup. It lives in the data directory: ``` /opt/homelab/data/zigbee2mqtt/data/configuration.yaml ``` This path is mounted read-write by the base `docker-compose.yml`: ```yaml volumes: - /opt/homelab/data/zigbee2mqtt/data:/app/data ``` Do **not** mount `configuration.yaml` as a separate `:ro` volume — z2m will fail with `EROFS`. ### Minimal configuration.yaml ```yaml homeassistant: true permit_join: false mqtt: base_topic: zigbee2mqtt server: mqtt://mosquitto:1883 serial: port: tcp://192.168.1.105:6638 adapter: ezsp frontend: port: 8080 advanced: log_level: info ``` ## chelsty-ha — No node-agent `chelsty-ha` does not have a node-agent deployed. Home Assistant is monitored indirectly: if MQTT goes silent on `chelsty-infra`, HA is likely down. In `hosts/chelsty-ha/services.yaml`: ```yaml services: homeassistant: monitor: false # No node-agent; suppresses supervisor action generation ``` Remove `monitor: false` once node-agent is bootstrapped on this VM. ## Critical Backup Sets | Data | Path | |------|------| | HA config + DB | `/opt/homelab/data/homeassistant/` on chelsty-ha | | z2m config + coordinator backup + network key | `/opt/homelab/data/zigbee2mqtt/data/` | | Mosquitto persistence + password file | `/opt/homelab/data/mosquitto/` | | SLZB-06U coordinator state | Backup via SLZB-06U web UI at `192.168.1.105` | > ⚠️ The Zigbee network key is in `configuration.yaml` or `coordinator_backup.json` — losing it requires re-pairing all devices.