Willkommen zurück bei Smart Security!
In diesem Blogeintrag behandeln wir das Thema ZigBee sowie dessen Integration in unsere Device-seitige (Device = Raspberry Pi) Architektur.
ZigBee ist ein Funkstandard, der insbesondere in den Bereichen Smart Home und Sensornetzwerken eingesetzt wird. ZigBee ist auf einen niedrigen Energieverbrauch und niedriges Datenaufkommen ausgelegt. Im Gegensatz zu Funkstandards wie WLAN bilden ZigBee-Geräte stets ein Mesh-Netzwerk. Dies bedeutet, dass die Knoten auch untereinander verbunden sind, fällt also Kommunikationspfad weg, kann ein anderer Pfad verwendet werden. Somit agiert jedes Gerät auch als „ZigBee-Repeater“.
In unserem Anwendungsgebiet der Einbruchsicherheit gibt es beispielsweise Fenster- und Türsensoren, die über ZigBee kommunizieren. Somit können Kabelgebundene Verbindungen eingespart werden.

Hardware
Da der Raspberry Pi von Haus aus kein ZigBee mit an Bord hat, benötigen wir ein zusätzliches Modul, um den Funkstandard zu unterstützen. Die Wahl fällt hierbei auf den Texas Instruments CC2531 USB-Dongle. Link: CC2531EMK Daughter card | TI.com
Als Firmware des Sticks kommt die folgende zum Einsatz: Z-Stack-firmware/CC2531_DEFAULT_20201127.zip at master · Koenkk/Z-Stack-firmware (github.com).

Software
Auf der Suche nach geeigneter Software, um die neu geschaffene ZigBee-Hardwareschnittstelle anzusprechen, stießen wir auf die drei folgenden Projekte:
- Home Assistant
- ZigBee2MQTT
- openHAB

Bei Home Assistant und OpenHAB handelt es sich um Smart Home Plattformen, die einen sehr großen Funktionsumfang im Smart Home Bereich bieten. Darunter befinden sich auch entsprechende ZigBee-Implementierungen. Alle drei der Alternativen werden bereits als Docker-Container angeboten, was sie sehr leicht in unsere Architektur einbauen ließe. Da unsere Architektur allerdings möglichst leichtgewichtig bleiben sollte, fiel bei uns die Wahl auf ZigBee2MQTT.
Auch wenn OpenHAB und Home Assistant ausgeschieden sind, wird in Kürze ein weiterer Blogeintrag zu diesen Smart Home Plattformen folgen, sie sind bestimmt für einige unter uns für das eigene Zuhause interessant.
ZigBee2MQTT
ZigBee2MQTT ist eine Bridge, in dem Fall für uns ein Protokoll-Übersetzer, der uns erlaubt, ZigBee-Geräte über MQTT zu steuern. Da wir in unserer Architektur bereits MQTT einsetzen, eignet sich dieses Protokoll hervorragend für unseren Verwendungszweck, ZigBee-Sensoren einzubinden.
Um ZigBee2MQTT in unsere Architektur einzubauen, schaffen wir einen neuen Service, in dem wir einen neuen Ordner auf der device-Seite anlegen, der ein Dockerfile, sowie eine Konfigurationsdatei enthält. Des Weiteren definieren wir den Service in der docker-compose.yml. Der Aufbau kann hier nachvollzogen werden: Phape/dhbwka-wwi-iotws-architektur (github.com)
Das Dockerfile enthält lediglich die folgenden beiden Anweisungen, um das Parent-Image auszuwählen und die Konfigurationsdateien in den Container zu kopieren:
FROM koenkk/zigbee2mqtt
COPY config /app
Wir beschränken uns auf eine Konfigurationsdatei, die folgendermaßen aussieht:
# Home Assistant integration (MQTT discovery)
homeassistant: false
# allow new devices to join
permit_join: true
# MQTT settings
mqtt:
# MQTT base topic for zigbee2mqtt MQTT messages
base_topic: iot-projekt/zigbee
# MQTT server URL
server: 'mqtt://broker.hivemq.com:1883'
# MQTT server authentication, uncomment if required:
# user: my_user
# password: my_password
# Serial settings
serial:
# Location of CC2531 USB sniffer
port: /dev/ttyACM0
Wichtig sind für uns insbesondere diese Konfigurationen:
- Permit_join: festlegen, ob neue ZigBee-Geräte hinzugefügt werden dürfen
- Mqtt base_topic: das MQTT-Standardtopic, in das gepublished wird
- Mqtt server: festlegen des MQTT-Servers. Hier können wir später unseren eigenen Server angeben
- Serial port: hier geben wir mit „/dev/ttyACM0“ an, dass der ZigBee-Stick in einem USB-Port des Raspi steckt
Der Service sieht in der docker-compose.yml folgendermaßen aus:
# Service zum übersetzen von Zigbee zu MQTT
zigbee2mqtt:
build: zigbee2mqtt/
volumes:
- zigbee2mqtt-data:/app/data
devices:
- /dev/ttyACM0:/dev/ttyACM0
restart: always
network_mode: host
privileged: true
environment:
- TZ=Europe/Amsterdam
Das Docker-Volume muss vorher ganz oben in der Datei definiert werden:
volumes:
redis-data:
grafana-data:
zigbee2mqtt-data:
Auch hier ist darauf zu achten, dass dem Container Zugriff auf die USB-Ports gewährt ist, dies ist durch die „devices“ Konfiguration realisiert.
Steuern der Geräte
Um MQTT leicht überwachen und nutzen zu können, wird die App „MQTT Explorer“ verwendet.
Hier muss man ebenfalls den Broker konfigurieren und die Topics subscriben.

Topics können unter „Advanced“ verwaltet werden, wir haben eingestellt: iot-projekt/#
Mit der # wird festgelegt, dass alle subtopics ebenfalls abonniert werden.

Nun kann man MQTT-Befehle an das Zigbee-Gerät senden
- Topic: iot-projekt/zigbee/<device-friendly-name>/set
- Value: json-format, man kann beispielsweise bei einer Lampe die Helligkeit, Farbe und den Zustand (an/aus) einstellen
- Übersicht über die MQTT-JSON-Struktur: MQTT topics and message structure | zigbee2mqtt.io
Viel Spaß beim Nachmachen!
Sehr interessanter Ansatz. Einziger Nachteil ist, dass die MQTT-Verbindungsdaten im Docker-Image „hart-codiert“ sind. Das wird vermutlich aber nicht so leicht änderbar sein, wenn es nicht gerade eine Option in Zigbee2MQTT gibt, diese z.B. aus Umgebungsvariablen zu lesen (die dann in der Balena Cloud hinterlegt werden könnten).