Document Z-Wave JS and Zigbee2MQTT on Docker host; drop Raspberry Pi docs

- raspi_zwave.md -> zwave_zigbee.md: zwavejs + zigbee2mqtt containers, Z-Net G8 ports 2001/2002
- Remove obsolete migratezwave.md plan
- Add containers to docker.md, MQTT/Zigbee notes to ha.md, component entry to CLAUDE.md
This commit is contained in:
dohertj2
2026-10-09 07:23:22 -04:00
parent 0b2f68a1c2
commit fab35e8e7c
6 changed files with 74 additions and 137 deletions
+1
View File
@@ -27,4 +27,5 @@ Credentials live inline in each component's `.md` file under its **Access** sect
- [Veeam Server](veeam.md) — Windows Server 2025 at 10.100.0.30, Veeam B&R 12.3, backup server. **Read veeam.md for credentials and connection details.** - [Veeam Server](veeam.md) — Windows Server 2025 at 10.100.0.30, Veeam B&R 12.3, backup server. **Read veeam.md for credentials and connection details.**
- [Desktop](desktop.md) — Windows PC, dual-homed on LAN_100 (10.100.0.49) and DATA_50 (10.50.0.49) - [Desktop](desktop.md) — Windows PC, dual-homed on LAN_100 (10.100.0.49) and DATA_50 (10.50.0.49)
- [Wonderware Dev VM](ww.md) — Windows 10 ESXi VM at 10.100.0.48, OpenSSH (passwordless) - [Wonderware Dev VM](ww.md) — Windows 10 ESXi VM at 10.100.0.48, OpenSSH (passwordless)
- [Z-Wave & Zigbee](zwave_zigbee.md) — HomeSeer Z-Net G8 at 10.200.0.106 hosts both radios (Z-Wave on :2001, SmartStick ZB on :2002). `zwavejs` (HA → ws://10.100.0.35:3100) and `zigbee2mqtt` (→ HA Mosquitto) containers on the Docker host, deployed via the playbook. Old Raspberry Pi is gone.
- [Unifi Network](unifi.md) — UDM Pro gateway + USW Pro Aggregation central switch, API access via key - [Unifi Network](unifi.md) — UDM Pro gateway + USW Pro Aggregation central switch, API access via key
+3 -1
View File
@@ -100,6 +100,8 @@ All 21 containers running. Most are on the `traefik` network.
| Container | Image | URL | Port | Purpose | | Container | Image | URL | Port | Purpose |
|-----------|-------|-----|------|---------| |-----------|-------|-----|------|---------|
| semaphore | semaphoreui/semaphore:latest | http://10.100.0.35:3000 | 3000 | Ansible UI | | semaphore | semaphoreui/semaphore:latest | http://10.100.0.35:3000 | 3000 | Ansible UI |
| zwavejs | zwavejs/zwave-js-ui:latest | zwave.dohertylan.com | 8091 (UI), 3100→3000 (HA websocket) | Z-Wave JS UI for HA — see [zwave_zigbee.md](zwave_zigbee.md) |
| zigbee2mqtt | koenkk/zigbee2mqtt:latest | zigbee.dohertylan.com | 8080 (UI, Traefik only) | Zigbee coordinator → HA Mosquitto — see [zwave_zigbee.md](zwave_zigbee.md) |
### lmxopcua (carry `project=lmxopcua` label) ### lmxopcua (carry `project=lmxopcua` label)
@@ -138,7 +140,7 @@ All compose files are under `/opt/<service>/docker-compose.yml`:
/opt/tautulli/ /opt/nzbget/ /opt/vpn_downloads/ /opt/tautulli/ /opt/nzbget/ /opt/vpn_downloads/
/opt/uptime_kuma/ /opt/stash/ /opt/utilities/ /opt/uptime_kuma/ /opt/stash/ /opt/utilities/
/opt/semaphore/ /opt/ilo_fan/ /opt/semaphore/ /opt/ilo_fan/
/opt/plex/ /opt/plex/ /opt/zwavejs/ /opt/zigbee2mqtt/
/opt/otopcua-mssql/ /opt/otopcua-modbus/ /opt/otopcua-abcip/ /opt/otopcua-mssql/ /opt/otopcua-modbus/ /opt/otopcua-abcip/
/opt/otopcua-s7/ /opt/otopcua-opcuaclient/ /opt/otopcua-s7/ /opt/otopcua-opcuaclient/
``` ```
+2 -2
View File
@@ -43,8 +43,8 @@
| Category | Integrations | | Category | Integrations |
|----------|-------------| |----------|-------------|
| **Z-Wave / Zigbee / Matter** | zwave_js, matter | | **Z-Wave / Zigbee / Matter** | zwave_js, matter, Zigbee via Zigbee2MQTT over mqtt — see [zwave_zigbee.md](zwave_zigbee.md) |
| **MQTT / ESPHome** | mqtt, esphome | | **MQTT / ESPHome** | mqtt (Mosquitto broker add-on; logins `caffha`, `watermgr`, `zigbee2mqtt`), esphome |
| **WiFi Devices** | shelly, ac_infinity, flair, midea_dehumidifier_lan, govee_ble | | **WiFi Devices** | shelly, ac_infinity, flair, midea_dehumidifier_lan, govee_ble |
| **Appliances** | ge_home, roborock | | **Appliances** | ge_home, roborock |
| **Media** | sonos, apple_tv, cast, webostv | | **Media** | sonos, apple_tv, cast, webostv |
-79
View File
@@ -1,79 +0,0 @@
# Migrate Z-Wave JS from Raspberry Pi to Home Assistant
## Context
Z-Wave JS UI currently runs on a Raspberry Pi (10.200.0.190) as a Docker container, connecting to the Z-Net G8 controller at `tcp://10.200.0.106:2001`. Home Assistant then connects to the Raspi's websocket on port 3000. This adds an unnecessary hop and dependency on the Raspi. Since the Z-Net G8 is network-based, HA can connect to it directly.
**Current**: HA → ws:3000 → Raspi (Z-Wave JS UI Docker) → tcp:2001 → Z-Net G8
**Target**: HA → Z-Wave JS add-on (local) → tcp:2001 → Z-Net G8
## Current State
- **219 Z-Wave entities** in HA
- **~23 Z-Wave nodes** with custom names (DownstairsBathroomFan, GarageSensor1, etc.)
- **Security keys** (S0, S2 Auth/Unauth/Access Control, LR) configured in Z-Wave JS UI
- Device pairings stored in Z-Net G8 NVM (persist regardless of software change)
- Raspi also runs: zigbee2mqtt, portainer_agent, ouroboros (these stay on the Raspi)
## Recommended Approach: Z-Wave JS UI Add-on on HAOS
Install the **Z-Wave JS UI community add-on** on HAOS rather than the official Z-Wave JS add-on. Reasons:
- Same software as current setup → minimal risk
- Keeps the full web UI for network management
- HomeSeer docs specifically recommend Z-Wave JS UI for Z-Net controllers
- Security keys and node names can be migrated directly
## Steps
### 1. Backup current Z-Wave JS UI on Raspi
- Create NVM backup from the Z-Wave JS UI web interface (http://10.200.0.190:8091)
- Copy the store directory from the Raspi container: `sudo docker exec zwavejs2mqtt tar czf /tmp/zwave-store-backup.tar.gz /usr/src/app/store/`
- Copy backup locally: `scp dohertj2@10.200.0.190:/tmp/zwave-store-backup.tar.gz ./`
- Save the settings.json (contains security keys and TCP port config)
### 2. Stop Z-Wave JS UI on Raspi
- `ssh dohertj2@10.200.0.190 "sudo docker stop zwavejs2mqtt"`
- This releases the TCP connection to the Z-Net G8 (only one client can hold it)
### 3. Install Z-Wave JS UI add-on on HAOS
- Via HA web UI: Settings → Add-ons → Add-on Store → search "Z-Wave JS UI" (community add-on)
- OR via API if possible: add the community add-on repository and install
### 4. Configure the add-on
- Set serial port to `tcp://10.200.0.106:2001`
- Enter the existing security keys:
- S2_Unauthenticated: `015BD790CCDB08172CBD12754C73E4D3`
- S2_AccessControl: `B3F99B99EE958BFAE813A84FD3586E2A`
- S0_Legacy: `FBF63F5E6515286C3AB8CC9E5F275B46`
- S2_Authenticated: `67E9ECD830733A1E1BEB22DC0EAA2739`
- S2_Authenticated_LR: `2176EE246C67320A42F2C0A23932E9B5`
- S2_AccessControl_LR: `E534F94FCD0BE8B42F056F2F3548002E`
- Start the add-on
### 5. Reconfigure HA Z-Wave JS integration
- Remove the current zwave_js integration (pointing to ws://10.200.0.190:3000)
- Re-add it pointing to the local add-on's websocket (ws://localhost:3000 or the add-on's internal URL)
- Verify all 219 entities are rediscovered with correct names/device assignments
### 6. Verify
- Check all Z-Wave nodes are online in the Z-Wave JS UI add-on
- Confirm entity count matches (~219)
- Test a few devices (turn a light on/off, check a sensor reading)
- Verify automations that use Z-Wave devices still work
### 7. Cleanup
- Remove the zwavejs2mqtt container from the Raspi: `sudo docker rm zwavejs2mqtt`
- Update `raspi_zwave.md` to reflect new architecture
## Risk Mitigation
- **Rollback**: If anything goes wrong, stop the HA add-on, restart the Raspi container, and re-point the integration back
- **Entity IDs**: Removing and re-adding the integration may change entity IDs. HA should re-discover them with the same unique IDs from Z-Wave JS, but automations/dashboards may need updating if not
- **Cross-VLAN**: HA (10.100.0.40, VLAN 100) must be able to reach Z-Net G8 (10.200.0.106, VLAN 200) on TCP port 2001 — confirmed allowed
## Verification
1. Entity count: `curl -s http://10.100.0.40:8123/api/template -d '{"template":"{{ integration_entities(\"zwave_js\") | list | length }}"}' ` should return ~219
2. Z-Wave JS UI web interface accessible from HA add-on
3. Test device control via HA
4. Check HA logs for Z-Wave errors
-55
View File
@@ -1,55 +0,0 @@
# Z-Wave Infrastructure
## Architecture
```
HA (10.100.0.40) --ws:3000--> Raspberry Pi (10.200.0.190) --tcp:2001--> Z-Net G8 (10.200.0.106)
(Z-Wave JS UI) (Z-Wave radio controller)
```
## Z-Net G8 (Z-Wave Controller)
- **Hostname**: Z-Net-G8
- **IP**: 10.200.0.106 (IOT_200, VLAN 200)
- **MAC**: 02:53:ec:d0:de:dd
- **Manufacturer**: HomeSeer Technologies
- **Role**: Z-Wave radio controller (Node 1), serial-over-TCP on port 2001
## Raspberry Pi (Z-Wave JS UI Host)
- **Hostname**: zwave
- **IP**: 10.200.0.190 (IOT_200, VLAN 200)
- **MAC**: e4:5f:01:02:3c:26
- **Hardware**: Raspberry Pi (Raspberry Pi Trading Ltd)
- **SSH**: `ssh dohertj2@10.200.0.190` (passwordless)
- **Web UI**: http://10.200.0.190:8091
- **Z-Wave JS websocket**: ws://10.200.0.190:3000
### Docker Containers
| Container | Image | Ports |
|-----------|-------|-------|
| zwavejs2mqtt | zwavejs/zwave-js-ui:latest | 3000 (websocket), 8091 (web UI) |
| zigbee2mqtt | koenkk/zigbee2mqtt:latest | — |
| portainer_agent | portainer/agent:2.21.5 | 9001 |
| ouroboros | pyouroboros/ouroboros | — |
### Z-Wave JS Config
- **Serial port**: `tcp://10.200.0.106:2001` (Z-Net G8 over network)
- **Z-Wave region**: 1 (US)
- **Server port**: 3000 (websocket for HA)
- **Status**: ready
## Home Assistant Integration
- **Integration**: zwave_js
- **Connects to**: ws://10.200.0.190:3000
- **Node 1**: HomeSeer Z-Wave Shield with External Antenna (Z-Net G8)
## Notes
- Both devices sit on the IoT VLAN (10.200.0.0/24)
- HA connects cross-VLAN (LAN_100 -> IOT_200) to the Raspi websocket
- The Raspi also runs Zigbee2MQTT (separate Zigbee network)
- Tracked by Unifi as device_tracker.zwave (Raspi) and device_tracker.z_net_g8 (controller)
+68
View File
@@ -0,0 +1,68 @@
# Z-Wave & Zigbee Infrastructure
## Architecture
```
Z-Wave: HA (10.100.0.40) --ws:3100--> Docker host (10.100.0.35) zwavejs --tcp:2001--> Z-Net G8 (10.200.0.106) Z-Wave radio
Zigbee: HA Mosquitto (10.100.0.40:1883) <--mqtt-- Docker host zigbee2mqtt --tcp:2002--> Z-Net G8 SmartStick ZB (USB)
```
Both radios live on the Z-Net G8; both controller apps run as containers on the Docker host, deployed by the Ansible playbook (`~/playbook`, roles `zwavejs` and `zigbee2mqtt`).
The Raspberry Pi (10.200.0.190) that previously hosted Z-Wave JS UI is gone.
## Z-Net G8 (Z-Wave Controller)
- **Hostname**: Z-Net-G8
- **IP**: 10.200.0.106 (IOT_200, VLAN 200)
- **MAC**: 02:53:ec:d0:de:dd
- **Manufacturer**: HomeSeer Technologies
- **Role**: Z-Wave radio controller (Node 1), serial-over-TCP on port 2001
- **Zigbee**: HomeSeer SmartStick ZB plugged into the Z-Net's USB, exposed on port **2002** (2003 is for older Sonoff ZBDongle-E revisions). Requires Z-Net firmware ≥ 1.0.27 (running 1.0.27).
- **Web UI**: http://10.200.0.106/
## Z-Wave JS UI (container on the Docker host)
- **Host**: [Docker Server](docker.md) — `ssh dohertj2@10.100.0.35`
- **Container**: `zwavejs` (`zwavejs/zwave-js-ui:latest`), restart `unless-stopped`, created 2026-07-03
- **Compose file**: `/opt/zwavejs/docker-compose.yml` (templated by playbook role `zwavejs`)
- **Store/data**: `/opt/zwavejs/store` → `/usr/src/app/store` (`settings.json`, `nodes.json`, `backups/`)
- **Network**: `traefik`
- **Web UI**: https://zwave.dohertylan.com (Traefik → port 8091, Authelia SSO; Z-Wave JS UI's own auth is disabled)
- **Z-Wave JS websocket**: ws://10.100.0.35:3100 (host 3100 → container 3000)
### Z-Wave JS Config
- **Serial port**: `tcp://10.200.0.106:2001` (Z-Net G8 over network)
- **Z-Wave region**: 1 (US)
- **Server port**: 3000 in container (published as 3100)
## Home Assistant Integration
- **Integration**: zwave_js
- **Connects to**: ws://10.100.0.35:3100
- **Size**: 25 devices, 296 entities (2026-10-09)
- **Node 1**: HomeSeer Z-Wave Shield with External Antenna (Z-Net G8)
- Two stale `not_loaded` config entries remain (an old "Z-Wave JS" entry and a Silicon Labs CP2102N USB serial entry)
## Zigbee2MQTT (container on the Docker host)
- **Container**: `zigbee2mqtt` (`koenkk/zigbee2mqtt:latest`, 2.14.2 at deploy), restart `unless-stopped`, deployed 2026-10-09
- **Playbook role**: `zigbee2mqtt` — `sudo ansible-playbook site.yml -i localhost, -c local --tags zigbee2mqtt --limit localhost` from `~/playbook` (Semaphore currently has no project configured)
- **Compose file**: `/opt/zigbee2mqtt/docker-compose.yml`
- **Data**: `/opt/zigbee2mqtt/data` → `/app/data` (`configuration.yaml` holds the generated network key — back it up; `coordinator_backup.json`)
- **Config ownership**: `configuration.yaml` is seeded once by Ansible (never overwritten); MQTT, serial and frontend settings are enforced by `ZIGBEE2MQTT_CONFIG_*` env vars in the compose file
- **Web UI**: https://zigbee.dohertylan.com (Traefik → port 8080, Authelia SSO)
- **Coordinator**: `tcp://10.200.0.106:2002`, adapter `ember`, EmberZNet 7.4.3, IEEE 0x8c8b48fffe2dd481
- **Network**: channel 25, PAN ID 64462 (0xFBCE) — new network formed 2026-10-09; all devices must be (re)paired
- **MQTT**: HA's Mosquitto broker add-on at mqtt://10.100.0.40:1883, base topic `zigbee2mqtt`, HA discovery enabled
- **User**: `zigbee2mqtt` / **Password**: `Aywm6DjOR3bfSo9c7zDoWDxX` (login in the Mosquitto add-on options; also in the playbook role defaults)
### Pairing devices
Turn on **Permit join** in the Zigbee2MQTT web UI (or the `switch.zigbee2mqtt_bridge_permit_join` entity in HA), then reset/pair the device. It appears in HA automatically via MQTT discovery.
## Notes
- Z-Net G8 is on the IoT VLAN; the Docker host reaches it cross-VLAN (or via its IOT_200 interface 10.200.0.35)
- Tracked by Unifi as device_tracker.z_net_g8