Modbus-Proxy als Home-Assistant-Add-on: Ein Patch für die Marstek Venus D
Die meisten Modbus-Geräte erlauben nur eine einzige TCP-Verbindung, jeder weitere Client wird abgewiesen. Ein Modbus-Proxy sitzt dazwischen, hält die eine Verbindung zum Gerät und bedient beliebig viele Clients. Für Home Assistant gibt es dafür das Add-on ha-modbusproxy von Akulatraxas, das den modbus-proxy von tiagocoutinho verpackt. Mein Fork ist dasselbe Add-on mit einem Patch: Er baut den Proxy aus einem angepassten Zweig statt aus dem PyPI-Release.
Das Problem an der Venus D
Antwortet eine Marstek Venus D (Control/EMS v150) auf das Lesen eines nicht implementierten Registers, schickt sie eine Fehlerantwort von neun Byte. Im MBAP-Header steht dort eine Länge von 4, das Protokoll verlangt 3. Ein Proxy ist selbst ein Parser: Er liest laut Header ein weiteres Byte, das nie kommt. Der Mechanismus im Detail: readexactly() wartet auf das fehlende Byte, write_read verbrennt zwei Timeouts auf der Geräte-Sperre – beim Standardwert bis zu 20 Sekunden –, und alle anderen Clients der Bridge warten in der Zwischenzeit. Die Marstek Modbus Suite beschreibt dasselbe als Messung: Am Client kamen gar keine Bytes an, die echten Frames waren erst sichtbar, nachdem der Proxy gestoppt war.
Die Suite braucht selbst keinen Proxy, denn sie spricht direkt mit dem Speicher und korrigiert die fehlerhaften Antworten der Firmware selbst. Einen Proxy braucht man, wenn ein zweiter Client den Speicher mitbenutzt – das Gerät nimmt nur eine einzige Modbus-TCP-Sitzung an und verweigert jede weitere, solange eine gehalten wird. Weil die Suite absichtlich Registerlücken abfragt, um zu lernen, welche das Gerät bedient, ist die Fehlerantwort an dieser Stelle kein seltenes Ereignis mehr. Bis der Fix im Original steckt, empfiehlt die Suite dieses gepatchte Add-on.
Der Patch
Das Add-on installiert den Proxy per pip aus sphings79/modbus-proxy@fix/exception-frame-mbap-length. Dieser Zweig rahmt Fehlerantworten nach dem Protokoll und nicht nach dem Längenfeld des Headers. Dafür kommt git ins Build-Image. Das ist ein Deployment-Zweig, der nicht für Upstream gedacht ist. Die Korrektur selbst liegt als Pull Request im Original (tiagocoutinho/modbus-proxy#62); für das Add-on gibt es einen PR und ein Issue (#43, #42).
Name, Version und Repository-Metadaten sind geändert, damit sich der Fork als eigenes Add-on-Repository hinzufügen lässt und neben dem Original läuft, statt es zu überdecken. Das Add-on heißt „modbus-proxy (exception-frame patch)“, die Version 1.1.1-exception-frame.1.
Die Version und der Docker-Tag
Die erste Fassung trug die Version 1.1.0+exception-frame.1. Das Build schlug damit fehl, mit nichts als „invalid reference format“, das der Supervisor als unbekannten Fehler weiterreicht. Die Add-on-Version wird zum Image-Tag, und eine Docker-Referenz darf nur Buchstaben, Ziffern, Unterstriche, Punkte und Bindestriche enthalten. Reproduziert wurde es lokal mit docker build -t local/modbus-proxy:1.1.0+exception-frame.1 .. Die Version 1.1.1-exception-frame.1 ist ein gültiger Tag und sortiert trotzdem über der 1.1.0, auf der sie beruht. Das Image baut, enthält den gepatchten Proxy und reicht eine korrigierte Fehlerantwort an den Client durch.
Installation und Einrichtung
- In Home Assistant das Add-on-Repository
https://github.com/sphings79/ha-modbusproxyhinzufügen. - „ModBusProxy“ aus dem Add-on-Store installieren.
- Alle Clients stoppen, die sich bisher mit dem Modbus-Server verbinden – der Server braucht unter Umständen etwas, bevor sich der Proxy verbinden darf.
- In der Konfiguration die IP des Modbus-Servers eintragen, das Add-on starten und die Clients auf die IP von Home Assistant und den gewählten Port umstellen.
Der erste Start kann dauern, weil der Container lokal gebaut wird. Das Add-on ist nur mit dem Hassio-Supervisor getestet und für aarch64 und amd64 gebaut.
Mehrere Geräte lassen sich über die Liste devices im YAML-Modus bedienen, jeweils mit eigenem Listen-Port. Das ist ein Beitrag von jomach im Original:
devices:
- upstreamhost: 192.168.1.212
upstreamport: 502
listenport: 502
- upstreamhost: 192.168.1.213
upstreamport: 502
listenport: 503
timeout: 5
loglevel: INFOJeder listenport muss eindeutig sein und im Netzwerkbereich des Add-ons freigegeben werden; dort stehen die Ports 502 bis 510 zur Verfügung. Ohne devices verhält sich das Add-on wie bisher. Das Projekt ist ein Fork unter Apache-2.0; alles ab der Überschrift „Home Assistant AddOn Modbus Proxy“ im README stammt aus dem Original.
Zum Projekt
-
Modbus Proxy (Add-on, gepatcht)
Fork des Home-Assistant-Add-ons „ha-modbusproxy“ von Akulatraxas: Der Proxy ermöglicht mehrere Modbus-Clients an einem Server und rahmt Fehlerantworten korrekt, wie sie die Marstek Venus D sendet.
Unterstützen
Diese Tools entstehen in meiner Freizeit und bleiben kostenlos, offen und cloud-frei. Wenn dir eins davon einen Nachmittag gespart hat, freue ich mich über einen Kaffee oder ein Stück Pizza.
Kaffee oder PizzaWeitere Beiträge
- Rollladen-Steuerung pro Raum: Taster, Fenster, Kälte und Regen Eine Automation pro Raum, die Taster, Fensterkontakt, Kälte, Regen und die Zeit vor Sonnenaufgang zusammenführt. Zwei Merker-Helfer verhindern, dass sich die Auslöser gegenseitig überfahren.
- Stromausfall erkennen und Geräte wiederherstellen in Home Assistant Nach einem Stromausfall booten Lampen und Steckdosen in zufälligen Zuständen. Drei Erkennungswege, ein gemeinsames Script und ein Wiederherstellungsfenster bringen alles wieder in den gewünschten Zustand.
- Rauchmelder löst aus: Alle Rollläden fahren hoch (Home Assistant) Bei Rauchalarm sollen die Rollläden im ganzen Haus hochfahren, damit Fenster als Fluchtweg frei sind. Die Automation ist kurz – aber ein fehlendes „from“ im Trigger entscheidet darüber, ob sie im Ernstfall überhaupt feuert.