Zigbee2MQTT kojarzy się głównie z dodatkiem do Home Assistanta, ale do działania wcale go nie potrzebuje. To po prostu most: komunikuje się z czujnikami, żarówkami i włącznikami Zigbee przez adapter USB lub sieciowy i publikuje wszystko jako wiadomości MQTT. Z tych urządzeń może potem korzystać każdy program obsługujący MQTT: Node-RED, openHAB, skrypt w Pythonie, ESP32 albo zwykłe narzędzie wiersza poleceń. W tym poradniku uruchomisz Zigbee2MQTT i Mosquitto w Dockerze na dowolnym komputerze z Linuksem, sparujesz pierwsze urządzenie i poznasz tematy MQTT, których będziesz używać na co dzień.

Czego potrzebujesz

Według dokumentacji Zigbee2MQTT potrzebne są trzy elementy:

  1. Adapter Zigbee. Twórcy projektu polecają adaptery z oprogramowaniem zStack (Texas Instruments) lub EmberZNet (Silicon Labs). Przed instalacją zajrzyj na stronę swojego adaptera w dokumentacji, bo niektóre modele wymagają dodatkowych ustawień.
  2. Komputer. Raspberry Pi, mini PC albo dowolny serwer z Linuksem i Dockerem. Do tego broker MQTT; zalecany jest Mosquitto.
  3. Urządzenia Zigbee do sparowania.

Adapter USB podłącz przez przedłużacz USB, a nie bezpośrednio do komputera. Według dokumentacji to pierwsza rzecz do sprawdzenia przy kłopotach z przekroczonym czasem odpowiedzi, parowaniem albo znikającymi urządzeniami, bo dzięki niemu jest mniej zakłóceń.

Znajdź stałą ścieżkę do adaptera

Nazwy w rodzaju /dev/ttyUSB0 czy /dev/ttyACM0 mogą się zmienić po restarcie albo po podłączeniu innego urządzenia USB. Lepiej użyć stałej ścieżki z katalogu /dev/serial/by-id/:

ls -l /dev/serial/by-id/

Zobaczysz coś w rodzaju usb-ITead_Sonoff_Zigbee_3.0_USB_Dongle_Plus_...-if00-port0. Skopiuj pełną nazwę. Adaptery sieciowe (z Ethernetem lub Wi-Fi) mają zamiast tego adres tcp://IP:PORT.

Docker Compose z Mosquitto i Zigbee2MQTT

Utwórz katalog, na przykład ~/zigbee, a w nim plik compose.yaml:

services:
  mosquitto:
    image: eclipse-mosquitto:2
    container_name: mosquitto
    restart: unless-stopped
    ports:
      - 1883:1883
    volumes:
      - ./mosquitto/config:/mosquitto/config
      - ./mosquitto/data:/mosquitto/data

  zigbee2mqtt:
    image: ghcr.io/koenkk/zigbee2mqtt
    container_name: zigbee2mqtt
    restart: unless-stopped
    depends_on:
      - mosquitto
    ports:
      - 8080:8080
    volumes:
      - ./z2m-data:/app/data
      - /run/udev:/run/udev:ro
    environment:
      - TZ=Europe/Warsaw
    devices:
      - /dev/serial/by-id/IDENTYFIKATOR-ADAPTERA:/dev/ttyACM0

Część dotycząca Zigbee2MQTT odpowiada oficjalnemu przykładowi dla Dockera. Katalog /run/udev jest zamontowany tylko do odczytu, żeby Zigbee2MQTT mógł wykryć adapter. W ./z2m-data trafiają konfiguracja i stan sieci, a restart: unless-stopped uruchamia kontener ponownie po awarii lub restarcie.

Dla Mosquitto utwórz plik mosquitto/config/mosquitto.conf:

listener 1883
allow_anonymous false
password_file /mosquitto/config/passwd
persistence true
persistence_location /mosquitto/data/

Załóż konto dla Zigbee2MQTT i drugie dla siebie:

docker compose run --rm mosquitto mosquitto_passwd -c /mosquitto/config/passwd z2m
docker compose run --rm mosquitto mosquitto_passwd /mosquitto/config/passwd me

Potem uruchom całość:

docker compose up -d

Konfiguracja początkowa

Przy pierwszym uruchomieniu, gdy nie ma jeszcze pliku configuration.yaml, Zigbee2MQTT wyświetla na porcie 8080 stronę konfiguracji początkowej. Otwórz http://IP-SERWERA:8080 i uzupełnij pola:

  • Adapter: zwykle wykrywa się automatycznie. Jeśli nie, wpisz ścieżkę wewnątrz kontenera (w przykładzie powyżej /dev/ttyACM0) i typ adaptera (zstack, ember itd.).
  • Serwer MQTT: mqtt://mosquitto:1883. W sieci tworzonej przez Compose kontenery są dostępne pod nazwami usług.
  • Użytkownik i hasło MQTT: konto z2m utworzone przed chwilą.
  • Ustawienia sieci: wybierz automatyczne generowanie identyfikatora PAN, rozszerzonego identyfikatora PAN i klucza sieci. Według dokumentacji zmiana klucza sieci w przyszłości oznacza ponowne parowanie wszystkich urządzeń, więc zdecyduj raz.
  • Kanał: domyślnie 11. W dokumentacji zalecane są kanały ZLL: 11, 15, 20 lub 25. Wybierz taki, który nie pokrywa się z najbardziej obciążonym kanałem Wi-Fi 2,4 GHz w okolicy.

