Marstek Venus A – Erfahrungen & Modbus-Tools

Praxisnotizen zur Ansteuerung eines Marstek Venus A Heimspeichers per Modbus TCP, gesammelt beim Aufbau einer preisgesteuerten Lade-/Entladestrategie.

Werbung
Den hier beschriebenen Akku (Marstek Venus A) gibt es bei Amazon
Affiliate-Link zum Amazon-Partnerprogramm – als Amazon-Partner verdienen wir an qualifizierten Verkäufen, für dich entstehen dabei keine Mehrkosten.
Bei Amazon ansehen
Werbung
Zusatzakku für den Marstek Venus A gibt es ebenfalls bei Amazon
Affiliate-Link zum Amazon-Partnerprogramm – als Amazon-Partner verdienen wir an qualifizierten Verkäufen, für dich entstehen dabei keine Mehrkosten.
Bei Amazon ansehen
Neu: Verlaufsdaten in SQLite + eigenes Dashboard
Collector-Script schreibt Messwerte in eine SQLite-Datenbank, dazu eine PHP-Seite mit Live-Ansicht und History – inkl. Screenshot und Scripts zum Download.
Battery-Stats ansehen

Kernerkenntnis: Lokale API vs. Modbus

Die WLAN-App selbst läuft einwandfrei – aber die lokale API des Akkus (UDP, Port 30000, muss extra eingeschaltet werden) läuft nicht zuverlässig. Sobald diese API aktiv ist, kommt es zu unregelmäßigen Aussetzern und Fehlverhalten – z. B. schaltet der Akku von selbst die Backup-Steckdose aus, schaltet die API selbständig wieder aus, schaltet die LEDs von selbst an oder die Überschusseinspeisung wird deaktiviert – oder alles gleichzeitig, was oft wie ein halber Reset oder Neustart wirkt. Der Akku lief damit keine zwei Tage am Stück stabil. Lässt man die API komplett deaktiviert und steuert den Akku stattdessen ausschließlich per Modbus TCP über ein LAN-Kabel an, läuft er sehr stabil (Stand dieses Tests: erst wenige Wochen, aber bislang ohne Aussetzer – getestet mit Firmware-Version 149).

Im Internet liest man häufig von genau solchen Problemen (Aussetzern, spontanen Fehlfunktionen, Geräten, die irgendwann gar nicht mehr reagieren) – aber so gut wie nie, wodurch sie eigentlich verursacht werden. Unsere Vermutung, basierend auf den eigenen Erfahrungen: die API-Zugriffe selbst.

Modbus TCP ist bei diesem Gerät nur über die kabelgebundene Ethernet-Schnittstelle erreichbar, nicht über WLAN. Der Akku hat in der Praxis zwei unterschiedliche IPs, je nachdem welches Interface gerade aktiv ist – bei Verbindungsproblemen lohnt es sich, zuerst zu prüfen, ob eine zweite (LAN-)IP existiert.

Kurzer Vorgriff: Auch die Modbus-TCP-Umsetzung des Akkus ist genau genommen nicht standardkonform – handelsübliche Modbus-Software kommt damit nicht klar, weshalb wir eigene Python-Scripts geschrieben haben. Details dazu weiter unten.

Warum uns das wichtig ist – eine kurze Geschichte: Der erste Akku wurde über die API gesteuert. Nach etwa drei Wochen mit ständigen Problemen ging er irgendwann gar nicht mehr an: Man konnte ihn einschalten, die grüne Power-LED leuchtete, aber die LEDs auf der Frontleiste blieben aus. Auch per App war er nicht mehr erreichbar. Erst nach langem Nachhaken und vielen Diskussionen mit dem Support wurde das Gerät getauscht. Auch hier vermuten wir im Nachhinein die API als Ursache – gesichert ist das nicht, aber es passt genau ins Bild der Aussetzer und Fehlfunktionen von oben.

Beim Ersatzgerät haben wir ganz am Anfang die API noch einmal kurz getestet und dabei – bis auf den Totalausfall – exakt die gleichen Probleme wie beim ersten Akku gesehen. Seitdem läuft das Ersatzgerät ausschließlich per Modbus (API deaktiviert) – und das Problem ist seitdem nie wieder aufgetreten.

