rtl-433 MQTT autodiscovery ohne Addon

Posted on So 26 Februar 2023 in Computer & Electronics

In früheren Posts hatte ich ja schon meine Funkthermometer in Homeassistant (HASS) eingebunden. Das funktioniert wunderbar. Allerdings habe ich inzwischen ziemlich viele solche Temperatursensoren und es wird zunehmend mühsam, die alle im Config-File zu pflegen. Und jedesmal, wenn bei einem Sensor eine neue Batterie fällig wird ändert das blöde Ding seine ID und ich darf wieder ins Config File und den betroffenen Sensor finden, die neue ID rausfinden und dort eintragen. Das ist auf die Dauer etwas lästig.

Bei meiner Recherche bin ich dann auf das rtl_433_mqtt_autodiscovery Addon gestoßen, das dieses Problem adressiert. Bei einem Freund hatten wir das auch schon mal erfolgreich eingerichtet und es funktioniert wie gedacht: Das Addon liest die MQTT Messages mit und wenn es eine rtl-433 Message findet erzeugt es seinerseits eine zusätzliche MQTT Message in einem Format, dass HA versteht und dann die entsprechenden Sensoren von selbst erkennt. Natürlich löst das noch nicht das Problem, mit den Wechselnden IDs, aber zumindest ist es damit getan, zu schauen, welche neuen Sensoren aufgetaucht sind und diese dann entsprechend umzubenennen, dass sie wieder am alten Ort auftauchen.

Nun ist es allerdings so, dass Addons im Gegensatz zu Integrations nicht einfach im Homeassistant eingebunden werden. Addons sind keine Bestandteile von Homeassistant, sondern externe Services, die außerhalb von HASS laufen und mit diesem reden. Dazu muss man verstehen, dass HASS (=Homeassistant) die eigentliche Web Applikation ist und HASSOS ein ganzes Betriebssystem (OS) das dazu gedacht ist, z.B. auf einem Raspberry Pi zu laufen. Und letzteres kann andere Software als Addon verwalten.

Mosquitto ist ein solches Beispiel: es ist ein eigenständiges Stück Software, das einen MQTT Server zur Verfügung stellt. Und bei mir läuft selbiger auch ganz traditionell als Service auf meinem Debian Server. Wer nun HASSOS auf einem Pi laufen hat, der hat garkeinen so direkten OS-Zugriff und würde Mosquitto stattdessen als Addon installieren. Letztlich sind Addons nichts andderes, als irgendwelche Server-Prozesse, die in ihrem eigenen Docker-Container verpackt wurden und dann vom HASSOS Supervisor installiert, gestartet und überwacht werden.

Das ist praktisch, wenn man wenig Ahnung von LINUX hat und/oder es einfach bequemer findet HASS als eine Art Appliance laufen zu lassen, ohne sich direkt mit den Interna befassen zu müssen. Mir persönlich ist das eher unsympathisch und es kommt mir komplexer vor, als es direkt im OS zu verwalten. Z.B. haben wir neulich versucht, ein SSH Addon auf dem Pi eines Freundes zum Laufen zu bekommen. Letztlich hat es funktioniert, aber wir haben ewig daran rumgebastelt, bis es ging. Unter Debian wäre es ein simples apt install sshd gewesen.

Und so wollen wir uns heute mal damit befassen, wie wir in den Genuss dieses Autodiscovery Features kommen, ohne HASSOS zu nutzen.

rtl-433 als Service einrichten

Damit der autodiscovery Service etwas ausrichten kann, brauchen wir zunächst mal den eigentlichen rtl-433 Service der die Sensor-Daten via rtl-sdr empfängt. Das ist bei mir eigentlich schon eingerichtet, aber ich beschreibe es hier trotzdem nochmal, damit man diesen Post als vollständiges Tutorial verwenden kann. Außerdem hatte ich in meiner ursprünglichen Konfiguration das Format der MQTT-Topics der Sensoren verändert und das würde der Autodiscovery Service nicht verstehen. D.h. wenn Ihr meiner ursprünglichen Anleitung gefolgt seid müsst Ihr nun auch zumindest das Config File anpassen. Hier die Schritte:

rtl-433 installieren:

sudo apt install rtl-433

Config File erzeugen (/etc/rtl_433.conf) und diesen Inhalt reinschreiben:

convert si
output mqtt://hal:1883,user=phil,pass=TopS3cret,retain=0
report_meta time:utc
report_meta newmodel

Nun den User für den Service anlegen und in group plugdev aufnehmen, damit er Zugriff auf den rtl-sdr hat:

sudo adduser rtl_433
sudo adduser rtl_433 plugdev

Und noch die permissions einschränken, damit nicht Hinz&Kunz das lesen können (password!):

sudo chown rtl_433:rtl_433 /etc/rtl_433.conf
sudo chmod o-rwx /etc/rtl_433.conf

Als nächstes legen wir das Service File an (/etc/systemd/system/rtl_433.service) – mit diesem Inhalt:

# See https://github.com/merbanan/rtl_433/issues/1651 for original
# suggestion
[Unit]
Description=RTL_433 service
Documentation=man:rtl_433
StartLimitIntervalSec=10
After=syslog.target network.target

[Service]
Type=exec
User=rtl_433
Group=rtl_433
ExecStart=/usr/bin/rtl_433 -c /etc/rtl_433.conf
Restart=always
RestartSec=30s

# View with: sudo journalctl -f -u rtl_433 -o cat
SyslogIdentifier=rtl_433

[Install]
WantedBy=multi-user.target

Nun können wir den Service starten und dauerhaft aktivieren:

