Turris Omnia: deCONZ im LXC-Container

Home Assistant gibt es mehrere Möglichkeiten Zigbee-Geräte einzubinden. Zum einen gibt es ZHA (Zigbee Home Automation) als native integration, bei der ein kompatibler Zigbeestick ohne weitere Software-Installation  eingebunden werden kann. Mit Zigbee2MQTT werden die Zigbee-Geräte über MQTT an Home Assistant angebungen. Als dritte Variante kann mit einem ConBee, ConBee II oder RaspBee-Modul auch die Software deCONZ bzw. Phoscon von Dresden Elektronik an Home Assistant angebunden werden. Alle Lösungen haben dabei ihre Vor- und Nachteile, wie ein vergleichsweise ausführlicher .  

Vor allem die Darstellung des Zigbee-Netzwerks und die immer wieder hervorgehobene Stabilität waren für mich die ausschlaggebenden Punkte in einem ersten Versuch auf deCONZ und Phoscon zu setzen.

Eingesetzten Software und Hardware

Die hier genannten Schritte wurde mit folgender Software und Hardware durchgeführt:

  • TurrisOS 4.x
  • Debian Buster (OS im LXC-Container) 
  • deCONZ 2.05.74-raspbian-buster-stable
  • ConBee-Stick

Wie der LXC-Container anzulegen ist, wird hier nicht erklärt. Ich gehe davon aus, dass der Container bereits grundlegend eingerichtet wurde.

Hinweis: Ich verwende die alte Version des ConBee-Sticks. Bei der neuen Version des Sticks (ConBee II) muss die Einbindung des Sticks ggf. angepasst werden. Dies gilt insbesondere für die zu installierenden Treiber und Device-IDs (siehe auch [2]).

Disclaimer: Wie immar kann ich keine Garantie geben. Für alles was ihr an euren Geräten vornehmt seid ihr selbst verantwortlich. Besonders das Aktualisieren der Stick-Firmware kann dazu führen, dass der Stick unbrauchbar wird.

Auf dem Turris Omnia

Zunächst müssen einige Punkte auf dem Turris Omnia als Host vorbereitet werden. Wenn der ConBee-Stick angeschlossen wird, kann mit lsusb kontrolliert werden, ob der Stick grundsätzlich erkannt wird: 

lsusb
  
Bus 002 Device 003: ID 0403:6015 Future Technology Devices International, Ltd Bridge(I2C/SPI/UART/FIFO)
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 005 Device 002: ID 174c:5136 ASMedia Technology Inc. ASM1053 SATA 3Gb/s bridge
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 002: ID 0409:005a NEC Corp. HighSpeed Hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 005 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

Kernelmodul installieren

Über die ID (im Beispiel oben Zeile  2, ID 0403:6015) kann ermittelt werden, welches Kernelmodul installiert werden muss. Für den ConBee ist dementsprechend das Paket kmod-usb-serial-ftdi im TurrisOS zu installieren. Die USB-Utilities sollten zusätzlich installiert werden:

opkg update
opkg install kmod-usb-serial-ftdi 
opkg install usbutils

Wurde der richtige Treiber installiert, sollte für den ConBee-Stick ein neues Device /dev/ttyUSB0 angelegt werden. Im Zweifelsfalle den Stick nochmal neu einstecken. 

Berechtigungen des Devices anpassen

Jetzt wird zwar immerhin schon das Device erkannt und korrekt angelegt, aber der Zugriff ist im Standard lediglich für den Benutzer root zugelassen. Daher muss die Datei /etc/plugdev.d/usb/20-conbee mit folgenden Inhalt angelegt werden:

CONBEE_PRODID="403/6015/1000"
SYMLINK="conbee"

