Skip to content

Zigbee2MQTT

Zigbee2MQTT allows you to use your Zigbee devices without the need for proprietary bridges or gateways. It bridges events from the Zigbee network to the Mosquitto MQTT broker, which are then discovered by Home Assistant, and from there exposed to voice platforms through the Matter Hub.

The module lives in modules/nixos/services/zigbee2mqtt.nix and is enabled in hosts/nixos/configuration.nix.

  • Coordinator: SONOFF Dongle Max MG24 (Zigbee firmware).
  • Connection: Local USB Port.
  • Stable Device Path: /dev/SONOFF_Dongle_Max_MG24-zigbee.
  • Reason for Migration: The MG24 dongle is the same hardware family used as the Thread RCP for the OTBR. Two physical MG24 sticks are deployed — one flashed for Zigbee, one for Thread — and distinguished by serial number via the USB aliases module (see below).

[!IMPORTANT] The two MG24 dongles are identical by model and differ only by serial number. The system resolves them to stable symlinks via udev, so services never depend on the volatile by-id ordering.

  • Coordinator: SONOFF Zigbee 3.0 USB Dongle Plus.
  • Connection: Local USB Port.
  • Path: /dev/serial/by-id/usb-...
  • Reason for Migration: Improved stability and lower latency. By using USB, we eliminated dependencies on internal network routing and static IPs (iotDongleIp).
  • Coordinator: SONOFF Zigbee/Thread PoE Dongle MAX (Dongle-M).
  • Connection: Ethernet/PoE (Remote TCP Bridge).
  • Port: tcp://192.168.1.101:6638.
  • Coordinator: Texas Instruments CC2531 USB Stick.

Stable device aliases for both MG24 dongles are created by modules/nixos/system/usb-aliases.nix, which installs udev rules that match each stick by serial number and exposes a human-readable symlink:

SymlinkDongleFirmware / RoleUsed By
/dev/SONOFF_Dongle_Max_MG24-zigbeeMG24 (serial A)Zigbee coordinatorZigbee2MQTT
/dev/SONOFF_Dongle_Max_MG24-threadMG24 (serial B)Thread RCPOpenThread BR

Zigbee2MQTT is configured to bind to /dev/SONOFF_Dongle_Max_MG24-zigbee, so its coordinator assignment does not change across reboots or when USB ports are reordered.

PortProtocolDescription
8080HTTPWeb Interface (Frontend)
6638TCPRemote Zigbee-over-TCP (legacy, Dongle-M only)

The Web UI is accessible externally via the Cloudflare Tunnel:

  • URL: https://zigbee2mqtt-home.javiersc.com
  • Internal: http://localhost:8080

The Nginx reverse proxy has WebSocket support enabled so the live log stream and device state updates work correctly over the tunnel without falling back to HTTP polling.

MQTT credentials are required to connect to Mosquitto.

Secret PathKeyEnvironment Variable
op://Homelab/Mosquito/usernameusernameZIGBEE2MQTT_CONFIG_MQTT_USER
op://Homelab/Mosquito/passwordpasswordZIGBEE2MQTT_CONFIG_MQTT_PASSWORD
  • Paths: /var/lib/zigbee2mqtt (Device database and state).
  • Exclusions: *.log, configuration_backup_*.yaml, log/.

[!IMPORTANT] Coordinator Migration: When moving from a CC2531 (Z-Stack) to a Dongle-M (EZSP/Ember), you MUST wipe the /var/lib/zigbee2mqtt directory. The backup files from the old coordinator are incompatible and will prevent the service from starting.

If Zigbee2MQTT cannot reach the coordinator:

  1. Confirm the MG24 Zigbee stick is present at /dev/SONOFF_Dongle_Max_MG24-zigbee (ls -l /dev/SONOFF_Dongle_Max_MG24-zigbee).
  2. Verify the correct serial number is matched by the udev rule in modules/nixos/system/usb-aliases.nix.
  3. (Legacy Dongle-M only) If running the older PoE coordinator, ensure it is powered via PoE and its IP is fixed to 192.168.1.101 with port 6638 enabled in its web interface.
Terminal window
journalctl -u zigbee2mqtt -f

If you decide to go back to a network-based coordinator (like the Dongle-M):

  1. Add the coordinator IP as an explicit option or value in the Zigbee2MQTT service module.
  2. Update modules/nixos/services/zigbee2mqtt.nix to use tcp://<ip>:6638 as the zigbeePort.
  3. Ensure the device has a static IP lease in your router.
  1. Access the Web UI.
  2. Click “Permit join (All)”.
  3. Put your device in pairing mode (e.g., hold the reset button for 5 seconds).
  4. The device should appear in the list.