Tutoriales

Zigbee2MQTT: conecta dispositivos Zigbee a cualquier broker MQTT

Ejecuta Zigbee2MQTT con cualquier broker MQTT: configuration.yaml, TLS y credenciales, Docker, topics del bridge y de dispositivos, y cómo probar cada paso.

Actualizado · 8 min de lectura

Zigbee2MQTT: conecta dispositivos Zigbee a cualquier broker MQTT

Zigbee2MQTT convierte un coordinador Zigbee USB en una pasarela MQTT: cada sensor, bombilla e interruptor emparejado aparece como un mensaje JSON en un topic, y cada topic que termina en /set se convierte en un comando. No incluye broker: lo configuras en configuration.yaml, y sirve cualquier broker MQTT que cumpla el estándar: un Mosquitto local, el add-on de Home Assistant o un broker gestionado en la nube.

Este tutorial configura Zigbee2MQTT (2.x) con un broker externo, explica la estructura de topics y muestra cómo verificar la conexión y controlar un dispositivo desde la línea de comandos.

Cómo encajan las piezas

Flujo de datos
Zigbee device ──radio──▶ Coordinator (USB) ──serial──▶ Zigbee2MQTT ──MQTT──▶ Broker ──▶ Home Assistant / Node-RED / your app

Zigbee2MQTT es un cliente MQTT más. Eso tiene dos consecuencias prácticas: el broker puede estar en cualquier lugar accesible por red, y cualquier otra cosa que hable MQTT —un dashboard, un script, el cliente online— ve exactamente los mismos mensajes que tu software domótico.

Configuración mínima

Zigbee2MQTT lee data/configuration.yaml. La sección MQTT es la que lo conecta con tu broker:

data/configuration.yaml
mqtt:
  base_topic: testmqtt/z2m          # por defecto "zigbee2mqtt"
  server: mqtts://broker.connectmq.com:8883
  user: '!secret user'
  password: '!secret password'
  client_id: z2m-living-room
  keepalive: 60
  version: 5                        # 3, 4 (3.1.1) o 5

serial:
  port: /dev/ttyACM0
  adapter: ember                    # zstack, ember, deconz, zigate, zboss

frontend:
  enabled: true
  port: 8080

homeassistant:
  enabled: false                    # true si Home Assistant debe descubrir los dispositivos

advanced:
  log_level: info
data/secret.yaml
user: username
password: password

Notas sobre las claves importantes:

  • server: mqtt://host:1883 para TCP sin cifrar, mqtts://host:8883 para TLS. Las URLs WebSocket (wss://host:8084/mqtt) también funcionan porque Zigbee2MQTT usa MQTT.js por debajo, pero TCP es lo normal para una pasarela.
  • base_topic: la raíz de todo lo que publica Zigbee2MQTT. Mantén el valor por defecto zigbee2mqtt en un broker privado; en un broker de pruebas compartido usa una raíz única como la de arriba para no chocar con otros usuarios.
  • client_id: debe ser único en el broker. Dos instancias con el mismo ID se expulsarán mutuamente en bucle; consulta buenas prácticas de client ID.
  • ca, key, cert: solo para una CA privada o TLS mutuo. Un broker con certificado de confianza pública funciona solo con mqtts://. Nunca "arregles" errores de certificado con reject_unauthorized: false en producción.
  • !secret: guarda las credenciales en secret.yaml para que puedas compartir o versionar configuration.yaml con seguridad.

Todas las opciones se pueden fijar también con variables de entorno, algo cómodo en contenedores: ZIGBEE2MQTT_CONFIG_MQTT_SERVER, ZIGBEE2MQTT_CONFIG_MQTT_USER, ZIGBEE2MQTT_CONFIG_MQTT_PASSWORD, etc.

Ejecutarlo con Docker

docker-compose.yml
services:
  zigbee2mqtt:
    image: ghcr.io/koenkk/zigbee2mqtt
    restart: unless-stopped
    volumes:
      - ./data:/app/data
      - /run/udev:/run/udev:ro
    ports:
      - "8080:8080"
    environment:
      - TZ=Europe/Berlin
    devices:
      - /dev/serial/by-id/usb-ITead_Sonoff_Zigbee_3.0_USB_Dongle_Plus-if00-port0:/dev/ttyACM0