if [ "${PRODUCT}" = "${CONBEE_PRODID}" ]; then
    if [ "${ACTION}" = "add" ]; then
        DEVICE_NAME=$(ls /sys/${DEVPATH} | grep tty)
        if [ -z ${DEVICE_NAME} ]; then
            logger -t hotplug "Warning DEVICE_NAME is empty"
            exit
        fi
        logger -t hotplug "Device name of ConBee is ${DEVICE_NAME}"

        /bin/chown root:plugdev /dev/${DEVICE_NAME}
        /bin/chmod 664 /dev/${DEVICE_NAME}
        logger -t hotplug "Changed access rights for /dev/${DEVICE_NAME}"

        /bin/mkdir -p /media/msata/srv/lxc/deconz/rootfs/run/udev/data
        /bin/bash -c "/bin/echo -e 'E:ID_VENDOR_ID=0403\nE:ID_MODEL_ID=6015' > /media/msata/srv/lxc/deconz/rootfs/run/udev/data/c188:0"
        logger -t hotplug "Created missing udev data for deCONZ running in deconz container"

        ln -s /dev/${DEVICE_NAME} /dev/${SYMLINK}
        logger -t hotplug "Symlink from /dev/${DEVICE_NAME} to /dev/${SYMLINK} created"
    fi
fi

if [ "${PRODUCT}" = "${CONBEE_PRODID}" ]; then
    if [ "${ACTION}" = "remove" ]; then
        rm /dev/${SYMLINK}
        logger -t hotplug "Symlink /dev/${SYMLINK} removed"

        rm -r /media/msata/srv/lxc/deconz/rootfs/run/udev/data
        logger -t hotplug "Deleted artificial udev data for deCONZ"

    fi
fi

Wird ein USB-Gerät mit der Produkt-ID des ConBee-Sticks (siehe Zeile 1) angeschlossen, so werden die Berechtigungen angepasst und zusätzlich ein symbolischer Link /dev/conbee auf das entsprechende Device angelegt. Das macht es einfach nachzuvollziehen welches Device zu dem Stick gehört. Darüber hinaus wird in dem Dateisystems des LXC-Containers eine Datei im Verzeichnis udev angelegt, die deCONZ benötigt, um das Device korrekt zu erkennen. Beim Entfernen des Sticks werden der Symlink und die udev-Datei wieder gelöscht.

Device Initialisierung bei Reboot

Damit das USB-Device nicht nur beim Anstecken des Devices sondern auch beim Systemstart korrekt initialisiert wird, muss folgendes Script beim Booten (z.B. in der Datei rc.local) ausgeführt werden:

#!/bin/bash

ID_CONBEE="403/6015/1000"

# Devices werden beim Booten quasi eingesteckt...
ACTION="add"

# init ftdi_sio devices
for i in $(dmesg | grep -Eo "ftdi_sio.*FTDI USB Serial Device.*$" | 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 "$(grep PRODUCT /sys/bus/usb/devices/${DEVICENAME}/uevent | cut -d "=" -f 2)" in
                ${ID_CONBEE})
                        . /etc/hotplug.d/usb/20-conbee
                        ;;
        esac
done

Device-Passthrough für LXC-Container

Wird der ConBee korrekt erkannt und angelegt, muss das Device durch folgende Zeilen in der Konfigurationsdatei des LXC-Containers verfügbar gemacht werden:

# Zugriff auf ConBee-Stick erlauben
lxc.cgroup.devices.allow = c 188:*
lxc.mount.entry = /dev/ttyUSB0 dev/ttyUSB0 none bind,optional,create=file 0 0

Erweiterte Rechte für LXC-Container

Achtung: Durch diese Änderung werden dem Container weitreichende Berechtigungen zugeordnet, was den sicheren Betrieb des Containers beeinträchtigen kann.

Damit bei mit die Phoscon bzw. deCONZ später im Container fehlerfrei startet, mussten bei mir noch einige Beschränkungen für den LXC-Containers aufgehoben werden. Dazu müssen folgende Einträge an das Ende der Konfigurationsatei eingetragen werden:

# für deCONZ müssen Beschränkungen für den Container weitgehend aufgehoben werden
lxc.apparmor.profile = unconfined
lxc.cgroup.devices.allow = a
lxc.cap.drop =

