Thread-Geräte
Matter-over-Thread-Geräte (Türkontakte, Hygrometer, viele batteriebetriebene Sensoren) brauchen zusätzliche, physische Infrastruktur, die Matter-over-Wifi-Geräte (z.B. smarte Steckdosen) nicht benötigen. Diese Seite beschreibt, was zusätzlich nötig ist und wie es eingerichtet wird.
Übersicht: was zusätzlich benötigt wird
Ein Thread Border Router (TBR), bereits im lokalen Netz aktiv, bevor überhaupt ein Kopplungsversuch gestartet wird. matter-server (der Sidecar dieses Plugins) ist ein Matter-Controller, kein Border Router - er kann kein Thread-Netz selbst aufspannen.
Ein Bluetooth-Adapter auf dem Host, auf dem dieses Plugin (server-Rolle) läuft - für die Erstkopplung neuer, noch nicht vernetzter Geräte (siehe unten, warum).
IPv6 im lokalen Netz, zumindest auf dem Segment, in dem der Border Router und der matter-server-Host stehen.
Ohne TBR schlägt jeder Kopplungsversuch eines Thread-Geräts fehl - unabhängig davon, ob Bluetooth korrekt eingerichtet ist oder nicht.
Thread Border Router
Zwei Wege:
Ein fertiges TBR-Gerät (z.B. ein Zigbee/Thread-Hub eines Herstellers, oder ein Smart-Home-Hub mit eingebautem TBR). Keine weitere Einrichtung für dieses Plugin nötig - das TBR-Gerät kümmert sich selbst um das Thread-Netz, matter-server findet es über mDNS.
OpenThread Border Router (OTBR) selbst betreiben - quelloffen, herstellerunabhängig, läuft als Docker-Container auf jedem Linux-Host (auch ohne Home Assistant). Der Rest dieses Abschnitts beschreibt diesen Weg.
Benötigte Hardware für einen selbst betriebenen OTBR
Ein RCP-fähiger Funk-Stick (Radio Co-Processor, mit ot-rcp-Firmware, IEEE 802.15.4). Ein
bekannt funktionierendes Gerät: ConBee III.
Warnung
Nicht jeder „Zigbee/Thread-Stick“ ist als eigenständiger TBR nutzbar - manche Hersteller-FAQs grenzen explizit ein, ob „nicht mit dem Hersteller-Hub nutzbar“ bedeutet „gar nicht standalone möglich“ oder nur „kein fertiges Komplettpaket ohne Zusatz-Software“. Vor dem Kauf die genaue Formulierung der Hersteller-FAQ prüfen, nicht nur den Produktnamen.
Die Baudrate des Sticks muss zur OT_RCP_DEVICE-Umgebungsvariable passen - sie ist nicht
für jeden Stick gleich. ConBee III läuft mit 115200, nicht mit der neueren OTBR-Standard-Baudrate
460800.
Docker-Setup
sudo mkdir -p /var/lib/otbr
docker run --name=otbr --detach --network=host --cap-add=NET_ADMIN \
--device=/dev/thread --device=/dev/net/tun \
--volume=/var/lib/otbr:/data --env-file=otbr-env.list \
--restart=always openthread/border-router
/dev/thread durch den tatsächlichen Geräte-Pfad des RCP-Sticks ersetzen (z.B. per Udev-Regel
auf einen stabilen Namen fixieren, nicht auf /dev/ttyUSB0 verlassen, das sich nach einem
Neustart ändern kann).
otbr-env.list (Beispiel):
OT_RCP_DEVICE=spinel+hdlc+uart:///dev/thread?uart-baudrate=115200
OT_INFRA_IF=eth0
OT_THREAD_IF=wpan0
OT_WEB_LISTEN_PORT=9090
OT_INFRA_IF ist das Netzwerk-Interface, über das der Border Router das Thread-Netz mit dem
normalen LAN verbindet - i.d.R. das reguläre Ethernet/WLAN-Interface des Hosts.
Bemerkung
OT_WEB_LISTEN_PORT ist optional und nur nötig, falls Port 8080 (OTBRs Standard für sein
eigenes Web-Dashboard) bereits belegt ist. Betrifft nur das Dashboard, nicht die
Kern-Funktionalität (Port 8081, REST-API) - ein Konflikt dort zeigt sich in den Logs als
Absturz von otbr-web, während otbr-agent normal weiterläuft.
Wichtig
Nur die Silicon-Labs-eigenen Images (siliconlabsinc/openthread-border-router) sind
32-Bit-ARMv7-only. Auf einem 64-Bit-Host (arm64/x86_64) das generische
openthread/border-router-Image verwenden, nicht das Silicon-Labs-Image.
IPv6 auf dem Infra-Interface
Der Border Router benötigt IPv6 auf OT_INFRA_IF - Thread selbst basiert auf IPv6.
Warnung
Zwei unterschiedliche, unabhängig voneinander wirkende sysctls können IPv6 auf einem
Interface verhindern - disable_ipv6 allein zu prüfen reicht nicht:
net.ipv6.conf.<interface>.disable_ipv6- der bekannte Ein/Aus-Schalter.net.ipv6.conf.<interface>.addr_gen_mode- steuert, wie Adressen generiert werden. Wert1bedeutet „keine“ - es werden überhaupt keine IPv6-Adressen erzeugt, nicht einmal eine Link-Local-Adresse, obwohldisable_ipv6auf0steht.ip -6 addr show <interface>zeigt dann eine komplett leere Liste.
Bei fehlender IPv6-Adresse trotz disable_ipv6=0 als nächstes addr_gen_mode prüfen:
sysctl net.ipv6.conf.<interface>.addr_gen_mode
# 0 = EUI64 (normal), 1 = keine Adressen, 2 = stable-privacy, 3 = random
sysctl -w net.ipv6.conf.<interface>.addr_gen_mode=0
Thread-Netzwerk aktiv bilden
Ein laufender OTBR-Container bedeutet nicht automatisch ein bestehendes Thread-Netz - beides muss getrennt eingerichtet werden:
docker exec otbr ot-ctl dataset init new
docker exec otbr ot-ctl dataset commit active
docker exec otbr ot-ctl ifconfig up
docker exec otbr ot-ctl thread start
docker exec otbr ot-ctl state
state sollte nach kurzer Zeit leader zeigen. detached direkt nach thread start ist
normal (kurzer Übergangszustand) - nur wenn es dauerhaft bei detached bleibt, liegt ein
Problem vor (RCP-Kommunikation prüfen, docker logs otbr).
Warnung
mDNS ist link-lokales Multicast (Port 5353) und überschreitet keine VLAN-/Subnetz-Grenzen, auch wenn Routing zwischen den Netzen erlaubt ist. Border Router und der matter-server-Host (dieses Plugin) müssen im selben Layer-2-Segment stehen, sonst findet matter-server den Border Router nicht - andernfalls ist zusätzlich ein mDNS-Reflektor (z.B. Avahi im Reflector-Modus) nötig.
Bluetooth für die Erstkopplung
Ein fabrikneues, noch nie gekoppeltes Matter-over-Thread-Gerät hat noch keine Netzwerk-Zugangsdaten und ist daher noch nicht über IP erreichbar. Die Übergabe dieser Zugangsdaten beim allerersten Pairing läuft über Bluetooth Low Energy (BLE), nicht über das Thread-Netz selbst. Ohne einen funktionierenden Bluetooth-Adapter auf dem matter-server-Host lässt sich daher kein neues Thread-Gerät kommissionieren, unabhängig davon, wie gut der Border Router eingerichtet ist.
Ein einfacher USB-BLE-Stick genügt (getestet: TP-Link UB500).
Einrichtung
HCI-ID des Adapters ermitteln (i.d.R.
0für den einzigen/ersten Adapter,hci0):bluetoothctl listIm Plugin-Instanz-Parameter
server_bluetooth_adapterdie HCI-ID eintragen (als String, z.B.'0'- nicht die MAC-Adresse).
Wichtig
Ohne gesetzten server_bluetooth_adapter bleibt BLE deaktiviert und ein neues
Thread-Gerät kann nicht kommissioniert werden, selbst mit korrekt funktionierender Hardware.
Bekannte Bluetooth-Stolperfallen unter Linux
Warnung
Fehlende Adapter-Firmware. Günstige USB-BLE-Sticks mit Realtek-Chipsatz (z.B. RTL8761B, u.a. im TP-Link UB500 verbaut) benötigen eine separate, proprietäre Firmware-Datei, die Debian/Devuan nicht standardmäßig installiert:
sudo apt-get install firmware-realtek
Diese liegt in der non-free-firmware-Repository-Komponente (Debian 12/“bookworm“ und
neuer; ältere Versionen nutzen non-free) - ggf. erst in den apt-Quellen aktivieren. Ohne
die Firmware zeigt dmesg einen Fehler wie firmware: failed to load rtl_bt/... - der
Adapter wird als hci0 erkannt, aber die Firmware-Initialisierung schlägt fehl. Nach der
Installation den Stick einmal ab- und wieder anstecken (oder ohne physischen Zugriff per
Treiber-Rebind: echo -n "<bus-id>:1.0" > /sys/bus/usb/drivers/btusb/unbind gefolgt von
bind mit derselben ID).
Fehlende Root-Rechte für Raw-Sockets. Ohne die Capability cap_net_raw auf dem
tatsächlich verwendeten Node.js-Binary bleibt BLE-Scanning wirkungslos - ohne jede
Fehlermeldung, das Scannen startet einfach nie:
sudo setcap cap_net_raw+eip <pfad-zum-node-binary>
getcap <pfad-zum-node-binary>
Den tatsächlich verwendeten Pfad über den laufenden Prozess ermitteln, nicht per which
node raten - beides kann sich unterscheiden, je nachdem, welche Umgebung shng beim Start
tatsächlich verwendet:
pgrep -f MatterServer.js
readlink -f /proc/<pid>/exe
Adapter nicht eingeschaltet. Der Raw-HCI-Modus (Linux-Standardverhalten von matter.js) schaltet einen ausgeschalteten Adapter nicht selbst ein:
sudo hciconfig hci0 up
hciconfig hci0
# Flags-Zeile muss "UP RUNNING" enthalten
Thread-Netzwerk-Zugangsdaten im Plugin registrieren
Selbst mit funktionierendem Bluetooth scheitert die Kommissionierung eines Thread-Geräts ohne einen weiteren, einmaligen Schritt: matter-server muss wissen, welche Zugangsdaten es dem Gerät für das Thread-Netz übergeben soll. Diese werden nicht automatisch vom Border Router übernommen - sie müssen einmalig eingetragen werden.
Aktives Dataset des Border Routers auslesen (Hex-Format):
docker exec otbr ot-ctl dataset active -x
Im Webinterface unter „Thread Netzwerk-Zugangsdaten“ den Hex-String eintragen und absenden.
Die Zugangsdaten werden dauerhaft in matter-servers eigenem Speicher abgelegt (kein erneutes Eintragen nach einem Neustart nötig) - eine einmalige Einrichtung pro Thread-Netz, kein Schritt pro Gerät. Solange nichts gesetzt ist, zeigt der Devices-Tab ein Eingabefeld; danach zeigt der Tabellenkopf oben auf der Seite stattdessen „Gesetzt“ mit einer Löschen-Option (zum bewussten Zurücksetzen, z.B. bei einem Netz-Wechsel).
Fehlerbilder bei fehlgeschlagener Kommissionierung
Zwei deutlich unterschiedliche Fehler weisen auf unterschiedliche fehlende Voraussetzungen hin:
Fehlermeldung |
Bedeutung |
|---|---|
|
Das Gerät wurde über keinen Kanal (weder Netzwerk noch Bluetooth) überhaupt gefunden. Meist: Gerät nicht (mehr) im Pairing-Modus, zu weit vom Bluetooth-Adapter entfernt, falscher Code eingegeben, oder Bluetooth ist nicht aktiv (siehe oben). |
|
Bluetooth-Pairing war erfolgreich (Gerät ist bereits kryptografisch in shngs Fabric aufgenommen), aber es wurden keine Netzwerk-Zugangsdaten übergeben. Thread Netzwerk-Zugangsdaten (siehe oben) registrieren. |
Bekannte Probleme
node-gyp unter Debian/Devuan
Betrifft nicht nur dieses Plugin, sondern jeden nativen Node.js-Baustein, der während npm
install kompiliert werden muss (u.a. die BLE-Anbindung) - ein bekanntes
Debian/Devuan-Paketierungsproblem, kein Fehler dieses Plugins.
Debian/Devuan liefert ein eigenes, entkerntes node-gyp aus (/usr/share/nodejs/node-gyp),
das ein separates, nicht immer mitinstalliertes Python-Modul voraussetzt. Symptom:
ModuleNotFoundError: No module named 'gyp'
Da fehlgeschlagene optionale npm-Abhängigkeiten standardmäßig stillschweigend übersprungen
werden, erscheint ohne Weiteres gar keine Fehlermeldung - nur ein fehlendes Verzeichnis in
node_modules. Den eigentlichen Fehler sichtbar machen:
npm install --foreground-scripts
Warnung
Ein global installiertes, aktuelles node-gyp (npm install -g node-gyp) behebt dies
nicht zuverlässig - Debians eigenes npm ruft für automatisch getriggerte Builds
weiterhin sein eigenes, systemweites node-gyp auf, unabhängig von $PATH.
Stattdessen das fehlende Python-Modul in genau dem Python installieren, das node-gyp tatsächlich
verwendet - dessen eigene Log-Ausgabe zeigt den genauen Pfad (gyp info find Python using ...
found at "..."). Läuft eine virtuelle Umgebung (venv), reicht ein systemweites apt install
gyp nicht - venvs sind bewusst vom System-Python isoliert:
<pfad-zum-python-des-venvs>/bin/pip install gyp-next
Multicast-Fehler (EHOSTUNREACH) auf macOS
Falls matter-server auf macOS beim Senden von Multicast-Paketen mit EHOSTUNREACH fehlschlägt:
in einem konkreten Fall lag die Ursache nicht bei Little Snitch (auch mit einer expliziten
Erlauben-Regel für alle Prozesse im lokalen Netz), nicht an Parallels‘ virtuellen
Netzwerk-Interfaces (auch nach vollständigem Beenden von Parallels reproduzierbar) und nicht an
einer systemweiten Multicast-Sperre (funktionierender dns-sd-Eigentest parallel dazu). Die
wahrscheinlichste verbleibende Ursache ist eine Eigenheit des jeweiligen Netzwerks selbst (z.B.
Client-Isolation in Gäste-/öffentlichen WLANs) - bei diesem Fehlerbild lohnt sich ein Test in
einem anderen Netz, bevor eine Software-Ursache vermutet wird.