Wireless M-Bus in Home Assistant über ESP32 + MQTT – verteilte Empfänger, WebUI und automatische Erkennung

wmbusmeters ist ein hervorragender Decoder, aber die übliche Home-Assistant-Konfiguration setzt voraus, dass der Funkempfänger direkt mit dem Home-Assistant-Host verbunden ist.

Das wird unpraktisch, wenn sich die Zähler außerhalb der Funkreichweite befinden, wenn der Empfänger im Keller, Treppenhaus oder in der Garage platziert werden muss, wenn USB-Funksticks mit ZHA- oder Z-Wave-Sticks konkurrieren oder wenn mehrere Empfangspunkte benötigt werden.

Dieses Projekt trennt deshalb den Funkempfang von der Dekodierung.

Der ESP32 wird dort platziert, wo der Funkempfang am besten ist, und übernimmt ausschließlich die Funkseite. Er veröffentlicht Wireless-M-Bus-RAW-Telegramme über MQTT.

Dekodierung, AES-Schlüssel, Zählertreiber und die Erstellung der Home-Assistant-Entitäten bleiben auf dem Home-Assistant-Host. Mehrere ESP-Empfänger können denselben Decoder versorgen. Am Home-Assistant-Host selbst ist kein USB-Funkempfänger erforderlich.

LISTEN-Modus

Jeder empfangene Zähler erscheint automatisch in der WebUI — mit Hersteller, Zähler-ID, vorgeschlagenem Treiber, Empfangsstatistiken (15 min / 60 min) und einer Live-Vorschau der dekodierten Werte. Der Zähler kann also geprüft werden, bevor er konfiguriert wird. Dafür sind weder YAML noch ein Neustart erforderlich.

Zähler mit einem Klick hinzufügen

Ein erkannter Zähler kann direkt aus der WebUI hinzugefügt werden — vorgeschlagenen Treiber bestätigen oder ändern, bei Bedarf den AES-Schlüssel eintragen, fertig. Die Home-Assistant-Entitäten werden anschließend automatisch über MQTT Discovery erstellt, und zwar aus genau den Feldern, die tatsächlich im dekodierten JSON vorhanden sind. Keine manuellen Sensordefinitionen pro Treiber, keine Einträge in configuration.yaml. Das Hinzufügen löst nur einen Soft-Reload der Pipeline aus — das Add-on selbst startet nicht neu.

SEARCH-Modus

In Mehrfamilienhäusern können gleichzeitig Dutzende Zähler empfangen werden. Der SEARCH-Modus vergleicht den auf dem physischen Zähler angezeigten Messwert mit den live dekodierten Werten und identifiziert so den eigenen Zähler — ohne jede ID einzeln durchzuprobieren.

Pipeline-Dashboard

Die WebUI zeigt den gesamten Datenfluss:

ESP-Empfänger → MQTT → Decoder → Home Assistant

Jede Stufe zeigt ihren tatsächlichen Status und die aktuelle Aktivitätsrate. Eine Stufe wird nur dann als funktionsfähig angezeigt, wenn dort wirklich Daten fließen — die Oberfläche zeigt kein „grün", wenn im Hintergrund nichts verarbeitet wird.

Selbstdiagnostizierender Start

Probleme mit dem MQTT-Broker werden als konkrete, verständliche Meldungen angezeigt: falsche Zugangsdaten, nicht erreichbarer Broker oder fehlende Pflichtfelder — die WebUI sagt direkt, welche Einstellung geprüft werden muss, statt leere Felder und unerklärte Striche zu zeigen.

Weitere Funktionen

  • automatische Broker-Erkennung: Mosquitto über die Supervisor-API, EMQX über eine Broker-Probe (manuelle Konfiguration weiterhin möglich)

  • Unterstützung für CC1101, SX1276 und SX1262

  • AES-Schlüssel pro Zähler, verwaltet in der WebUI

  • mehrere ESP-Empfänger an einem gemeinsamen Decoder

  • WebUI in fünf Sprachen: Englisch, Polnisch, Deutsch, Tschechisch, Slowakisch

  • Betrieb auch als eigenständiger Docker-Container ohne Home Assistant

  • Funk-Firmware und Decoder werden unabhängig voneinander aktualisiert — neue Zählertreiber erfordern kein erneutes Flashen der Empfänger