Danach kann man den LXC-Container (neu) starten und sich mit ihm verbinden:

lxc-stop <container-name>
lxc-start <container-name>
lxc-attach <container-name>

Im LXC-Container

In dem LXC-Container muss die Phoscon/deCONZ-Software installiert werden. Dabei ist zu berücksichtigen, dass das von Dresden Elektronik bereitgestellte Paket für den RaspberryPi entwickelt wurde. Unglücklicherweise existiert dabei eine Abhängigkeit zum RaspberryPi spezifischen Paket wiringpi, dass im Debian Buster des LXC-Containers nicht automatisch mit installiert werden kann. 

Abhängigkeiten installieren (wiringpi)

Das wiringpi-Paket kann aber manuell heruntergeladen und installiert werden:

wget https://project-downloads.drogon.net/wiringpi-latest.deb
apt install ./wiringpi-latest.deb

Repository hinzufügen und installieren

Die Installation des deconz-Paket ist dann nur noch Debian-Standard:

# Schlüssel für Repository installieren
wget -O - http://phoscon.de/apt/deconz.pub.key | sudo apt-key add -

# deCONZ-Repository hinzufügen  
echo "deb http://phoscon.de/apt/deconz $(lsb_release -cs) main" > /etc/apt/sources.list.d/deconz.list
# deCONZ installieren
apt update
apt install deconz

Zugriff auf ConBee für deCONZ ermöglichen

Intern verwendet deCONZ Funtkionen der Bibliothek libqt5serial, um das richtige Device in der udev-Datenbank unter /run/udev/data/ zu ermitteln. Diese ist im LXC-Container aber nicht verfügbar. Daher muss der Eintrag manuell angelegt werden:

# Verzeichnis erstellen
mkdir -p /run/udev/data/
  
# Datei mit den Device-Infos anlegen.
echo "E:ID_VENDOR_ID=0403
E:ID_MODEL_ID=6015" > /run/udev/data/c188\:0

Hinweis: Die VENDOR_ID und MODEL_ID wird mit dem Kommando lsusb ermittelt. der Dateiname (188:0) richtet sich nach den Attributen des Devices, die mit ls -la /dev/ttyUSB0 ermittelt werden können.

 Für einen Benutzer mit root-Rechten sollte der Stick nun verfügbar sein:

$ GCFFlasher_internal -l

GCFFlasher V3_13 (c) dresden elektronik ingenieurtechnik gmbh
Path             | Vendor | Product | Serial     | Type
-----------------+--------+---------+------------+-------
/dev/ttyUSB0     | 0x0403 | 0x6015  |            | ConBee

Benutzer anlegen und Autostart anpassen

Im Default wir der deCONZ-Dienst mit der User-ID 1000 gestartet. Es empfiehlt sich aber einen dedizierten Benutzer für deCONZ anzulegen:

# Benutzer anlegen
useradd deconz

# Homeverzeichnis anlegen
mkdir /home/deconz
chown -R deconz:deconz /home/deconz

# Zur Gruppe dialout hinzufügen, um Berechtigungen
# für den Zugriff auf das ConBee-Device 
usermod -a -G plugdev deconz

Danach muss in der Datei deconz.services durch folgende Anpassungen sichergestellt werden, dass der neue Benutzer verwendet wird und beim Systemstart der Zugriff auf den Stick ermöglicht wird:

$ cp /lib/systemd/system/deconz.service /etc/systemd/system/
$ systemctl daemon-reload
$ systemctl edit --full deconz [Unit] Description=deCONZ: ZigBee gateway -- REST API Wants=deconz-init.service deconz-update.service [Service] User=deconz PermissionsStartOnly=true ExecStartPre=/bin/chown root:plugdev /dev/ttyUSB0 ExecStartPre=/bin/chmod 664 /dev/ttyUSB0 ExecStartPre=/bin/mkdir -p /run/udev/data ExecStartPre=/bin/bash -c "/bin/echo -e 'E:ID_VENDOR_ID=403\nE:ID_MODEL_ID=6015' > /run/udev/data/c188:0" ExecStart=/usr/bin/deCONZ -platform minimal --http-port=80 Restart=on-failure StartLimitInterval=60 AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_KILL CAP_SYS_BOOT CAP_SYS_TIME [Install] WantedBy=multi-user.target

