Marstek Modbus Suite 2.0: Ein eigenes Panel, das auch schreibt
Mit Version 2.0 bekommt die Marstek Modbus Suite eine eigene Seite in der Seitenleiste von Home Assistant, und sie schreibt jetzt auch: Leistung, Grenzwerte, Betriebsmodi und alle sechs Zeitpläne lassen sich dort setzen. Gebaut ist das in zehn Betas, in denen sich ein paar Annahmen als falsch herausstellten. Die interessantesten stehen weiter unten.
Das Panel
Sobald ein Speicher eingerichtet ist, erscheint ein Eintrag in der Seitenleiste. Es sind keine zusätzlichen Karten nötig, jedes Element wird von der Integration selbst mitgeliefert. Es gibt sieben Reiter: Übersicht mit dem Ladezustand als Doppelring (die Lücke zwischen den Ringen ist die Reserve), Zellen, Packs, Solar, Energie, Steuerung und System. Hinter dem Zahnrad liegen die Einstellungen.
Das Panel findet seine Werte über das Register hinter einer Entität, nicht über deren Namen. Wer ein Gerät umbenennt, einem anderen Bereich zuordnet oder die Sprache wechselt, lässt es damit nicht ins Leere laufen.

Die Zellenansicht beantwortet etwas, das eine Entitätsliste nicht kann. Das Gerät meldet ein Delta je Pack, aber nie eines über den ganzen Stapel. Ein Pack, das auf einem anderen Niveau liegt als seine Nachbarn, fällt in keiner Zahl auf – auf der gemeinsamen Achse ist es der Balken, der seitwärts gewandert ist. Ein schmaler Balken ist ein ausgeglichenes Pack, ein breiter Drift innerhalb des Packs.

Ein nutzbares Energiefenster
Bis 1.4.1 rechneten die Laufzeiten bis 0 und bis 100 Prozent. So betreibt niemand einen Speicher, deshalb wanderten beide Enden. Die Untergrenze ist eine Option je Eintrag unter Konfigurieren → Energiefenster, Standard 12 Prozent. Venus A, D und E v3 geben discharging_cutoff_capacity nicht heraus, die in der Marstek-App eingestellte Grenze lässt sich also nicht zurücklesen. Die Obergrenze liest die Integration aus charge_to_soc, aber nur, wenn dort ein Wert im eigenen Bereich 10 bis 100 steht. Eine Venus D unter externer Steuerung meldet dort eine glatte 0, was „Energie bis voll“ größer als den Speicher machen würde; so ein Wert wird als volle Ladung behandelt. Daraus entstehen usable_energy und energy_to_full.
Zwei Schwellen wurden gegen ein echtes Gerät korrigiert. Leerlauf gilt jetzt ab 30 W statt 5 W: Eine Venus D nimmt im Nichtstun rund 18 W auf, und die Division des Packs durch diesen Wert ergab eine Laufzeit von 637 Stunden, rechnerisch richtig und völlig nutzlos. Und die Obergrenze für Laufzeiten sinkt von 999 auf 48 Stunden, denn darüber ist es keine Prognose mehr, und drei Stellen suggerieren eine Genauigkeit, die nicht da ist.
Wenn Normalbetrieb wie ein Fehler aussieht
Der Speicher lädt und entlädt ein Pack nach dem anderen. Dabei liegen die Packs etwa zehn Prozentpunkte Ladezustand auseinander, ihre Zellen entsprechend auf unterschiedlicher Spannung. Das ist das Design, kein Defekt. Drei Anzeigen behandelten es trotzdem als Fehler, und das fiel erst beim Rendern gegen echte Messwerte auf:
- Die Pack-Spreizung warnte ab 5 Prozentpunkten, der Normalbetrieb stand dauerhaft auf Orange. Jetzt beginnt die Warnung bei 12, kritisch ab 20, die Skala reicht bis 25.
- Die Übersichtskachel meldete die Spreizung über den ganzen Stapel (höchste Zelle minus niedrigste Zelle) und bewertete sie gegen 100 mV, den Grenzwert für Zellen innerhalb eines Packs. Bei gestaffelten Packs ist „kritisch“ damit garantiert. Jetzt zeigt sie die größte Spreizung innerhalb eines einzelnen Packs und nennt es. Packs, die 160 mV gegeneinander versetzt, aber je für sich eng sind, lesen 8 mV und grün; ein Pack, das innen um 120 mV driftet, wird rot und beim Namen genannt.
- Die Packtabelle markierte jedes Pack mit mehr als 5 Punkten Abstand zum Median – bei zehn Punkten Versatz im Normalbetrieb zu jedem Zeitpunkt die halbe Tabelle.
- Ein Wert im MOSFET-Status ungleich null galt als Schutzfall. Das Gerät schließt aber die MOSFETs jeweils nur eines Packs, der Wert sagt schlicht, welches Pack gerade arbeitet. Er wird jetzt genau so gemeldet.
Der Median als Bezug ist Absicht: Ein einzelner Ausreißer zieht den Mittelwert zu sich und versteckt damit, dass er einer ist.
Die Reserve unterhalb der Entladegrenze
Im Normalbetrieb stoppt das Gerät an der eingestellten Entladegrenze, entlädt aber bei laufendem Off-Grid-Ausgang bis 8 Prozent weiter. Dieses Band war unsichtbar, denn usable_energy zählt nur bis zur Grenze. backup_reserve_energy zeigt es, auf Venus A und D, wo der Wert bestätigt ist; andere Modelle bekommen weder Sensor noch die zugehörigen Zeilen im Panel.
reserve = capacity × (min(SOC, floor) − 8) / 100Bei einem 17,9-kWh-Pack ergibt das 0,72 kWh bei 61 Prozent und bei 12 Prozent, 0,36 kWh bei 10 Prozent und 0 kWh bei 8 Prozent. Der Wert wird gemeldet, egal ob die Steckdose scharf geschaltet ist, denn eine Zahl, die genau dann auf null fällt, wenn man einen Ausfall plant, beantwortet nichts. Im Panel erscheint die Reserve in „Reserve · Lebensdauer“ und als gepunktete Linie unter der Entladegrenze in den Packsäulen.