Zwei Zugriffswege im Überblick

Modbus TCP (Port 502) empfohlen

Nur über LAN/Ethernet-Kabel erreichbar. Lesen (FC3/FC4) und Schreiben (FC6) einzelner Register. In unserer Erfahrung deutlich stabiler als die App-gesteuerten Wege – funktioniert aber nur mit selbst geschriebenen Scripts, da die Modbus-Implementierung des Akkus nicht standardkonform ist und fertige Modbus-Software daran scheitert (Details).

Lokale JSON-RPC API (UDP, Port 30000) instabil

Funktioniert über WLAN. Offizielle „Local API“ mit Methoden wie ES.GetStatus/ES.SetMode. Das ist genau die API, die den Akku instabil laufen lässt (siehe Kernerkenntnis oben) – nicht als primären Steuerweg nutzen.

Warum eigene Scripts statt fertiger Modbus-Software?

Die Modbus-TCP-Implementierung des Akkus weicht vom Standard ab. Mit keinem der getesteten fertigen Modbus-Programme kam eine funktionierende Verbindung zustande. Erst eigene, minimalistische Python-Scripts (modbus.py/modbus_w.py) haben zuverlässig funktioniert.

Was den Unterschied macht, lässt sich direkt am Code der Scripts ablesen – sie sprechen bewusst „unsauberes" Modbus TCP:

  • Es wird kein fertiges Modbus-Framework verwendet, sondern ein rohes TCP-Socket. Der 7-Byte-Header (Transaction ID, Protocol ID, Length, Unit ID) wird von Hand zusammengebaut.
  • Die Antwort wird nicht anhand der Längenangabe im Header geparst, sondern anhand fester Byte-Positionen (Function-Code-Byte, Datenbytes) – die Length-Angabe im Header wird schlicht ignoriert, statt als Prüfkriterium zu dienen.
  • Ein Code-Kommentar in modbus.py dokumentiert explizit einen Firmware-Bug: Bei Fehler-/Exception-Antworten schickt der Akku eine falsche Längenangabe im Header (4 statt der korrekten 3) – die Scripts werten die Antwort trotzdem aus, statt sie deswegen zu verwerfen.
  • Die Registernummern (z. B. 42010, 30001) werden unverändert als Protokolladresse übertragen, ohne die in der Modbus-Welt verbreitete Offset-Konvention (z. B. „40001 abziehen") anzuwenden.

Genau das war der Punkt, an dem fertige Modbus-Programme gescheitert sind – sie halten sich strikt an die Spezifikation und geben bei diesen Abweichungen auf. Die eigenen Scripts sind bewusst genau an diesen Stellen toleranter gebaut, und funktionieren dadurch zuverlässig.

Transparenzhinweis: Beide Scripts sind KI-generiert (mit Unterstützung von Claude entstanden). Bei uns laufen sie im Test einwandfrei und liefern zuverlässig korrekte Werte – trotzdem: selbst prüfen, bevor man sich blind darauf verlässt, insbesondere bei schreibenden Zugriffen (Force Mode, Leistung setzen).

Werbung
Selbst mit Claude coden?
Über diesen Link bekommst du eine kostenlose Woche Claude Code geschenkt. Schließt du danach ein Abo ab, erhalten wir dafür Nutzungsguthaben – für dich entstehen keine Kosten. Referral-Link, es gelten die Nutzungsbedingungen von Anthropic.
Claude Code verschenken

Wichtige Register

Schreibbare Steuerregister

RegisterFunktionWerte
42000RS485-Kontrolle aktivieren21930 (0x55AA) = ein, 21947 (0x55BB) = aus
42010Force Mode0 = Stop/Idle, 1 = Laden, 2 = Entladen
42020Ladeleistung0–2500 W
42021Entladeleistung0–2500 W
43000Work Mode0 = Manual, 1 = Anti-Feed, 2 = Trade Mode
44002Max Charge Power800–2500 W
44003Max Discharge Power800–2500 W

Wichtige Leseregister

RegisterBedeutungSkalierung
30001Batterieleistung (W, signed): + = Laden, − = Entladenroh (1:1)
30006AC-Leistungroh (1:1), W
30037–30040PV/MPPT-Leistung 1–4×0.1, W
30100Batteriespannung×0.01
30101Batteriestrom (signed)×0.1
32104SOC (%)roh (1:1)
32105„Battery Total Energy" = Nennkapazität (nicht der aktuelle Ladezustand!)roh in Wh
33000Kumulierte Akku-Entladung (32-Bit, +33001)×0.01 kWh
33002Kumulierte Akku-Ladung (32-Bit, +33003)×0.01 kWh

Es gibt kein eigenes Register für die aktuell gespeicherte Energie (Wh) – sie lässt sich nur als SOC% × Nennkapazität berechnen. Ebenso existiert kein Register für kumulierte PV-Gesamterzeugung, nur die Momentanleistung je MPPT-String.

Vorsicht bei den Vendor-Labels: Die offizielle Doku bezeichnet 33000/33002 als „Total Charging/Discharging Energy“ – bei unserem Gerät war das aber genau andersherum belegt als beschriftet. Vor dem Verlassen auf diese Register lohnt sich ein empirischer Abgleich (Register-Wert vs. beobachtetes Lade-/Entladeverhalten).

Das ist nur die Kurzfassung mit den bei uns bestätigten Registern. Es gibt noch deutlich mehr Register (Temperaturen, Zellspannungen, Zeitpläne, Diagnose, Netzwerk) – gesammelt in unserer erweiterten Register-Referenz. Achtung: Der Großteil davon ist ungeprüft und stammt aus Community-Quellen für das Venus-D-Modell, nicht von unserem A-Modell selbst getestet – deckt sich aber in den bislang von uns stichprobenartig verglichenen Fällen häufig mit dem A-Modell.

Bekannte Fallstricke

Work Mode kann Steuerbefehle stillschweigend blockieren. Steht Register 43000 nicht auf 0 (Manual) – z. B. auf 1 (Anti-Feed), Werkseinstellung bei neuen Geräten – werden Schreibbefehle auf 42010/42020/42021 vom Gerät ignoriert. Der Modbus-Write selbst meldet trotzdem Erfolg (Echo kommt zurück), nur der Akku reagiert nicht.

42000 und 43000 setzen sich beim Schreiben gegenseitig zurück (bestätigter, deterministischer Effekt, kein Timing-Problem). Schreiben von 43000 wirft 42000 zuverlässig wieder auf „aus“ (21947) zurück – und umgekehrt. Das zuletzt geschriebene Register „gewinnt“, das andere kippt garantiert um, ohne dass der Write das meldet.

Funktionierende Reihenfolge nach einem Neustart – 42000 muss der allerletzte Write sein:

43000 = 0       # Work Mode Manual (falls gewünscht)
42000 = 21930   # RS485-Kontrolle – MUSS zuletzt vor 42010/42020 stehen
42010 = 1/2     # Force Mode Laden/Entladen
42020/42021     # Leistung setzen

42010/42020/42021 setzen 42000 nicht zurück – sie können also gefahrlos danach folgen.

Diese Prozedur muss nach jedem Neustart des Akkus erneut durchlaufen werden. Ist das Gerät aber einmal im richtigen Modus (42000 aktiv), scheint es Schreibbefehle bis zum nächsten Neustart zuverlässig anzunehmen – ohne dass man die Register zwischendurch nochmal anfassen muss.

Nicht zu häufig abfragen. Wird der Akku zu dicht getaktet mit Modbus-Anfragen „bombardiert“, kommt es zu fehlerhaften bzw. unvollständigen Rückmeldungen. Ein Poll-Intervall von einigen Sekunden (z. B. alle 3–5 s ein Register) ist unproblematisch – mehr sollte man dem Gerät nicht zumuten. Zwischen mehreren Register-Reads hintereinander lohnt sich zusätzlich eine kurze Pause (in unserem Dauerbetrieb bewährt: 3 s).

Sich nicht darauf verlassen, dass jede einzelne Abfrage klappt. Auch bei moderater Abfragefrequenz schlägt gelegentlich ein Read oder Write fehl (Timeout, leere/unvollständige Antwort). Eigener Code sollte das einplanen – also Fehler abfangen, ggf. mit Retry, und nicht bei einem einzelnen Fehlschlag den letzten bekannten Wert verwerfen oder einen Steuerbefehl als endgültig gescheitert werten.

Scripts zum Download

Zwei schlanke Python-Scripts, raw-socket-basiert (keine externen Modbus-Bibliotheken nötig), zum Lesen und Schreiben einzelner Register per Modbus TCP.

modbus.py
Liest ein Register aus (FC3 Holding, Fallback FC4 Input). Aufruf: python3 modbus.py <IP> <REGISTER> [slave_id]
Download
modbus_w.py
Schreibt ein Register (FC6 Write Single Register). Aufruf: python3 modbus_w.py <IP> <REGISTER> <VALUE> [slave_id]
Download

Beide Scripts verbinden sich per TCP auf Port 502 direkt mit der LAN-IP des Akkus – dafür muss der Akku per Ethernet-Kabel im gleichen Netz hängen.

Nutzung auf eigene Verantwortung. Insbesondere modbus_w.py schreibt direkt in Steuerregister des Akkus (Force Mode, Lade-/Entladeleistung). Bei falscher Anwendung – z. B. Schreiben unerwarteter Werte in unbekannte Register – ist eine Fehlfunktion oder Beschädigung des Geräts nicht auszuschließen. Wir übernehmen keine Haftung für Schäden am Akku, angeschlossenen Geräten oder sonstige Folgeschäden durch die Nutzung dieser Scripts. Vor Schreibzugriffen immer erst mit Lesebefehlen (modbus.py) vertraut machen und Werte im Zweifel gegen die Register-Tabellen oben prüfen.

Voraussetzungen & Verwendung

Abhängigkeiten

Beide Scripts nutzen ausschließlich die Python-Standardbibliothek (socket, struct, sys) – es müssen keine zusätzlichen Pakete per pip installiert werden. Es genügt eine vorhandene Python-3-Installation.

Linux

Auf den meisten Distributionen ist Python 3 bereits vorinstalliert. Falls nicht:

# Debian/Ubuntu
sudo apt install python3

# Fedora
sudo dnf install python3

# Arch
sudo pacman -S python

Prüfen mit python3 --version. Danach direkt aus dem Download-Ordner aufrufen, z. B.:

python3 modbus.py 192.168.1.50 32104
# → liest SOC (%) vom Akku unter dieser IP

python3 modbus_w.py 192.168.1.50 42010 2
# → setzt Force Mode auf "Entladen"

Windows

Die Scripts sind unverändert unter Windows lauffähig – sie verwenden nur plattformunabhängige Standardbibliotheks-Funktionen (TCP-Socket, Byte-Packing), keine Linux-spezifischen Aufrufe.

Vorgehen:

  1. Python 3 installieren von python.org/downloads (beim Setup „Add python.exe to PATH“ ankreuzen).
  2. modbus.py und modbus_w.py in einen beliebigen Ordner herunterladen.
  3. Eingabeaufforderung (cmd) oder PowerShell in diesem Ordner öffnen (z. B. Shift+Rechtsklick im Explorer → „PowerShell-Fenster hier öffnen“).
  4. Aufruf mit python statt python3 (unter Windows heißt das Kommando meist schlicht python, teils auch py):
python modbus.py 192.168.1.50 32104
python modbus_w.py 192.168.1.50 42010 2

Falls Windows das Kommando nicht findet: py -3 modbus.py 192.168.1.50 32104 probieren (der „py“-Launcher wird bei der Standard-Installation mitinstalliert).

Netzwerk-Voraussetzung (beide Systeme)

Ausgabe verstehen

modbus.py gibt Rohwert (dezimal + hex) und – für signed Register wie 30001 – zusätzlich den vorzeichenbehafteten Wert aus:

Register : 30001  [Holding FC3]  Slave: 1
Roh      : 65326  (0xFF2E)
Signed   : -210

modbus_w.py bestätigt den geschriebenen Wert per Geräte-Echo:

Register : 42010  Wert: 2  Slave: 1
OK — Register 42010 = 2

Häufig gestellte Fragen (FAQ)

Warum geht die Backup-Steckdose am Marstek Venus A von selbst aus?

Bei uns trat das nur auf, solange die lokale JSON-RPC-API des Akkus (UDP, Port 30000) aktiv war. Ist diese API eingeschaltet, kommt es zu unregelmäßigen Aussetzern und Fehlfunktionen – unter anderem schaltet sich die Backup-Steckdose eigenständig aus (siehe Kernerkenntnis oben). Nachdem wir die API deaktiviert und ausschließlich per Modbus TCP über LAN gesteuert haben, ist das Problem bei uns nicht mehr aufgetreten. Ein gesicherter Ursachennachweis ist das nicht, aber es passt zu allen bislang beobachteten Aussetzern.

Warum schaltet sich die Überschusseinspeisung am Marstek Venus A von selbst aus?

Bei uns trat das nur auf, solange die lokale JSON-RPC-API des Akkus (UDP, Port 30000, muss extra eingeschaltet werden) aktiv war. Ist diese API aktiv, kommt es zu unregelmäßigen Aussetzern und Fehlverhalten – unter anderem deaktiviert der Akku von selbst die Überschusseinspeisung, oft zusammen mit weiteren Symptomen wie einer ausgeschalteten Backup-Steckdose oder sich selbst einschaltenden LEDs, teils alles gleichzeitig, was insgesamt wie ein halber Reset oder Neustart wirkt. Mit aktiver API lief der Akku bei uns keine zwei Tage am Stück stabil. Nachdem wir die API komplett deaktiviert und den Akku stattdessen ausschließlich per Modbus TCP über ein LAN-Kabel angesteuert haben, ist das Problem nicht mehr aufgetreten (in unserem Test bislang mehrere Wochen ohne Aussetzer, Firmware-Version 149). Ein gesicherter Ursachennachweis ist das nicht – im Internet finden sich viele ähnliche Berichte über solche Aussetzer, aber kaum je eine Erklärung für die Ursache –, aber es passt zu allen bislang beobachteten Fehlfunktionen.

Warum schalten sich die LEDs am Marstek Venus A von selbst wieder an, obwohl sie ausgeschaltet waren?

Auch das trat bei uns ausschließlich auf, solange die lokale JSON-RPC-API des Akkus (UDP, Port 30000, muss extra eingeschaltet werden) aktiv war. Neben spontan wieder eingeschalteten LEDs kam es dabei zu weiteren unregelmäßigen Aussetzern – etwa schaltete sich die Backup-Steckdose von selbst aus, die Überschusseinspeisung wurde deaktiviert, oder die API selbst schaltete sich wieder ab –, teils alles gleichzeitig, was insgesamt wie ein halber Reset oder Neustart wirkte. Mit aktiver API lief der Akku bei uns keine zwei Tage am Stück stabil. Nachdem wir die API komplett deaktiviert und den Akku stattdessen ausschließlich per Modbus TCP über ein LAN-Kabel angesteuert haben, ist das Problem nicht mehr aufgetreten (in unserem Test bislang mehrere Wochen ohne Aussetzer, Firmware-Version 149). Ein gesicherter Ursachennachweis ist das nicht, aber es passt zu allen bislang beobachteten Fehlfunktionen.

Hat der Marstek Venus A Modbus?

Ja. Der Akku bietet Modbus TCP auf Port 502 – allerdings nur über die kabelgebundene LAN/Ethernet-Schnittstelle, nicht über WLAN. Die Implementierung ist zudem nicht vollständig standardkonform, weshalb handelsübliche Modbus-Software damit oft scheitert (Details). Wir haben deshalb ein eigenes, schlankes Python-Script (modbus.py) geschrieben, das genau mit diesen Abweichungen klarkommt und bei uns zuverlässig funktioniert – zum kostenlosen Download weiter unten auf dieser Seite, keine externen Modbus-Bibliotheken nötig. Die wichtigsten Register sind in der Register-Tabelle oben aufgeführt.

Beim Einschalten des Marstek Venus A leuchtet die Power-LED grün, aber die LED-Leiste vorne geht nicht an – was tun?

Das war bei uns ein Totalschaden. Der Akku ließ sich zwar einschalten (grüne Power-LED leuchtet), reagierte aber weder über die LED-Leiste an der Front noch über App oder Netzwerk – auch per App war er nicht erreichbar. Nach etwa einer Minute ging bei uns sogar die grüne Power-LED wieder aus. Eine Lösung, um das Gerät in diesem Zustand selbst wieder zum Laufen zu bringen, ist uns nicht bekannt – in unserem Fall half nur, den Support zu kontaktieren und das Gerät tauschen zu lassen.

Kann man die Entladetiefe des Marstek Venus A auf unter 12 % stellen?

Uns ist keine Möglichkeit bekannt, das in der App einstellbare Minimum von 12 % zu unterschreiten – und wir würden davon auch abraten. Bei den vermutlich verbauten LFP-Zellen (siehe Zellchemie-Einschätzung in den Battery-Stats-FAQ) gilt ein unterer Spannungs-Cutoff von ca. 2,8 V pro Zelle als üblicher, konservativ gewählter Sicherheitswert: Unterhalb davon flacht die Entladekurve stark ab, zwischen 2,8 V und 2,6 V steckt Erfahrungswerten zufolge nur noch rund 3 % der nutzbaren Kapazität. Wirklich kritisch – im Sinne von spürbaren Kapazitätsverlusten – wird es bei LFP-Zellen meist erst deutlich darunter, etwa ab 2,5 V, irreversible Schäden typischerweise erst unter 2,0 V pro Zelle; 2,8 V selbst ist also eher der Rand des Sicherheitspuffers als bereits der kritische Bereich. Dieser Puffer ist trotzdem sinnvoll, weil einzelne Zellen im Pack nie perfekt balanciert sind: Bei 12 % Pack-SOC kann eine schwächere Einzelzelle schon spürbar tiefer liegen als der Durchschnitt. Ein niedrigeres Limit würde diesen Sicherheitsabstand verkleinern, ohne nennenswert mehr nutzbare Energie zu bringen. Hinzu kommt: Bei uns springt der angezeigte SOC in diesem unteren Bereich gelegentlich sprunghaft, z. B. von 12 % auf 5 %, statt gleichmäßig zu sinken. Das ist ein bekanntes Symptom bei LFP-Zellen: Die Spannungskurve verläuft über weite Teile des Ladebereichs extrem flach, sodass das BMS den SOC dort kaum aus der Spannung ableiten kann und stattdessen auf Coulomb-Counting (Strom-Integration) angewiesen ist – ein Verfahren, das ohne regelmäßige Vollladung/-entladung zur Rekalibrierung mit der Zeit drifted. Genau im unteren Bereich, wo die Kurve wieder steiler wird, zeigt sich diese Ungenauigkeit dann als sprunghafte Korrektur. Ein zusätzlicher Grund, hier keinen Puffer zu verschenken, indem man die 12-%-Grenze künstlich weiter absenkt.

Welche Firmware-Version sollte man beim Marstek Venus A installieren?

Aus unserer Erfahrung sollte man mindestens Version 148 installiert haben. Version 149 verbessert danach noch ein paar Kleinigkeiten und ist die Version, mit der wir aktuell stabil per Modbus TCP laufen (siehe Kernerkenntnis oben). Version 150 gibt es inzwischen ebenfalls, die haben wir bislang aber noch nicht getestet – uns ist kein Weg bekannt, eine Firmware wieder zurückzustufen, falls sich mit 150 neue Probleme zeigen sollten, weshalb wir hier bewusst vorsichtig sind. Was sich zwischen den Versionen konkret ändert, ist reine Spekulation: Der Hersteller veröffentlicht keine Changelogs zu seinen Firmware-Updates, sodass man nur anhand des eigenen Nutzungsverhaltens raten kann, was besser oder anders geworden ist.