Files
network/migratezwave.md
T

4.0 KiB

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)

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