Hinweis: Die Zeilen 10 - 13 sind etwas redundant, da die Berechtigungen auf das Device bereits durch das Hotplug-Script auf dem Host bereits korrekt gesetzt sein sollten. Ich passe die Berechtigungen auf das Device aber trotzdem auch nochmal im Startscript an, um sicherzugehen, dass beim Start von deCONZ auch alles korrekt gesetzt ist.

Nach einem Neustart des LXC-Containers sollten der deCONZ-Dienst automatisch gestartet werden, was mit netstat -tulpen leicht zu überprüfen ist: 

$ netstat -tulpen | grep deCONZ

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      998        19752605   125/deCONZ
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      998        19752684   125/deCONZ
udp        0      0 0.0.0.0:1900            0.0.0.0:*                           998        19752811   125/deCONZ

Ist die Phoscon-Seite über HTTP erreichbar ist, sollte unter Menü > Einstellungen > Gateway auch der Stick erscheinen:

ConBee Adapter in Phoscon-Oberfläche

Firmware aktualisieren

Ein Firmware-Update über die gerade erst aufgesetzte Phoscon-Seite funktioniert leider nicht. Dies liegt daran, dass der GCFFlasher verucht die Kernelmodule neu zu laden. Das klappt natürlich nicht in einem LXC-Container, so dass der Flash-Vorgang nicht durchgeführt wird. Auch wenn die Web-Oberfläche suggeriert, dass die Aktualisierung erfolgreich war, wird man feststellen, dass die Firmware-Version des Sticks sich nicht geändert hat.

Daher muss ein Firmwareupdate manuell durchgeführt werden. Ich benutze dazu einfach meinen Windows 10 Laptop und nutze die Windows-Version des GCFFLasher, der auf der Homepage von Dresden Elektronik heruntergeladen werden kann. Die passende Firmware kann ebenfalls bei Dresden Elektronik heruntergeladen werden (siehe [5]). Der Dateiname für eine ConBee-Firmware muss dabei folgendem Muster enstprechen deCONZ_Rpi_*.bin.GCF. Die Dateien deCONZ_ConBeeII_*.bin.GCF funktionieren nur für die neuere Version ConBee II (siehe auch [6]).

C:\Tools\GCFFlasher>GCFFlasher.exe -l
GCFFlasher V2_10 (c) dresden elektronik ingenieurtechnik gmbh 2016/09/26

 1 FTDI device found

 device | vendor | product | serial | description
--------|--------|---------|---------|----------------------
 0 | 0x0403 | 0x6015 | DO00KA2V | FT230X Basic UART

C:\Tools\GCFFlasher>GCFFlasher.exe -d 0 -f deCONZ_Rpi_0x26350500.bin.GCF
GCFFlasher V2_10 (c) dresden elektronik ingenieurtechnik gmbh 2016/09/26
using firmware file: deCONZ_Rpi_0x26350500.bin.GCF
reset via FTDI

flashing 125732 bytes: |=============================|
verify: ....
SUCCESS

 

Quellen

[1] Phoscon von Dresden Elektronik
[2] Installing Phoscon/Deconz gateway on Turris Omnia in LXC container
[3] https://github.com/dresden-elektronik/deconz-rest-plugin/issues/284
[4] Dresden Elektronik - Software Download
[5] Dresden Elektronik - Firmware Download 
[6]  Update deCONZ manually

Kommentare

PostadresseE-MailadresseFestnetzMobiltelefonSMS/SignalThreemaTwitter DirektnachrichtFAXWeb Page