Mapea el coordinador por su ruta /dev/serial/by-id/...: /dev/ttyUSB0 puede cambiar tras un reinicio o al conectar otro dispositivo USB. Si ejecutas un broker local en el mismo Compose, refiérete a él por el nombre del servicio (mqtt://mosquitto:1883), no por localhost: dentro de un contenedor, localhost es el propio contenedor. La guía del stack Docker Compose cubre esa configuración.

Arráncalo y sigue el log:

Arrancar y seguir los logs
docker compose up -d
docker compose logs -f zigbee2mqtt

Un arranque correcto muestra Connecting to MQTT server at mqtts://broker.connectmq.com:8883 seguido de Connected to MQTT server. Si ves MQTT error: Connection refused: Not authorized o MQTT failed to connect, exiting..., revisa primero las credenciales y la pareja puerto/esquema; la guía de errores de Zigbee2MQTT repasa cada mensaje.

La estructura de topics

TopicDirecciónPayload
<base>/bridge/stateZ2M → broker (retenido){"state":"online"} / {"state":"offline"} (Last Will)
<base>/bridge/infoZ2M → broker (retenido)Versión, coordinador, configuración
<base>/bridge/devicesZ2M → broker (retenido)Todos los dispositivos emparejados con sus capacidades
<base>/bridge/eventZ2M → brokerDispositivo unido, entrevista terminada, salida
<base>/bridge/request/...Tú → Z2MPeticiones de administración (permit join, renombrar, eliminar)
<base>/bridge/response/...Z2M → túResultado de cada petición
<base>/<friendly_name>Z2M → brokerEstado del dispositivo en JSON
<base>/<friendly_name>/setTú → Z2MComandos en JSON
<base>/<friendly_name>/getTú → Z2MPedir al dispositivo que informe un valor
<base>/<friendly_name>/availabilityZ2M → broker (retenido){"state":"online"} si la disponibilidad está activada

Los dispositivos nuevos se nombran con su dirección IEEE (0x00158d0001a2b3c4). Renómbralos con algo significativo; una barra en el nombre crea jerarquía, así que living_room/ceiling se convierte en testmqtt/z2m/living_room/ceiling. Es la forma más sencilla de lograr un árbol de topics limpio para el hogar inteligente.

bridge/state, bridge/info y bridge/devices son mensajes retenidos, así que cualquier cliente que se suscriba después sabe al instante si el bridge está activo y qué dispositivos existen.

Prueba cada paso desde la línea de comandos

1. ¿Está conectado el bridge? Suscríbete al estado del bridge; el valor retenido llega al instante:

Estado del bridge
mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -u "$MQTT_USER" -P "$MQTT_PASS" -t 'testmqtt/z2m/bridge/state' -v
# testmqtt/z2m/bridge/state {"state":"online"}

2. Observa todo el tráfico mientras pulsas un botón o abres un sensor de puerta:

Todo bajo el topic base
mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -u "$MQTT_USER" -P "$MQTT_PASS" -t 'testmqtt/z2m/#' -v

3. Empareja un dispositivo abriendo la red durante un tiempo limitado (Zigbee2MQTT 2.x exige time; 0 la vuelve a cerrar):

Permit join durante 120 segundos
mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -u "$MQTT_USER" -P "$MQTT_PASS" \
  -t 'testmqtt/z2m/bridge/request/permit_join' -m '{"time": 120}'

La respuesta llega a bridge/response/permit_join, y bridge/event informa de device_joined y device_interview mientras el dispositivo se empareja.

4. Renómbralo y contrólalo:

Renombrar y conmutar
mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -u "$MQTT_USER" -P "$MQTT_PASS" -t 'testmqtt/z2m/bridge/request/device/rename' \
  -m '{"from": "0x00158d0001a2b3c4", "to": "living_room/ceiling"}'

mosquitto_pub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -u "$MQTT_USER" -P "$MQTT_PASS" -t 'testmqtt/z2m/living_room/ceiling/set' \
  -m '{"state": "TOGGLE", "brightness": 180, "transition": 1}'

El nuevo estado de la bombilla aparece en testmqtt/z2m/living_room/ceiling en menos de un segundo. Si un comando no hace nada, revisa bridge/logging: Zigbee2MQTT registra ahí los payloads rechazados.

Puedes hacer los mismos pasos en el navegador: abre el cliente MQTT online, suscríbete a testmqtt/z2m/# y publica en los topics /set desde el panel de publicación.

Ver tus topics de Zigbee2MQTT en directo

Integración con Home Assistant

Pon homeassistant: enabled: true y Zigbee2MQTT publica mensajes de discovery bajo homeassistant/.... La integración MQTT de Home Assistant debe apuntar al mismo broker; los dispositivos aparecen entonces automáticamente con todas sus entidades. Si cambiaste base_topic, no hay que tocar nada más: los payloads de discovery incluyen los topics de estado y de comando correctos. Consulta Home Assistant y MQTT para la parte del broker.

Checklist de producción

  1. Da a Zigbee2MQTT su propio usuario en el broker y limítalo a <base>/# más homeassistant/# si usas discovery.
  2. Usa TLS (mqtts://) siempre que el broker no esté en el mismo host.
  3. Activa availability para que los dispositivos desconectados se notifiquen en vez de quedarse obsoletos en silencio.
  4. Mantén permit_join cerrado salvo durante el emparejamiento.
  5. Haz copia de seguridad de todo el directorio data/: contiene la clave de red y la copia del coordinador, no solo la configuración.

Zigbee2MQTT es la forma más sencilla de liberar tus dispositivos Zigbee de los hubs de los fabricantes: un bloque YAML lo apunta a cualquier broker y, a partir de ahí, cada dispositivo es solo un topic. Verifica primero el estado del bridge, observa el tráfico mientras emparejas y controla los dispositivos con un simple mosquitto_pub antes de construir automatizaciones encima.

Preguntas frecuentes

¿Zigbee2MQTT incluye su propio broker MQTT?

No. Zigbee2MQTT es un cliente MQTT: traduce el tráfico de radio Zigbee en mensajes MQTT y necesita un broker externo, como Mosquitto, el add-on Mosquitto de Home Assistant o un broker gestionado.

¿Puede Zigbee2MQTT conectarse a un broker por TLS?

Sí. Pon mqtt.server en mqtts://host:8883. Con un broker que tenga un certificado de confianza pública no hace falta nada más; para una CA privada añade la opción ca, y para TLS mutuo añade key y cert.

¿Cómo controlo un dispositivo Zigbee por MQTT?

Publica JSON en <base_topic>/<friendly_name>/set, por ejemplo {"state": "TOGGLE"} o {"brightness": 128}. El nuevo estado del dispositivo se publica en <base_topic>/<friendly_name>.