sudo systemctl daemon-reload
sudo systemctl restart rtl_433.service
sudo systemctl enable rtl_433

rtl-433 Autodiscovery ohne Addon

Als nächstes kümmern wir uns um den Auto-Discovery-Service. Dazu habe ich mir mal das git repository genauer angeschaut. Die eigentliche funktionale Komponente ist ein Python Skript namens rtl_433_mqtt_hass.py, das aus dem rtl_433 Package stammt. Unter Debian findet es sich in /usr/share/doc/rtl-433/examples/rtl_433_mqtt_hass.py.

Und das muss man natürlich nicht in einem eigenen Docker Container laufen lassen, sondern kann es wie gehabt in einen systemd Service verwandeln, wie ich es auch schon mit rtl-433 getan habe. Also machen wir das mal.

Das Skript verwendet die paho-mqtt library, also installieren wir die als erstes:

apt install python3-paho-mqtt

Bevor wir das Ganze nun als Service verpacken, wollen wir es erstmal von Hand starten und schauen, ob auch alles funktioniert. Dazu nehmen wir zunächst mal das Discovery Topic Prefix FOO (statt homeassistant), damit beim Testen nicht schon alle möglichen Sachen automatisch in HASS angelegt werden:

> python3 /usr/share/doc/rtl-433/examples/rtl_433_mqtt_hass.py -u phil -P TopS3cret -H hal -D FOO 
MQTT connected: Connection Accepted.
Published inFactory-TH/3/138: battery_ok, temperature_C, humidity

Und in einem anderen Fenster überwachen wir was unter dem neuen Topic ankommt:

mosquitto_sub -h hal -u phil -P TopS3cret -t 'FOO/#'
{"device_class": "battery", "name": "inFactory-TH-3-138-B", "unit_of_measurement": "%", "value_template": "{{ float(value|int) * 99 + 1 }}", "state_topic": "rtl_433/hal/devices/inFactory-TH/3/138/battery_ok", "unique_id": "inFactory-TH-3-138-B", "device": {"identifiers": "inFactory-TH-3-138", "name": "inFactory-TH-3-138", "model": "inFactory-TH", "manufacturer": "rtl_433"}}
{"device_class": "temperature", "name": "inFactory-TH-3-138-T", "unit_of_measurement": "\u00b0C", "value_template": "{{ value|float }}", "state_topic": "rtl_433/hal/devices/inFactory-TH/3/138/temperature_C", "unique_id": "inFactory-TH-3-138-T", "device": {"identifiers": "inFactory-TH-3-138", "name": "inFactory-TH-3-138", "model": "inFactory-TH", "manufacturer": "rtl_433"}}
{"device_class": "humidity", "name": "inFactory-TH-3-138-H", "unit_of_measurement": "%", "value_template": "{{ value|float }}", "state_topic": "rtl_433/hal/devices/inFactory-TH/3/138/humidity", "unique_id": "inFactory-TH-3-138-H", "device": {"identifiers": "inFactory-TH-3-138", "name": "inFactory-TH-3-138", "model": "inFactory-TH", "manufacturer": "rtl_433"}}

Sehr gut – es funktioniert!

Nun brauchen wir ein service file (/etc/systemd/system/rtl433-autodiscovery.service):

[Unit]
Description=RTL_433 autodiscovery service
StartLimitIntervalSec=10
After=syslog.target network.target

[Service]
Environment=MQTT_HOST=hal
Environment=MQTT_USERNAME=phil
Environment=MQTT_PASSWORD=TopS3cret

Type=exec
User=rtl_433
Group=rtl_433
ExecStart=python3 -u /usr/share/doc/rtl-433/examples/rtl_433_mqtt_hass.py -H $MQTT_HOST
Restart=always
RestartSec=30s

# View with: sudo journalctl -f -u rtl_433-autodiscover -o cat
SyslogIdentifier=rtl_433-autodiscover

[Install]
WantedBy=multi-user.target

Jetzt können wir unseren Service starten und aktivieren, damit er zukünftig von selbst gestartet wird:

sudo systemctl daemon-reload
sudo systemctl start rtl_433-autodiscover.service
sudo systemctl enable rtl_433-autodiscover.service

Nutzung in Homeassistant

Die Spannung wächst und wir schauen mal in den Homeassistant:

Super – da sind sie ja! Und ich muss wohl mal zwei Batterien austauschen.

Nun bleiben ein paar Aufräumarbeiten: In meiner alten Konfiguration hatte ich die ganzen Sensoren ja manuell im configuration.yaml File definiert. Das muss nun auskommentiert oder rausgelöscht werden. Wenn ihr das aber gerade von Null auf einrichtet müsst Ihr das natürlich nicht machen.

Die Namen der Devices und der zugehörigen Entities sind aktuell eher kryptisch (z.B. inFactory-TH-1-156) und daher sollten wir sie vernünftig umbenennen. Das geht in HASS unter Settings > Devices&Services > MQTT devices und dann auf das konkrete Device gehen und dort auf das Stift-Icon oben rechts klicken. Nun können wir den Namen des Devices vergeben:

Die Namen der zugehörigen entities passen sich dann von selbst an.

An dieser Stelle können wir die Devices problemlos in ein Dashboard einbinden. Und wenn mal die Batterie gewechselt werden muss, dann muss man nur schauen, welcher Sensor mit kryptischem Namen neu dazu gekommen ist, das alte Device löschen und das neue wieder mit den gleichen Namen versehen. Auf diese Weise bleibt im Dashboard alles konstant und wir behalten auch die Device-History.