Steuerung
Der Reiter schreibt Lade- und Entladeleistung, Leistungs- und SoC-Grenzen, Arbeits- und erzwungenen Modus, die Schalter für Backup und RS485, alle sechs Zeitpläne und einen bestätigten Neustart. Jedes Bedienelement liest seine Grenzen aus der Entität, deshalb stimmt derselbe Editor auf einer Venus A mit niedrigerem Limit wie auf einer Venus D mit 2500 W. Zeiten werden zwischen dem HHMM der Register und einem Uhrzeitfeld umgerechnet. Einen Werksreset gibt es hier bewusst nicht, er bleibt in der Entitätsliste. Ein Hinweis steht im Panel selbst: Alles, was den Speicher von außen regelt, schreibt dieselben Register und gewinnt binnen Sekunden – der Reiter sagt das, statt kaputt zu wirken.
In den Betas fiel auf, dass der Venus A in Leistungsfeldern und Zeitplänen bis 2500 W angeboten wurden, obwohl ihre tatsächliche Grenze deutlich darunter liegt.
Namen, die verschwinden, und ein Name, der bleibt
Die Seitenleiste verlor nach einem Update ihren Eintrag. Der Abbau hing an async_unload_entry, das Home Assistant bei jedem Neuladen und jeder Optionsänderung aufruft, nicht nur beim Löschen eines Speichers. Das Panel wurde also routinemäßig abgebaut und kam nur zurück, wenn das folgende Setup es wieder anlegte. Der Abbau sitzt jetzt in async_remove_entry, die Registrierung läuft außerhalb des Blocks, dessen except das gesamte Setup zurückrollt, und loggt auf Info statt Debug. Ein Seitenleisteneintrag ist es nicht wert, einen Speicher nicht zu laden.
In diesem Zug bekamen Pfad, Element und Bundle den Domainnamen als Präfix (/marstek-modbus, marstek-modbus-panel). Ein Custom-Element-Name gilt global auf der Seite: Würde eine andere Integration eine Datei mit demselben Namen ausliefern, wirft die zweite Definition einen Fehler und ein Panel bleibt leer, ohne dass irgendwo ein Fehler in der Nähe der Ursache steht.
Mit beta.6 heißt die Integration Marstek Modbus Suite, weil sie vier Registerkarten, Steuerung, Zeitpläne und ein Panel mitbringt. Die Domain bleibt marstek_modbus. Sie zu ändern würde jede Entity-ID und jeden Konfigurationseintrag ungültig machen – das wäre eine Migration, keine Umbenennung, und sie träfe Leute, die nie danach gefragt haben. Bestehende Einträge behalten ihren Titel, nur neu hinzugefügte Speicher tragen den neuen Namen. Das Repository heißt jetzt marstek-modbus-suite; alte Links leiten weiter, HACS folgt dem Repository über die ID.
Beim Update von 1.x
- Eine Entität behält die ID, unter der sie registriert wurde. Drei Pack-1-Sensoren (
battery_1_voltage,battery_1_current,battery_1_cycle_count) waren in der Registerdatei, aber nicht in den Übersetzungen. Home Assistant fand keinen Namen, und einer registrierte sich alssensor.<gerät>ganz ohne Suffix. Der Anzeigename stimmt nach dem Update, die ID nicht; umbenennen oder aus der Registry löschen und neu starten. grid_standardliefert Kleinbuchstaben (nur Venus E v1/v2): ausGermanywirdgermany, weil Home Assistant die alte Schreibweise nicht als Übersetzungsschlüssel akzeptiert. Automationen, die gegen den alten Wert vergleichen, müssen angepasst werden, der angezeigte Name ändert sich nicht.
Home Assistant muss komplett neu gestartet werden, ein Neuladen genügt nicht. Auf dem Telefon scrollte die Seite seitlich, weil Reiterleiste, Zeitplan-Editor und Packsäulen die Seite statt ihrer eigenen Box verbreiterten; unter 640 px werden die Zellbereiche jetzt als Text geschrieben statt auf einer zwei Zentimeter langen Achse gezeichnet. Ein Skript, scripts/check_translations.py, prüft in der CI, dass jede Entität jeder Registerdatei in allen Katalogen einen Namen hat. Das ist nötig, weil eine fehlende Übersetzung zur Laufzeit weder Fehler noch Logzeile erzeugt.
Zum Projekt
-
Marstek Modbus Suite
Home-Assistant-Integration für Marstek-Venus-Speicher über lokales Modbus TCP: ohne Cloud, mit eigenem Panel, Steuerung, Zeitplänen und Pack- und Zellansicht.
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.