Po zatwierdzeniu Zigbee2MQTT zapisuje configuration.yaml w katalogu z2m-data i startuje. Jeśli coś jest nie tak, na przykład ścieżka adaptera, strona konfiguracji pojawi się znowu przy następnym uruchomieniu.

Zabezpiecz interfejs WWW i pliki

W przewodniku bezpieczeństwa Zigbee2MQTT jedna sprawa jest postawiona jasno: każdy, kto ma dostęp do interfejsu WWW albo brokera MQTT, ma pełną kontrolę nad siecią Zigbee. Dlatego:

  • Ustaw token interfejsu WWW w configuration.yaml, najlepiej z odwołaniem do osobnego pliku z sekretami:
frontend:
  enabled: true
  auth_token: '!secret.yaml auth_token'

a w pliku z2m-data/secret.yaml wpisz auth_token: dlugi-losowy-ciag. Do tego samego pliku możesz przenieść hasło MQTT i klucz sieci.

  • Ogranicz uprawnienia plików: chmod 600 configuration.yaml secret.yaml.
  • Nie wystawiaj portów 8080 ani 1883 do internetu. Do zdalnego dostępu użyj VPN.
  • Rozważ wariant bez uprawnień roota opisany w dokumentacji: kontener działa wtedy z identyfikatorem zwykłego użytkownika i z dodaną grupą dialout, która daje dostęp do adaptera.

Sparuj urządzenie

Otwórz interfejs WWW i kliknij Permit join (All). Dołączanie będzie otwarte przez 254 sekundy. Przełącz urządzenie w tryb parowania, zwykle przez reset opisany na jego stronie na liście obsługiwanych urządzeń Zigbee2MQTT. W dzienniku powinien pojawić się wiersz kończący się na device has successfully been paired.

Nadaj urządzeniu przyjazną nazwę, na przykład lampa_salon. Nazwa staje się częścią tematu MQTT, więc wybierz coś krótkiego i bez spacji.

Korzystaj z tematów MQTT

Wszystko, co robi Zigbee2MQTT, widać w MQTT i przez MQTT można tym sterować. Domyślny temat bazowy to zigbee2mqtt.

Podgląd wszystkich wiadomości:

mosquitto_sub -h IP-SERWERA -u me -P 'haslo' -t 'zigbee2mqtt/#' -v

Czujnik publikuje swój stan w formacie JSON w temacie zigbee2mqtt/PRZYJAZNA_NAZWA, na przykład temperaturę, wilgotność i poziom baterii.

Włączenie lampy:

mosquitto_pub -h IP-SERWERA -u me -P 'haslo' \
  -t 'zigbee2mqtt/lampa_salon/set' -m '{"state": "ON", "brightness": 150}'

Jeśli wolisz zwykłe wartości, wysłanie ON do tematu zigbee2mqtt/lampa_salon/set/state działa tak samo jak wiadomość JSON.

Aby odczytać wartość na żądanie, wyślij {"state": ""} do tematu zigbee2mqtt/PRZYJAZNA_NAZWA/get. Co można odczytać i ustawić w danym urządzeniu, znajdziesz w sekcji Exposes na jego stronie.

Przez MQTT zarządzasz też samym mostem:

  • zigbee2mqtt/bridge/request/permit_join z treścią {"time": 254} otwiera dołączanie bez interfejsu WWW,
  • zigbee2mqtt/bridge/devices (wiadomość zachowywana) zawiera listę sparowanych urządzeń,
  • zigbee2mqtt/bridge/state informuje, czy most działa,
  • zigbee2mqtt/bridge/request/backup zwraca archiwum ZIP katalogu danych zakodowane w Base64.

Od tego miejsca Node-RED, openHAB albo własny kod mogą subskrybować i publikować w tych tematach.

Kopie zapasowe i aktualizacje

Katalog z2m-data to cała sieć Zigbee: konfiguracja, klucz sieci i baza urządzeń. Regularnie rób jego kopię razem z mosquitto/config. Przy adapterach zStack i EmberZNet Zigbee2MQTT zapisuje też kopię koordynatora w pliku coordinator_backup.json, która przydaje się przy odtwarzaniu lub przenoszeniu sieci.

Aktualizacja:

docker compose pull
docker compose up -d

Przed przejściem na nową wersję główną przeczytaj informacje o wydaniu i zrób kopię zapasową.