Tests

Eine Decode-Regression-Suite läuft in der CI bei jedem Build im frisch gebauten Image und blockiert fehlerhafte Releases — mit Referenztelegrammen u. a. für Techem, Qundis, Kamstrup, Diehl, Apator, BMETERS, Maddalena und Integra. Regressionen in Treibern, Dekodierung und Feldzuordnung werden so früh erkannt.

Projektlinks

Die Funkkomponente basiert auf Arbeiten aus den ESPHome-Komponenten von SzczepanLeon. In diesem Projekt wurden Dekodierung und Zählertreiber aus der ESP-Firmware in das serverseitige Add-on verschoben; die ESP-Firmware übernimmt ausschließlich den Funkempfang.

Für wen ist das gedacht?

Dieses Projekt soll bestehende wmbusmeters-Installationen nicht ersetzen. Wenn ein USB-Funkempfänger direkt am Home-Assistant-Host zuverlässig alle Zähler erreicht, gibt es keinen Grund, etwas zu ändern.

Es richtet sich an Installationen, bei denen die Zähler nicht in der Nähe des HA-Hosts liegen, mehrere Empfangspunkte benötigt werden, kein USB-Gerät am Host erwünscht ist oder automatische Erkennung, WebUI und Diagnose gewünscht sind.

Der ESP steht dort, wo das Funksignal gut ist. Der Decoder läuft dort, wo Rechenleistung und Speicher vorhanden sind. MQTT verbindet beide.

sprich, die Vorteile ergeben sich insbesondere wenn man mehrere Empfänger benötigt und diese nicht einzeln mit ESPHome managen muss?

Genau, mehrere Empfänger sind der offensichtlichste Vorteil: N „dumme" ESPs, ein Decoder, eine zentrale Zählerliste — kein Zähler-YAML pro Board.

Aber der Punkt „nicht einzeln mit ESPHome managen" gilt schon ab einem einzigen Empfänger: der ESP wird einmal geflasht und danach nie wieder angefasst. Zähler hinzufügen/entfernen, Treiber wählen, AES-Schlüssel eintragen — alles passiert in der WebUI des Add-ons, ohne YAML, ohne Neukompilieren, ohne OTA.

Dazu kommen ein paar Dinge, die unabhängig von der Anzahl der Empfänger sind:

Treiber-Updates ohne Flashen: die Zählertreiber leben im Add-on (vollständiges wmbusmeters-Treiberset), nicht in der ESP-Firmware. Neuer Treiber oder Bugfix upstream → Add-on-Update, fertig. Kein Flash-Limit des ESP.
Discovery vor der Konfiguration: jeder gehörte Zähler erscheint in der WebUI mit Hersteller, Treibervorschlag und Live-Wert als Vorschau — bevor man ihn überhaupt anlegt.
AES-Schlüssel bleiben auf dem Server, nicht im ESP-YAML.
Wenn ein einzelner Empfänger mit der ESPHome-Komponente für dich gut funktioniert und du YAML magst — dabei bleiben, das ist völlig in Ordnung. Der Unterschied wird spürbar, sobald Zähler öfter wechseln, die Reichweite nicht reicht oder man das Flashen leid ist.

So sieht das bei mir live aus: drei Empfänger (Heltec, LilyGO, XIAO Seeed) an verschiedenen Standorten, ein Decoder — 70 Zähler in Reichweite, 27 Telegramme/min. Zähler hinzufügen, Treiber ändern, AES-Schlüssel eintragen — nichts davon hat je ein Reflash der Empfänger erfordert; das passiert komplett in der WebUI. (Firmware-Updates flashe ich natürlich gelegentlich — ich entwickle sie ja. :wink:)