rtl-433 MQTT autodiscovery ohne Addon
Posted on Sun 26 February 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.