Ostatnio sporo czasu poświęciliśmy protokołowi MQTT, który jest bardzo popularny w świecie automatyki domowej. Dzisiaj przyszła pora przyjrzeć się ZigBee, które jest z nim ściśle kojarzone, za sprawą świetnego projektu Zigbee2MQTT. Zastanowimy się czy to dobre połączenie i czy w ogóle ZigBee jest potrzebne, skoro mamy już WiFi.
ZigBee – co to takiego?
ZigBee to rodzina protokołów, bazujących na standardzie IEEE 802.15.4, wykorzystywana do budowy małych sieci bezprzewodowych o topologii siatki (mesh). Komunikacja opiera się o częstotliwość 2,4GHz, więc tą samą, którą wykorzystuje WiFi. ZigBee jest standardem tworzonym od kilkunastu lat przez Zigbee Alliance, wspierane przez bardzo wiele poważnych firm z branży IT.
Ujmując rzecz prościej – ZigBee to sposób komunikacji urządzeń bezprzewodowych, świetnie pasujący do zastosowań automatyki budynkowej. Oferuje wyraźnie mniejsze prędkości przesyłu danych niż WiFi, ale za to wymaga znacznie mniej mocy, przez co urządzenia mogą pracować znacznie dłużej na bateriach. Dodatkowo elementy sieci, które posiadają stałe zasilanie, są zazwyczaj także routerami, czyli stają się przekaźnikami danych. Pozwala to w prosty sposób rozszerzać zasięg sieci (to jest właśnie mesh). Cechą charakterystyczną ZigBee jest też to, że siecią zarządza jeden i tylko jeden koordynator.
W praktyce sprowadza się to posiadania jednej bramki ZigBee, która komunikuje się radiowo z siecią czujników i elementów wykonawczych z jednej strony i światem zewnętrznym z drugiej. I tu pojawiają się dwa problemy. Po pierwsze bramka jednego producenta, z pewnymi wyjątkami, współpracuje tylko z elementami tego samego ekosystemu (często jednego producenta). Drugą niedogodnością jest to, że zwykle komunikuje się z jakąś, zależną od producenta, usługą chmurową. I tu także są pewne wyjątki, lecz co do zasady właśnie tak wygląda architektura większości ekosystemów opartych o ZigBee.
Oczywiście nie dla wszystkich są to wady. W szczególności gdy ktoś nie chce zbyt wiele czasu poświęcić na budowę inteligentnych rozwiązań, to ma bardzo prostą drogę do wykonania wielu podstawowych lub nawet bardziej złożonych automatyzacji. Ja mam natomiast trochę inne podejście. Uważam, że automatykę buduje się na lata i uzależnianie się od usługi chmurowej jednego producenta nie jest zbyt bezpieczne. Po pierwsze jesteśmy zależni od dostępu do Internetu, po drugie włamanie na serwery dostawcy może mieć dla nas przykre skutki, a po trzecie nie mamy gwarancji, że usługa utrzyma się przez lata.
Zigbee2MQTT
I tu z pomocą przychodzi project zigbee2mqtt. Dzięki temu, że ZigBee jest dobrze udokumentowanym standardem, możliwa jest komunikacja z urządzeniami różnych producentów. Zigbee2MQTT pozwala podłączyć wiele urządzeń z jednym, tanim adapterem, pełniącym funkcję koordynatora. Ponieważ nie korzystamy z bramek producentów, nie jesteśmy skazani na ich usługi chmurowe. Zamiast tego otrzymujemy całą komunikację radiową „opakowaną” w protokół MQTT.
Możemy więc, wysyłając wiadomości na odpowiedni kanał, zażądać danych lub wykonania czynności przez jakieś urządzenie (np. sterownik światła czy rolet). Z drugiej strony, różne urządzenia publikują na swoich kanałach informację o zmianach stanów lub dokonanych pomiarach (np. włączniki świateł czy termometry). Ponieważ opieramy się na znanym i lubianym protokole MQTT, możemy w prosty sposób sterować automatyką w naszych programach lub wykorzystać gotowe narzędzia, takie jak np. NodeRed czy Home Assistant.
Adapter ZigBee
Żeby jednak użyć Zigbee2MQTT, co oczywiste, potrzebny jest sprzęt, który potrafi „rozmawiać” z urządzeniami na częstotliwości 2,4GHz. Oczywiście nie może to być karta WiFi, bo mimo zbieżności częstotliwości, nie potrafi ona obsłużyć standardu IEEE 802.15.4. Na szczęście przy obecnym bogactwie podzespołów elektronicznych, znalezienie czegoś właściwego, a jednocześnie współpracującego z Zigbee2MQTT, nie jest dużym problemem. Pełną listę wspieranych adapterów można znaleźć na stronie projektu.
Wiele osób swoją przygodę z tym standardem zaczyna od ekonomicznego adaptera CC2531. Nie jest to sprzęt bardzo polecany ze względu na wydajność czy stabilność, natomiast cena jest bezkonkurencyjna. Nie bez znaczenia jest też fakt, że posiada on interfejs USB, więc łatwo można go podłączyć do komputera czy też Raspberry Pi.
Niestety nie można powiedzieć, że CC2531 jest bez wad. Wiele osób krytykuje ten adapter za małą wydajność, co zresztą potwierdzane jest na stronie projektu Zigbee2MQTT. Nie jest on więc polecany dla sieci z dużą liczbą urządzeń bezpośrednio podłączonych do koordynatora. Wersja z wbudowaną anteną ma też dość ograniczony zasięg. Dlatego wybierając CC2531 warto od razu rozważyć wersję z zewnętrzną anteną. Wtedy dwa piętra w domu nie są problemem, przynajmniej u mnie.
Czy kupić więc CC2531, czy zdecydować się od razu na innego koordynatora sieci? Gdy planujemy dużą sieć, warto pewnie rozważyć coś lepszego, chociaż potencjalnie kilkukrotnie droższego. Jeżeli natomiast chcemy poeksperymentować z tym standardem lub ZigBee ma być wyłącznie dodatkiem do innej architektury, to można zacząć od tego najtańszego adaptera.
Wgrywanie oprogramowania do CC2531
Tutaj dochodzimy do kolejnej, drobnej wady urządzenia – nie jest to produkt w pełni gotowy do współpracy z Zigbee2MQTT. Na szczęście strona projektu bardzo dokładnie opisuje proces „flashowania” układu do roli koordynatora (CC2531 może być też routerem). Co prawda polecany jest do tego CC debuger, który jest dodatkowym kosztem, powodującym, że wybór taniego adaptera zaczyna mijać się z celem, natomiast mamy też metody alternatywne. Możemy użyć choćby Raspberry Pi czy odpowiednio zaprogramowanego układu ESP8266, który przecież świetnie znamy.
Niestety, jeżeli nie kupiliśmy specjalnej przejściówki z przewodem do programowania, napotkamy na barierę niestandardowego rozstawu pinów w CC2531, dlatego warto od razu rozważyć jej zakup. Unikniemy w ten sposób niepotrzebnego lutowania czy innego prowizorycznego łączenia. W końcu to naprawdę niewielki koszt. Sam proces programowania układu jest prosty i nie powinien zająć więcej niż 15-20 minut, razem z czytaniem dokumentacji.
Pierwsze podłączenie do Raspberry Pi
Po podłączeniu zaprogramowanego urządzenia do Raspberry Pi, system powinien je rozpoznać. Możemy to potwierdzić wydając komendę dmesg. Na końcu logu powinniśmy znaleźć wpisy:
[34717758.851893] usb 1-1.3: new full-speed USB device number 7 using dwc_otg
[34717758.999619] usb 1-1.3: New USB device found, idVendor=0451, idProduct=16a8, bcdDevice= 0.09
[34717758.999635] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[34717758.999645] usb 1-1.3: Product: TI CC2531 USB CDC
[34717758.999654] usb 1-1.3: Manufacturer: Texas Instruments
[34717758.999664] usb 1-1.3: SerialNumber: __0X00124B0014D9A78E
Jest całkiem dobrze, widać nawet właściwą nazwę chipa, chociaż akurat w tym wypadku nie wszystko poszło zgodnie z planem. Mimo wykrycia adaptera, w systemie nie pojawiło się oczekiwane urządzenia /dev/ttyACM0. Jednak szybka aktualizacja systemu przez apt update i apt upgrade spowodowała, że nowe urządzenie znakowe stało się dostępne:
pi@firma:/dev $ ls -la ttyACM0
crw-rw---- 1 root dialout 166, 0 gru 17 11:45 ttyACM0
Jak widać, prawa do odczytu i zapisu poza rootem, posiada tylko grupa dialout. Warto w tym momencie sprawdzić, za pomocą polecenia id, czy użytkownik, na którym chcemy uruchomić Zigbee2MQTT należy do tej grupy.
Przy okazji, gdy nie mamy pewności, czy to jest nasze urządzenie, którego szukamy lub też nie chcemy polegać na przydzielonym mu numerze, możemy sprawdzić utworzony automatycznie link symboliczny:
pi@firma:/dev $ ls -l /dev/serial/by-id/
total 0
lrwxrwxrwx 1 root root 13 gru 17 11:45 usb-Texas_Instruments_TI_CC2531_USB_CDC___0X00124B0014D9A78E-if00 -> ../../ttyACM0
Nic nie stoi na przeszkodzie, żeby używać go zamiast /dev/ttyACM0.
Instalacja Zigbee2MQTT
Instalację najlepiej przeprowadzić, jak zaleca dokumentacja, przez sklonowanie repozytorium:
sudo git clone https://github.com/Koenkk/zigbee2mqtt.git /opt/zigbee2mqtt
Następnie warto zmienić właściciela plików, zależnie od tego, na jakim użytkowniku chcemy uruchomić usługę (pamiętając o przynależności do grupy dialout):
chown -R pi /opt/zigbee2mqtt
Kolejny krok to instalacja zależności, jak zaleca dokumentacja:
cd /opt/zigbee2mqtt
npm ci
Oczywiście zakładam, że nodejs i npm są już zainstalowane, jak przystało na Raspberry Pi w porządnym inteligentnym domu.
Konfiguracja
Podstawowa konfiguracja jest równie prosta co instalacja. Wystarczy zmienić zawartość pliku /opt/zigbee2mqtt/data/configuration.yaml. Podajemy tam port naszego adaptera, adres brokera MQTT oraz bazę dla tematów, w których będzie publikował wiadomości. Na przykład:
homeassistant: false
permit_join: true
mqtt:
base_topic: zigbee2mqtt
server: 'mqtt://localhost'
serial:
port: /dev/ttyACM0
Warto zwrócić uwagę na opcję permit_join, która pozwala dołączać nowe urządzenia zigbee do naszej sieci. Na dłuższą metę nie jest zalecane, żeby była ona włączona, ale oczywiście na początek jest konieczna.
Jeżeli tworzysz kopie zapasowe ważnych plików na swojej Malinie częściej niż całości systemu, to zdecydowanie warto zapisywać do archiwum zawartość katalogu /opt/zigbee2mqtt/data/. Jest to także katalog, który zabezpieczamy przed wykonaniem aktualizacji wersji. Przechowuje on konfigurację i stan systemu.
Pierwsze uruchomienie
Pierwsze uruchomienie może być bardzo proste i interaktywne. Wywołujemy po prostu NodeJS, podając plik index.js. Wkrótce powinniśmy zobaczyć informacje o aktywnościach startowych:
pi@firma /opt/zigbee2mqtt $ node index.js
Zigbee2MQTT:info 2020-11-10 17:05:14: Logging to console and directory: '/opt/zigbee2mqtt/data/log/2020-11-10.17-05-13' filename: log.txt
Zigbee2MQTT:info 2020-11-10 17:05:14: Starting Zigbee2MQTT version 1.16.1 (commit #6b32f30)
Zigbee2MQTT:info 2020-11-10 17:05:14: Starting zigbee-herdsman…
Zigbee2MQTT:info 2020-11-10 17:05:21: zigbee-herdsman started
Zigbee2MQTT:info 2020-11-10 17:05:21: Coordinator firmware version: '{"meta":{"maintrel":3,"majorrel":2,"minorrel":6,"product":0,"revision":20190608,"transportrev":2},"type":"zStack12"}'
Zigbee2MQTT:info 2020-11-10 17:05:21: Currently 0 devices are joined:
Zigbee2MQTT:warn 2020-11-10 17:05:21: permit_join
set to true
in configuration.yaml.
Zigbee2MQTT:warn 2020-11-10 17:05:21: Allowing new devices to join.
Zigbee2MQTT:warn 2020-11-10 17:05:21: Set permit_join
to false
once you joined all devices.
Zigbee2MQTT:info 2020-11-10 17:05:21: Zigbee: allowing new devices to join.
Zigbee2MQTT:info 2020-11-10 17:05:22: Connecting to MQTT server at mqtt://localhost
Zigbee2MQTT:info 2020-11-10 17:05:22: Connected to MQTT server
Zigbee2MQTT:info 2020-11-10 17:05:22: MQTT publish: topic 'zigbee2mqtt/bridge/state', payload 'online'
Zigbee2MQTT:info 2020-11-10 17:05:22: MQTT publish: topic 'zigbee2mqtt/bridge/config', payload '{"commit":"6b32f30","coordinator":{"meta":{"maintrel":3,"majorrel":2,"minorrel":6,"product":0,"revision":20190608,"transportrev":2},"type":"zStack12"},"log_level":"info","network":{"channel":11,"extendedPanID":"0xdddddddddddddddd","panID":6754},"permit_join":true,"version":"1.16.1"}'
Jeżeli subskrybujemy gdzieś kanały zigbee2mqtt/# lub inne, zależnie od wybranej bazy, powinniśmy zobaczyć wpisy w zigbee2mqtt/bridge/config i zigbee2mqtt/bridge/state. Warto wiedzieć, że od teraz możemy konfigurować serwer zigbee2mqtt prze wydawanie poleceń na odpowiednim kanale mqtt.
Parowanie urządzeń ZigBee
Skoro mamy już działającą, nawet tymczasowo, usługę zigbee2mqtt, możemy spróbować dołączyć do naszego ekosystemu jakieś urządzenie lub czujnik. Jak to zrobić? Najłatwiej jest sprawdzić w dokumentacji, natomiast większość urządzeń albo ma specjalny przycisk, który należy przytrzymać nieco dłużej albo też wciskamy w ten sposób jeden z normalnych klawiszy. Jeżeli znaleźliśmy właściwą metodę, a nasze zigbee2mqtt pozwala na dołączanie, to na ekranie lub w logu powinniśmy zobaczyć informację o nowym urządzeniu:
Zigbee2MQTT:info 2020-12-17 12:26:06: Device '0xec1bbdfffea5391a' joined
Zigbee2MQTT:info 2020-12-17 12:26:06: Starting interview of '0xec1bbdfffea5391a'
Zigbee2MQTT:info 2020-12-17 12:26:06: MQTT publish: topic 'zigbee2/bridge/log', payload '{"message":{"friendly_name":"0xec1bbdfffea5391a"},"type":"device_connected"}'
Zigbee2MQTT:info 2020-12-17 12:26:06: MQTT publish: topic 'zigbee2/bridge/log', payload '{"message":"interview_started","meta":{"friendly_name":"0xec1bbdfffea5391a"},"type":"pairing"}'
Zigbee2MQTT:info 2020-12-17 12:26:06: MQTT publish: topic 'zigbee2/bridge/log', payload '{"message":"announce","meta":{"friendly_name":"0xec1bbdfffea5391a"},"type":"device_announced"}'
Zigbee2MQTT:info 2020-12-17 12:26:08: MQTT publish: topic 'zigbee2/0xec1bbdfffea5391a', payload '{"backlight_mode":"LOW","linkquality":34}'
Zigbee2MQTT:info 2020-12-17 12:26:08: MQTT publish: topic 'zigbee2/0xec1bbdfffea5391a', payload '{"backlight_mode":"LOW","calibration":"OFF","linkquality":26,"motor_reversal":"OFF","moving":"STOP","position":0}'
Zigbee2MQTT:info 2020-12-17 12:26:08: Successfully interviewed '0xec1bbdfffea5391a', device has successfully been paired
Zigbee2MQTT:info 2020-12-17 12:26:08: Device '0xec1bbdfffea5391a' is supported, identified as: TuYa Curtain/blind switch (TS130F)
Zigbee2MQTT:info 2020-12-17 12:26:08: MQTT publish: topic 'zigbee2/bridge/log', payload '{"message":"interview_successful","meta":{"description":"Curtain/blind switch","friendly_name":"0xec1bbdfffea5391a","model":"TS130F","supported":true,"vendor":"TuYa"},"type":"pairing"}'
Na powyższym przykładzie mamy sterownik do zasłon, mogący służyć równie dobrze do obsługi rolet lub bramy roletowej (jak w moim przypadku). Sprzedawany jest w Polsce pod nazwą EM1 TUYA, a znany jest szerzej jako TS130F. Jest kompatybilny z ekosystemem Tuya, ale oczywiście w pełni obsługiwany przez Zigbee2MQTT.
Sterowanie urządzeniami ZigBee przez MQTT
Gdy już urządzenie jest sparowane, warto nadać mu przyjazną nazwę. Oczywiście robimy to przy użyciu protokołu MQTT:
mqtt_pub -t "zigbee2/bridge/config/rename" '{"old": "0xec1bbdfffea5391a", "new": "brama"}'
Od tej pory jest to dla nas brama, a nie 0xec1bbdfffea5391a. Czytanie logów czy komunikacja będą więc dużo prostsze. Osoby dociekliwe pewnie zauważą, że odpowiedni wpis pojawił się w pliku configuration.yaml:
devices:
'0xec1bbdfffea5391a':
friendly_name: bramahala2
Oczywiście brama to nie zasłony, więc szybko okazało się, że sterownik należy skalibrować tak, żeby potrafił w pełni otworzyć i zamknąć przejście. Oczywiście w tryb kalibracji wprowadzamy go przez publikację odpowiedniej wiadomości na kanale MQTT:
mqtt_pub -t "zigbee2/brama/set/calibration" "on"
Pozostało postąpić zgodnie z instrukcją i w odpowiedniej sekwencji podnosić i opuszczać bramę z użyciem klawiszy. Następnie można już wyjść z trybu kalibracji i podnieść roletę:
mqtt_pub -t "zigbee2/bramahala2/set/calibration" "off"
mqtt_pub -t "zigbee2/bramahala2/set" "{\"position\": \"0\"}"
Bardzo szybko zauważymy w logu, że urządzenie przekazuje nam informacje o zmiana stanów, niezależnie od tego, czy sterujemy roletą przyciskami czy za pomocą MQTT. Na przykład, gdy roleta zatrzyma się na dole po opuszczeniu, powinniśmy zobaczyć w logu informację o opublikowaniu wiadomości na właściwym kanale:
MQTT publish: topic 'zigbee2/bramahala2', payload '{"backlight_mode":"LOW","calibration":"OFF","linkquality":34,"motor_reversal":"OFF","moving":"STOP","position":100}'
Bardzo proste, a jednocześnie dające bardzo bogate możliwości użycia w automatyzacji.
Uruchomienie na stałe
Zapewne bardzo rozsądną opcją do uruchamiania Zigbee2MQTT jest ustawienie skryptów startowych systemd, tak jak zaleca dokumentacja. Ja jednak mam już całkiem sporo skryptów obsługiwanych przez menadżera procesów pm2. Dlatego zmieniam nazwę pliku index.js na zigbee.js i uruchamiam usługę przez:
pm2 start zigbee.js
Menadżer dba o restarty procesów gdy jest to konieczne, monitoruje zużycie zasobów, zarządza logami, łącznie z ich okresową rotacją. Dlatego dla mnie jest to najwygodniejsze rozwiązanie.
Uruchamiając Zigbee2MQTT, pamiętajmy tylko, żeby wyłączyć automatyczne parowanie urządzeń.
Podsumowanie
Zdaję sobie sprawę, że wiele osób wykorzystuje Zigbee2MQTT jako dodatek do Home Assistanta lub innego nadzorcy inteligentnego domu, nie zastanawiając się nawet jak to działa. Mam jednak nadzieję, że ten wpis jest w stanie wyjaśnić kilka kwestii bardziej dociekliwym osobom. Może też zainteresuje kogoś, kto opiera automatyzacje o własne skrypty. Niezależnie od tego, jak realizujemy swoje cele, warto wiedzieć, jak to działa.
hej
Jak zwykle super wpis.
Może już coś kombinowałeś z upgrade urządzeń podłączonych bez bramki, a za pomocą adaptera CC2531. Niestety ja nie potrafię tego ogarnąć. Jedynie urządzenia + bramka danej firmy daje taką możliwość. Może jakaś wtyczka do domoticza albo HA pozwala na ściągnięcie i aktualizację urządzeń.
Dzięki. Tak, robiłem już aktualizację. Opiszę.
Super. Czekam na opis. Mam kilkanaście urządzeń z różnych firm i raczej nie planuję kupna do każdej marki bramki.