sphings-dev.de

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

  1. In Home Assistant das Add-on-Repository https://github.com/sphings79/ha-modbusproxy hinzufügen.
  2. „ModBusProxy“ aus dem Add-on-Store installieren.
  3. Alle Clients stoppen, die sich bisher mit dem Modbus-Server verbinden – der Server braucht unter Umständen etwas, bevor sich der Proxy verbinden darf.
  4. 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: INFO

Jeder 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.

Tags

Zum Projekt

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 Pizza

Weitere Beiträge