Introduction
Zigbee is a low-power wireless protocol essential for IoT in 2026, especially in smart homes. Unlike power-hungry Wi-Fi, Zigbee forms a mesh network where each device relays signals, supporting 100+ nodes with extended range. Zigbee2MQTT is the leading open-source tool that translates Zigbee messages to MQTT, enabling seamless integration with Home Assistant, Node-RED, or custom apps.
This intermediate tutorial guides you step-by-step: from Docker installation to JavaScript-based automation. Why it matters? In 2026, with rising Matter/Zigbee hybrids, mastering Zigbee2MQTT maximizes sensor battery life (up to 2 years) and reduces latency to <100ms. Result: a scalable, secure, cost-effective setup. Ready to turn your Raspberry Pi into a Zigbee coordinator?
Prerequisites
- Raspberry Pi 4+ (or Linux PC) with Docker and Docker Compose installed
- Compatible Zigbee dongle (e.g., Sonoff Zigbee 3.0 USB Dongle Plus, ID:
/dev/ttyUSB0) - MQTT broker (Mosquitto) or built-in
- Node.js 20+ for client scripts
- A Zigbee device to test (e.g., IKEA Tradfri or Tuya bulb)
- Basic knowledge of Docker, YAML, and MQTT
Create docker-compose.yml
version: '3.8'
services:
zigbee2mqtt:
image: ghcr.io/koenkk/zigbee2mqtt:2.0.6
restart: unless-stopped
devices:
- /dev/ttyUSB0:/dev/ttyUSB0
volumes:
- ./data:/app/data
- /run/udev:/run/udev:ro
ports:
- '8080:8080'
environment:
- TZ=Europe/Paris
depends_on:
- mqtt
mqtt:
image: eclipse-mosquitto:2.0
restart: unless-stopped
command: mosquitto -c /mosquitto/config/mosquitto.conf
volumes:
- ./mosquitto/config:/mosquitto/config
- ./mosquitto/data:/mosquitto/data
- ./mosquitto/log:/mosquitto/log
ports:
- '1883:1883'
- '9001:9001'
networks:
default:
name: zigbee-networkThis docker-compose deploys Zigbee2MQTT and Mosquitto in an isolated network. It mounts the USB dongle, persists data, and exposes MQTT on 1883. Create the folders ./data, ./mosquitto/config/data/log before launch to avoid volume errors.
Configure Mosquitto
Create the Mosquitto config file to enable anonymous connections (secure it in production). This allows Zigbee2MQTT to publish directly to MQTT topics like zigbee2mqtt/bridge/log.
mosquitto.conf
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
listener 1883
allow_anonymous true
listener 9001
protocol websockets
allow_anonymous trueMinimal configuration: session persistence, logging enabled, anonymous access for development. In production, add password_file and TLS certificates. Port 9001 is for WebSockets, useful for dashboards like Node-RED.
Launch the Stack
Run docker compose up -d in the docker-compose directory. Check logs with docker compose logs zigbee2mqtt. The Zigbee2MQTT UI will be at http://localhost:8080.
Start and Verify
#!/bin/bash
mkdir -p data mosquitto/{config,data,log}
docker compose up -d
echo "Attendre 30s pour init..."
sleep 30
docker compose logs zigbee2mqtt | tail -10
docker compose psComplete bash script for bootstrap: creates volumes, launches in detached mode, shows the last 10 logs and status. If 'serialport' error, check ls -l /dev/ttyUSB0 and udev permissions (99-zigbee.rules).
Configure Zigbee2MQTT
Edit data/configuration.yaml to set the serial port and MQTT. Enable permit_join: true via the UI to add devices.
configuration.yaml
homeassistant: true
permit_join: false
mqtt:
base_topic: zigbee2mqtt
server: mqtt://mqtt:1883
serial:
port: /dev/ttyUSB0
adapter: ezsp
advanced:
network_key: !secret network_key
pan_id: 0x1a62
channel: 11
frontend:
port: 8080
availability: true
Full config: Home Assistant auto-discovery, local MQTT, EZSP adapter for Sonoff dongle. Use network_key as a secret for security (generate with openssl rand -hex 16). Change channel if Wi-Fi interference.
Enable Pairing via API
#!/bin/bash
curl -X POST -H "Content-Type: application/json" \
-d '{"value": true}' \
http://localhost:8080/api/state/permit_join
echo "Pairing activé 255s. Appuyez sur reset de votre device Zigbee."
sleep 260
curl -X POST -H "Content-Type: application/json" \
-d '{"value": false}' \
http://localhost:8080/api/state/permit_join
echo "Pairing désactivé."Script to toggle permit_join via Z2M REST API. Run it to add a device: waits max 255s. Check the UI or MQTT for the new device (e.g., topic zigbee2mqtt/LumiereSalon).
MQTT Client in JavaScript
Create a Node.js script to subscribe to Zigbee events via MQTT. Great for custom automations without Home Assistant.
mqtt-client.js
const mqtt = require('mqtt');
const client = mqtt.connect('mqtt://localhost:1883');
client.on('connect', () => {
console.log('Connecté MQTT');
client.subscribe('zigbee2mqtt/#', (err) => {
if (!err) console.log('Souscrit à zigbee2mqtt/#');
});
});
client.on('message', (topic, message) => {
const payload = JSON.parse(message.toString());
console.log(`${topic}:`, payload);
if (topic.endsWith('/state') && payload.state?.brightness) {
console.log('Luminosité changée:', payload.state.brightness);
}
});
process.on('SIGINT', () => {
client.end();
process.exit();
});Full MQTT client with mqtt.js: subscribes to all Zigbee2MQTT topics, parses JSON, logs events. Example: reacts to brightness changes. Install with npm i mqtt, run node mqtt-client.js. Scalable for webhooks.
Best Practices
- Secure MQTT: Enable TLS and authentication in production (
require_certificate truein mosquitto.conf). - Choose the right channel: Use a Zigbee analyzer (e.g., zigbee-channelz) to avoid 2.4GHz interference.
- Regular backups: Copy
./dataweekly; restore viadatabase.sqlite. - Optimized mesh: Place 3+ routers (e.g., Philips Hue plugs) for >90% coverage.
- Monitoring: Integrate Prometheus via Z2M exporter to alert on dead devices.
Common Errors to Avoid
- Dongle not detected: Check
dmesg | grep ttyUSBand add udev rule (SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", GROUP="dialout"). - 'No response from device': Channel mismatch; force
channel: 15and reset network_key. - MQTT disconnected: Verify firewall (ufw allow 1883) and
availability: truein config. - Pairing fails: Battery <20% or distance >10m; use a nearby repeater.
Next Steps
Integrate with Home Assistant via auto-discovery. Check the Zigbee2MQTT docs. For custom firmware, see Tasmota Zigbee. Explore our IoT training courses on MQTT and advanced mesh networks.