Turris Omnia: Zigbee2mqtt im LXC-Container
Nachdem ich deCONZ im LXC-Container auf dem Turris zum Laufen bekommen habe, musste ich feststellen, dass einige Geräte der tint Serie von Müller Licht von deCONZ noch nicht unterstützt werden. Da mir grundsätzlich das Konzept gefällt, dass ich das Zigbee-Netzwerk getrennt von Home Assistant verwalte, kommt Zigbee2mqtt als alternative Lösung in Betracht. Außerdem werden bei Zigbe2mqtt neue Zigbee-Geräte schneller unterstützt. Zumindest ist die Seite mit den unterstützten Zigbee-Geräten ziemlich umfangreich.
Hardware auswählen
Leider lässt sich Zigbee2mqtt nicht mit einem ConBee-Adapter von Dresden Elektronik nutzen. Es werden aber einige Adapter von Texas Instruments von Zigbee2mqtt unterstützt (siehe Zigbee2mqtt - Supported Adapters). Die kostengünstigste Variante ist dabei wohl der CC2531. Allerdings ist der Funktionsumfang dieses Sticks auch etwas eingeschränkt. Es können nur ca. 30 Zigbee-Geräte angebunden werden und die Reichweite ist wohl ebenfalls beschränkt. Außerdem eignet sich der Stick für Zigbee 3.0 nur bedingt.
Der deutlich teurere CC1352P-2 ist zwar deutlich teurer unterstützt aber angeblich 100+ Zigbee-Devices bei deutlich besserer Reichweite und Zigbee 3.0 Unterstützung. Daher habe ich mich für diesen Adapter als Zigbee-Controller entschieden.
Firmware auswählen und flashen
Die Firmware für die Zigbee-Controller kann auf GitHub heruntergeladen werden (siehe Z-Stack-firmware auf GitHub). Es ist lediglich die passende Coordinator-Firmware auszuwählen. Für den CC1352P-2 ist die Firmware Z-Stack_3.x.0 auszuwählen.
Einen Überblick welche Firmware mit welchem Adapter verwendet werden kann findet sich im README.md des Repositories.
Wie die Firmware zu flashen ist, wird auf der Zigbee2mqtt-Seite erklärt (siehe Flashing the firmware on the CC2531 USB stick und Flashing via UNIFLASH) und hat bei mir ohne Probleme funktioniert. Ich habe die Prozedur aber auch im Artikel Zigbee2mqtt inkl. Coordinator-Firmware aktualisieren beschrieben.
Turris Omnia vorbereiten
Bevor Zigbee2mqtt in einem LXC-Container installiert werden kann, muss zunächst das TurrisOS angepasst werden.
Hotplug einrichten
Ich habe in dem Artikel Turris Omnia: USB-Devices per Hotplug-Daemon einrichten bereits beschrieben, wie per Hotplug-Script die Berechtigungen des USB-Devices angepasst und ein eindeutiger Link auf das entsprechende Device angelegt werden kann. Für den hier verwendeten CC1352P-2-Controller nutze ich folgendes Hotplug-Script:
cat <<\EOF > /etc/hotplug.d/usb/20-zigbee2mqtt
PRODID="451/bef3/100"
SYMLINK="zigbee2mqtt"
if [ "${PRODUCT}" = "${PRODID}" ]; then
if [ "${ACTION}" = "add" ]; then
DEVICE_NAME=$(find /sys/${DEVPATH}/tty/ -name ttyACM* | grep -Eo "ttyACM.*$")
if [ -z ${DEVICE_NAME} ]; then
logger -t hotplug "20-zigbee2mqtt: Device ${DEVICENAME} not relevant - skipping "
exit
fi
logger -t hotplug "20-zigbee2mqtt: determined ${DEVICE_NAME} as device name for ${DEVICENAME}"
/bin/chown root:plugdev /dev/${DEVICE_NAME}
/bin/chmod 664 /dev/${DEVICE_NAME}
logger -t hotplug "20-zigbee2mqtt: Changed access rights for /dev/${DEVICE_NAME}"
[ "${DEVICENAME: -1}" = 0 ] && SYMLINK="${SYMLINK}0"
[ "${DEVICENAME: -1}" = 3 ] && SYMLINK="${SYMLINK}1"
ln -s /dev/${DEVICE_NAME} /dev/${SYMLINK}
logger -t hotplug "20-zigbee2mqtt: Symlink /dev/${SYMLINK} -> /dev/${DEVICE_NAME} created"
fi
if [ "${ACTION}" = "remove" ]; then
rm /dev/${SYMLINK}[01]
logger -t hotplug "20-zigbee2mqtt: Symlink /dev/${SYMLINK}[01] removed"
fi
fi
EOF
Und damit der das Device bei einem Reboot ebenfalls korrekt initialisiert wird, müssen folgende Kommandos beim Systemstart des Turris ausgeführt werden (z.B. per rc.local
):
#!/bin/bash
ID_CC1352P_2="451/bef3/100"
# Devices werden beim Booten quasi eingesteckt...
ACTION="add"
# Init cdc_acm devices
for i in $(dmesg | grep -Eo "cdc_acm.*ttyACM.*$" | cut -d " " -f 2); do
DEVICENAME=${i%:}
DEVPATH="bus/usb/devices/${DEVICENAME}"
PRODUCT=$(grep PRODUCT /sys/bus/usb/devices/${DEVICENAME}/uevent | cut -d "=" -f 2)
case "${PRODUCT}" in
${ID_CC1352P_2})
. /etc/hotplug.d/usb/20-zigbee2mqtt
;;
esac
done
Device im LXC-Container bereitstellen
Jetzt muss das USB-Device mit ein paar kleinen Ergänzungen an der LXC-Konfiguration an den Container durchgereicht werden:
#
# USB-Devices für LXC-Container bereitstellen
#############################################
# /dev/bus/usb für lsusb im LXC-Container bereitstellen
# beseitigt Fehlermeldung "unable to initialize libusb: -99"
lxc.mount.entry = /dev/bus/usb dev/bus/usb none bind,optional,create=dir 0 0
# Zugriff auf CC1352P-2 (zigbee2mqtt) erlauben
lxc.cgroup.devices.allow = c 166:* rwm
lxc.mount.entry = /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file 0 0
lxc.mount.entry = /dev/ttyACM1 dev/ttyACM1 none bind,optional,create=file 0 0
lxc.mount.entry = /dev/zigbee2mqtt0 dev/zigbee2mqtt0 none bind,optional,create=file 0 0
lxc.mount.entry = /dev/zigbee2mqtt1 dev/zigbee2mqtt1 none bind,optional,create=file 0 0
Änderungen im LXC-Container
Nachdem der Turris Omnia soweit vorbereitet ist, geht es in dem entsprechenden LXC-Container weiter. Ich gehe davon aus, dass hier bereits ein Container mit Debian 10 (Buster) grundsätzlich eingerichtet ist - inkl. automatischem Start bei Reboot des Turris Omnia.
Es gibt mehrere Möglichkeiten wie Zigbee2mqtt installiert werden kann. Da die Software bei mit im gleichen LXC-Container wie Home Assistant läuft habe ich mich für die Installation im Python Virtual Environment entschieden.
Service Benutzer anlegen
Damit der Zigbee2mqtt-Dienst ohne administrative Berechtigungen ausgeführt werden kann, wird zunächst ein neuer Benutzer angelegt. Dabei sollte das Homeverzeichnis nicht direkt mit angelegt werden, da dies in einem späteren Schritt erfolgt:
adduser --system --home /srv/zigbee2mqtt --no-create-home --group --shell /bin/bash --disabled-login zigbee
adduser zigbee plugdev
Zigbee2mqtt Repository Clonen
Anschließend wird zigbee2mqtt per git in das Homeverzeichnis des neuen Benutzers gecloned und die Berechtigungen entsprechend angepasst:
git clone https://github.com/Koenkk/zigbee2mqtt.git /srv/zigbee2mqtt
chown -R zigbee:zigbee /srv/zigbee2mqtt
Zigbee2mqtt im Python Virtual Environment installieren
Jetzt wird zunächst in den Benutzerkontext von zigbee
gewechselt und eine virtuelle Python-Umgebung angelegt und aktiviert. (Zeilen 1 - 7). Danach werden ein paar Module per pip
aktualisiert (Zeile 10) und npm
installiert und eingerichtet (Zeilen 13ff):
# Python venv einrichten
sudo -u zigbee -i
cd /srv/zigbee2mqtt
python3 -m venv .
# Python venv aktivieren
source bin/activate
# pip, wheel und setuptools aktualisieren
pip install --upgrade pip wheel setuptools
# node Umgebung installieren...
pip install nodeenv
# ... und einrichten
nodeenv -p -n 10.15.1
# Um sicherzugehen, einmal die Python venv verlassen und wieder aktivieren
deactivate
source bin/activate
# Abhängigkeiten installieren
npm ci
# Python venv deaktivieren
deactivate
MQTT-Benutzer anlegen
Bevor die Konfiguration von Zigbee2mqtt angepasst werden kann, muss ggf. noch ein Benutzer im MQTT-Server angelegt werden. Für einen Mosquitto-Server werden dazu als root folgende Befehle ausgeführt:
$ mosquitto_passwd /etc/mosquitto/passwd zigbee2mqtt
Password:
Reenter password:
$ systemctl restart mosquitto
Da ich in meienr MQTT-Installation die Nutzer zusätzlich beschränke (nicht jeder Benutzer darf beliebige Topics-Posten), müssen dem Benutzer auch noch einige Zugriffsrechte eingeräumt werden:
# allow user zigbee2mqtt to read/write to necessary topics
user zigbee2mqtt
# Allow publishing and reading Device Status
topic readwrite zigbee2mqtt/#
# allow reading home Assitant Birth and Will messages
topic read hass/#
# allow publishing new device to Home Assistant (MQTT Discovery)
topic readwrite homeassistant/#
Damit die Änderungen übernommen werden, muss der MQTT-Dienst mit systemctl restart mosquitto
neu gestartet werden.
Zigbee2mqtt Grundkonfiguration
Jetzt kann die Zigbee2mqtt Konfiguration unter /srv/zigbee2mqtt/data/configuration.yaml
in den Abschnitten mqtt:
und serial:
entsprechend anpassen.
# MQTT settings
mqtt:
# MQTT Base Topic for zigbee2mqtt MQTT messages
base_topic: zigbee2mqtt
# MQTT Server URL
server: 'mqtt://localhost'
# Benutzerdaten für den MQTT server eintragen, sofern erforderlich:
user: my_user
password: my_password
# Serial settings
serial:
# Hier das oben erstellte USB-Device eintragen:
port: /dev/zigbee2mqtt0
Zigbee2mqtt starten
Für einen ersten Test, ob alles geklappt hat, kann der Server manuell gestartet werden:
# In den richtigen Benutzerkontext wechseln
sudo -u zigbee -i
# Python3 Environment aktivieren
source bin/activate
# Dienst starten
npm start
# Der Dienst kann mit Strg+c beendet werden
# Python Environment
deactivate
Wenn dabei kein Fehler auftritt, muss ein Startscript für systemd erstellt werden, damit der Dienst nach einem Reboot auch automtisch gestartet wird. Dazu reicht es die Datei /etc/systemd/system/zigbee2mqtt.service
anzulegen:
sudo cat <<\EOF > /etc/systemd/system/zigbee2mqtt.service
[Unit]
Description=zigbee2mqtt
After=network.target
Wants=mosquitto.service
[Service]
User=zigbee
PermissionsStartOnly=true
ExecStartPre=/bin/chown root:plugdev /dev/zigbee2mqtt0
ExecStartPre=/bin/chmod 664 /dev/zigbee2mqtt0
ExecStart=/bin/bash -c 'source /srv/zigbee2mqtt/bin/activate; /srv/zigbee2mqtt/bin/npm start'
WorkingDirectory=/srv/zigbee2mqtt
StandardOutput=inherit
StandardError=inherit
Restart=always
[Install]
WantedBy=multi-user.target
EOF
Wenn das Startup-Script per systemctl daemon-reload
eingelesen wurde, sollte sich der Dienst jetzt per systemctl start zigbee2mqtt
starten lassen. systemctl status zigbee2mqtt
zeigt, ob der Dients erfolgreicih gestartet wurde. Ist das der Fall, kann mit systemctl enable zigbee2mqtt.service
der automatische Start des Dienstes aktiviert werden.
Hinweis: Wie die Installation später aktualisiert werden kann wird in dem Artikel Zigbee2mqtt inkl. Coordinator-Firmware aktualisieren beschrieben.
Damit sollte Zigbee2mqtt in der Grundkonfiguration funktionieren. Bevor aber die ersten Zigbee-Geräte angebunden werden, sollte dass Zigbee-Netzwerk noch abgesichert werden. Außerdem muss im Home Assistant auch noch sichergestellt werden, dass die neu gekoppelten Devices im Home Assistant auch automatisch erkannt werden. Das wird dann im nächsten Artikel beschrieben (siehe Zigbee2mqtt absichern und in Home Assistant einbinden).
Quellen
[1] Zigbee2mqtt
[2] Zigbee2mqtt - Supported Devices
[3] Zigbee2mqtt - Supported AdaptersZigbee2mqtt - Supported Adapters
[4] GitHub - Z-Stack-Firmware
[5] Zigbee2mqtt - CC2531 flashen
[6] Zigbee2mqtt - Flashing via Uniflash
[7] Running Zigbee2mqtt
[8] Running Zigbee2mqtt in Virtual Environment
Kommentare