feat: Batteriemodul ereignisbasiert integrieren
Tests / test (push) Successful in 45s

This commit is contained in:
dh
2026-09-22 09:27:49 +00:00
parent d03a7fd8fb
commit d7308663da
18 changed files with 2670 additions and 51 deletions
+110
View File
@@ -0,0 +1,110 @@
# Schnittstelle Batterie
Diese Beschreibung ergaenzt den allgemeinen
[Manager-Verbraucher-Vertrag](Schnittstelle.md) fuer das Batteriemodul.
Vertragsversion ist 4.0.
## Manager an Batterie
Die Batterie empfaengt den unveraenderten gemeinsamen Datensatz:
~~~json
{
"Kopf": {
"Version": "4.0",
"AbsenderID": 10001,
"EmpfaengerID": 20001,
"Zeitpunkt": 1788825600
},
"Betriebsart": "PV",
"Sollleistung_W": -1500
}
~~~
Sollleistung_W verwendet folgende Semantik:
- positiver Wert: Batterie laden
- negativer Wert: Batterie entladen
- 0: Leistungsregister auf 0 setzen
- null: nur Betriebsart synchronisieren und neues Angebot anfordern
Ein konkreter Wert muss im zuletzt fuer dieselbe Betriebsart gemeldeten
Leistungsangebot enthalten sein. Waehren der Aenderungssperre wird nur die
Wiederholung des aktuellen Sollwerts akzeptiert.
## Batterie an Manager
Die Batterie verwendet alle Pflichtfelder des gemeinsamen Vertrags und
ergaenzt folgende Zustandseintraege:
| Kennung | Art | Typ | Einheit | Bedeutung |
| --- | --- | --- | --- | --- |
| Sollleistung_W | Sollwert | Integer oder null | W | Aktuell gueltige Manager-Vorgabe |
| Ladezustand_Prozent | Istwert | Float oder null | % | Physischer SoC |
| HystereseAktiv | Status | Boolean | - | Reserve-Hysterese ist aktiv |
| Batteriesteuerung | Status | Integer | - | 1 Wechselrichter, 2 Enelix |
| Messwertfehler | Stoerung | Boolean | - | Pflichtmesswert fehlt oder ist ungueltig |
| Registerfehler | Stoerung | Boolean | - | Mindestens ein Schreibbefehl ist fehlgeschlagen |
Beispiel:
~~~json
{
"Kopf": {
"Version": "4.0",
"AbsenderID": 20001,
"EmpfaengerID": 10001,
"Zeitpunkt": 1788825602
},
"Betriebsart": "Peak",
"PrioritaetPV": 0,
"PrioritaetPeak": 0,
"Leistungswerte_W": [-1500],
"AenderungMoeglich": true,
"Verfuegbar": true,
"Istleistung_W": -250.0,
"Leistungsquelle": 2,
"Zustand": [
{
"Kennung": "Sollleistung_W",
"Art": "Sollwert",
"Wert": -1500,
"Einheit": "W"
},
{
"Kennung": "Ladezustand_Prozent",
"Art": "Istwert",
"Wert": 54.2,
"Einheit": "%"
}
]
}
~~~
Ist die Leistungsmessung ungueltig, wird Istleistung_W als null und
Leistungsquelle als 0 gemeldet. Bei einem gueltigen Messwert ist
Leistungsquelle 2.
## Ereignisse
Das Modul registriert VM_UPDATE fuer:
- maximale Ladeleistung
- maximale Entladeleistung
- Ladezustand
- Netzleistung
- aktuelle Batterieleistung
Jede Aktualisierung berechnet Zustand und Angebot neu und plant eine
gebuendelte Rueckmeldung. Registerwerte werden nur geschrieben, wenn sich der
resultierende Befehl geaendert hat.
## Registerausgang
Der technische Ausgang besteht aus ausgewaehlten numerischen
IP-Symcon-Variablen. Das Modul verwendet RequestAction und setzt diese
Variablen nicht mit SetValue. Damit bleibt der jeweilige Modbus-, Skript- oder
Geraeteadapter fuer die konkrete Registerkommunikation verantwortlich.
Die genaue Herstellerabbildung steht in der
[Moduldokumentation](module/Batterie/README.md).
+8
View File
@@ -132,6 +132,14 @@ Symcon-Datenpunkte registriert `VerbraucherBasisTrait`.
`Leistungswerte_W`, `Betriebsart` und `Zustand` werden intern gehalten
und direkt in die Nachricht geschrieben.
## Batteriespezifische Erweiterung
Die Batterie verwendet denselben Vertrag 4.0 und ergaenzt Zustandseintraege
fuer Ladezustand, Hysterese, Steuerungsmodus, Messwertfehler und
Registerfehler. Positive Leistung bedeutet Laden, negative Leistung
Entladen. Die vollstaendige Semantik und Registeranbindung beschreibt die
[Schnittstelle Batterie](Schnittstelle-Batterie.md).
## Easee-Gateway-Transport
Der technische JSON-Vertrag zwischen `EaseeGateway` und
+67
View File
@@ -0,0 +1,67 @@
# Migration Batterie aus Enelix 1
## Ziel
Die bisherige Batterie wird als Enelix-2-Verbraucher auf Vertrag 4.0
umgestellt. Das alte Repository bleibt unveraendert und dient nur als
Verhaltensreferenz.
## Uebernommen
- positive Sollleistung fuer Laden und negative Sollleistung fuer Entladen
- dynamische maximale Lade- und Entladeleistung aus Variablen
- Ladezustand, Netzleistung und aktuelle Batterieleistung als Eingaben
- 250-W-Grundraster und 50-W-Feinwerte um 0
- Reserve-, Mindestladezustands- und Hystereselogik
- getrennte Angebote fuer PV und Peak
- Wechselrichter- oder Enelix-Steuerung
- Registercodes fuer generisch, GoodWe, SolarEdge und Sigenergy
- Aufsummierung der bezogenen Energie
## Angepasst
| Enelix 1 | Enelix 2 |
| --- | --- |
| zyklischer Timer Do_UserCalc | Messwert- und Managerereignisse |
| IdleCounter in Zyklen | Aenderungssperre in Sekunden mit Einmaltimer |
| PowerSteps als Modulvariable | Leistungswerte_W direkt im Vertrag |
| interne Stellwertvariablen | ausgewaehlte Registervariablen mit RequestAction |
| fest verdrahtete Herstellerhilfsvariablen | dynamisch sichtbare Registerauswahl |
| fest codierte 2-%-Hysterese | Property LadezustandHysterese |
| berechnete Istleistung | gemessene Istleistung, Leistungsquelle 2 |
| Interval-basierte Energie | Zeitintegration zwischen Ereignissen und Vollmeldungen |
| Is_Peak_Shaving als Variable | Betriebsart PV oder Peak im Vertrag 4.0 |
## Neu implementiert
- Validierung aller Mess- und Registervariablen
- Pflichtaktion auf jeder Zielregistervariable
- Messwertalter und sicherer Zustand bei ungueltigen Messwerten
- Sollwert-Timeout
- Diagnosevariablen, Registerfehlerstatus und Debug-Logging
- standardisierte PHPUnit- und Symcon-8.0-Laufzeittests
- explizite Schnittstellenbeschreibung
## Verworfen
- direkter SetValue-Aufruf auf internen Leistungs- und Modusvariablen
- zyklische Regelung mit frei konfigurierbarem Interval
- doppelte Peak-/PV-Codepfade mit identischer Registerabbildung
- ungenutzte Batteriespannungsproperty
- CheckIdle mit globalem GetValue ohne Objekt-ID
## Umstellung einer Anlage
1. Bestehende Batterieinstanz und alle bisherigen Variablen-IDs dokumentieren.
2. Sicherung der IP-Symcon-Konfiguration erstellen.
3. Neue Enelix-2-Batterieinstanz anlegen.
4. Fuenf Messwertvariablen zuordnen.
5. Batterietyp waehlen und die eingeblendeten Registervariablen zuordnen.
6. Reserve, Mindestladezustand und Aenderungssperre uebertragen.
7. Neue Batterie im Enelix-2-Manager zuordnen.
8. Diagnose und Logging aktivieren.
9. Laden, Entladen, 0 W und Wechselrichtermodus unter Aufsicht testen.
10. Alte Instanz erst nach erfolgreicher Feldpruefung deaktivieren.
Ein automatisches Loeschen oder Ueberschreiben der alten Instanz findet nicht
statt.
+109 -47
View File
@@ -1,59 +1,121 @@
# Batterie
> Status: Diskussionsentwurf. Positiv bedeutet Laden, negativ Entladen.
> Status: implementiert. Zielplattform ist IP-Symcon ab Version 8.0,
> Nachrichtenvertrag 4.0.
Die Auswahl des Batterietyps bestimmt den Adapter und die sichtbaren
Anschlussfelder. Ohne Logging bleibt von den zusätzlichen Variablen nur
`Ladestatus` sichtbar.
## Verantwortung
## Zusätzliche Variablen
Das Modul bildet einen Batteriespeicher als bidirektionalen Enelix-Verbraucher
ab. Es berechnet das betriebsart- und ladezustandsabhaengige
Leistungsangebot, empfaengt Sollleistungen vom Manager und uebersetzt sie in
herstellerspezifische Registerwerte.
| Ident | Typ / Zugriff | Beschreibung |
| --- | --- | --- |
| `Ladestatus` | Integer / Anzeige | `0` unbekannt, `1` ruhend, `2` laden, `3` entladen. |
| `Ladezustand` | Float / Logging | Physischer Ladezustand in %. |
| `LadezustandGueltig` | Boolean / Logging | Gültigkeit unabhängig von der Leistungsmessung. |
| `Steuerungsmodus` | Integer / lokal bedienbar | `0` Batterie, `1` Manager, `2` Virtuelle Batterie führt. |
| `NotnachladungAktiv` | Boolean / Logging | Aus Ladezustand ermittelter lokaler Bedarf. |
| `LadeleistungVerfuegbar` | Float / Logging | Aktuell nutzbare Ladeleistung in W. |
| `EntladeleistungVerfuegbar` | Float / Logging | Aktuell nutzbare Entladeleistung als positiver Betrag in W. |
| `MaxLadeleistung` | Float / lokal bedienbar | Wirksamer Parameter in W. |
| `MaxEntladeleistung` | Float / lokal bedienbar | Wirksamer Parameter in W. |
| `Mindestladezustand` | Float / lokal bedienbar | Wirksamer Parameter in %. |
| `Maximalladezustand` | Float / lokal bedienbar | Wirksamer Parameter in %. |
| `Nachladeschwelle` | Float / lokal bedienbar | Wirksamer Parameter in %. |
| `Nachladehysterese` | Float / lokal bedienbar | Wirksamer Parameter in %. |
| `Notnachladeleistung` | Float / lokal bedienbar | `0` deaktiviert; sonst Leistung in W. |
Positive Leistung bedeutet Laden, negative Leistung Entladen. Die
Geraeteanbindung erfolgt ausschliesslich ueber vom Benutzer ausgewaehlte
numerische IP-Symcon-Variablen. Schreibziele muessen eine Aktion besitzen.
## Zusätzliche Properties
## Ereignismodell
| Ident | Typ | Standard / Beschreibung |
| --- | --- | --- |
| `MaxLadeleistung` | Float | `0*` W; einzige einstellbare obere Ladegrenze. |
| `MaxEntladeleistung` | Float | `0` W; einzige einstellbare obere Entladegrenze. |
| `Mindestladezustand` | Float | `0*` %; Bereich 0–100. |
| `Maximalladezustand` | Float | `100` %; grösser als Mindestladezustand. |
| `Nachladeschwelle` | Float | `0*` %; zwischen Mindest- und Maximalladezustand. |
| `Nachladehysterese` | Float | `2` %; Schwelle plus Hysterese höchstens Maximalladezustand. |
| `Notnachladeleistung` | Float | `0` W; sonst höchstens MaxLadeleistung. |
| `Batterietyp` | Auswahl | `Unkonfiguriert`, `Herstellerunabhaengig`, `Goodwe`, `SolarEdge`, `SigEnergy`. |
| `BatterieInstanzID` | Integer | `0`; für kompatible Herstelleradapter. |
| `LadezustandVariableID` | Integer | `0`; nur herstellerunabhängig. |
| `IstleistungVariableID` | Integer | `0`; nur herstellerunabhängig. |
| `SollleistungVariableID` | Integer | `0`; nur herstellerunabhängig, vorzeichenbehaftet in W. |
| `LadezustandMaxAlter` | Integer | `60` s; Aktualität des Ladezustands. |
| `VirtuelleBatterieID` | Integer | `0`; Pflicht bei Steuerungsmodus 2. |
Fachliche Neuberechnungen werden ausgeloest durch:
Anschlussart, Batteriespannung, Gerätezuordnung, Leistungsschritt,
Sollwertquelle und externe Sollwerte entfallen.
- Aktualisierung eines der fuenf Messwerte
- Managerdaten mit Betriebsart oder Sollleistung
- lokale Aenderung der Variablen Aktiv
- Ablauf von Vorgabe-Timeout oder Aenderungssperre
- manuelle Aktualisierung in der Konfigurationsmaske
## Zustand
Der Meldezyklus verschickt eine Vollmeldung und dient nicht als Regelzyklus.
Ein periodischer Berechnungstimer oder Idle-Counter existiert nicht.
`Ladezustand_Prozent` als Istwert; `Steuerungsmodus` und
`NotnachladungAktiv` als Status; `LadezustandFehlt` und `Geraetefehler` als
Störungen.
## Properties
## Offene Punkte
### Gemeinsame Verbraucherproperties
- Michis konkrete Fehlerliste nachliefern und gegen den Entwurf prüfen.
- Datenpunkte und Leistungsgrenzen der drei Herstelleradapter verifizieren.
PrioritaetPV, PrioritaetPeak, Meldeintervall, VorgabeTimeout,
EinstellungenInVisu und LoggingEin stammen aus VerbraucherBasisTrait.
### Batteriespezifische Properties
| Property | Typ | Standard | Bedeutung |
| --- | --- | ---: | --- |
| Batterietyp | Integer | 0 | 0 unkonfiguriert, 1 generisch, 2 GoodWe, 3 SolarEdge, 4 Sigenergy |
| Batteriemanagement | Integer | 1 | 1 Wechselrichter, 2 Enelix |
| MaxLadeleistungVariableID | Integer | 0 | Dynamische Ladegrenze in W |
| MaxEntladeleistungVariableID | Integer | 0 | Dynamische Entladegrenze in W |
| LadezustandVariableID | Integer | 0 | SoC in Prozent |
| NetzleistungVariableID | Integer | 0 | Positiv Netzbezug, negativ Einspeisung |
| IstleistungVariableID | Integer | 0 | Positiv Laden, negativ Entladen |
| ManagementRegisterVariableID | Integer | 0 | Steuerungsquelle des Wechselrichters |
| ModusRegisterVariableID | Integer | 0 | Laden-/Entladen-Code |
| LeistungsRegisterVariableID | Integer | 0 | GoodWe-Leistungsregister in W |
| LadeleistungRegisterVariableID | Integer | 0 | Ladeleistung in W beziehungsweise kW |
| EntladeleistungRegisterVariableID | Integer | 0 | Entladeleistung in W beziehungsweise kW |
| ReserveLadezustand | Float | 20 | Peakshaving-Reserve in Prozent |
| MindestLadezustand | Float | 10 | Untere Entladegrenze in Prozent |
| LadezustandHysterese | Float | 2 | Hysterese oberhalb der Reserve |
| MesswertMaxAlter | Integer | 60 | Maximales Messwertalter in Sekunden |
| Aenderungssperre | Integer | 4 | Sperrzeit nach Sollwertaenderung |
| DiagnosevariablenAnzeigen | Boolean | false | Technische Variablen einblenden |
## Registeradapter
| Typ | WR-Management | Enelix-Management | Laden | Entladen |
| --- | ---: | ---: | --- | --- |
| Generisch | 0 | 1 | Modus 0, Ladeleistung W | Modus 1, Entladeleistung W |
| GoodWe | 1 | 2 | Modus 11, Betrag W | Modus 12, Betrag W |
| SolarEdge | 1 | 4 | Modus 3, Ladeleistung W | Modus 4, Entladeleistung W |
| Sigenergy | 0 | 1 | Modus 3, Ladeleistung kW | Modus 6, Entladeleistung kW |
Beim Wechsel in die Wechselrichtersteuerung werden zuerst die zum Typ
gehoerenden Leistungsregister auf 0 gesetzt und danach der Automatikcode
geschrieben. Im Enelix-Modus werden zuerst die Leistungswerte, dann Modus und
zuletzt Management geschrieben.
## Leistungsangebot
Das Raster besteht wie in Enelix 1 aus 250-W-Grundschritten. Um 0 werden
zusaetzlich -200, -150, -100, -50, 0, 50, 100, 150 und 200 W angeboten,
soweit diese Werte innerhalb der dynamischen Leistungsgrenzen liegen.
PV und Peak verwenden die bisherige SoC-Logik. Die Hysterese wird als
persistenter Modulzustand gefuehrt. Bei Wechselrichtersteuerung, lokaler
Deaktivierung oder ungueltigen Messwerten lautet das Angebot [0].
## Variablen
Immer sichtbar sind Aktiv und Ladestatus. Ladestatus verwendet:
| Wert | Bedeutung |
| ---: | --- |
| 0 | Messwert ungueltig oder unbekannt |
| 1 | Ruhezustand |
| 2 | Laden |
| 3 | Entladen |
Die Diagnoseoption ergaenzt die gemeinsamen Verbraucherdiagnosen sowie
Ladezustand, Netzleistung, Leistungsgrenzen, Hysterese, Steuerungsmodus,
BezogeneEnergie, LeistungsangebotDiagnose und LetzterRegisterbefehl.
## Fehlerbehandlung
- Status 201: Konfiguration oder Variablentyp ungueltig
- Status 202: Messwert fehlt, ist veraltet oder fachlich ungueltig
- Status 203: RequestAction auf mindestens ein Register ist fehlgeschlagen
Ein ungueltiger oder abgelaufener Sollwert wird verworfen und durch 0 ersetzt.
Die konkrete Stoerung wird im Vertrag und bei aktivierter Diagnose in
Stoerung und Stoertext gemeldet.
## Managerkommunikation
Die fachliche Schnittstelle ist in
[Schnittstelle Batterie](../../Schnittstelle-Batterie.md) beschrieben.
Transport und gemeinsame Felder folgen
[EMS-Schnittstelle](../../Schnittstelle.md).
## Tests
- BatterieReglerTest: Raster, Hysterese, PV/Peak und Herstellerabbildung
- BatterieModulstrukturTest: Metadaten, Formular, Ereignismodell und Manager-ID
- Symcon/modules/Batterie.php: reale Modulinstanz und Registeraktionen unter
IP-Symcon 8.0
+2 -2
View File
@@ -1,6 +1,6 @@
# EMS-Module und Modulentwürfe
> Manager, Warmwassererwaermer, Verbraucher 1-Stufig, Ladestation Stand-Alone,
> Manager, Warmwassererwaermer, Batterie, Verbraucher 1-Stufig, Ladestation Stand-Alone,
> Easee Gateway und Ladestation Gateway sind als installierbare IP-Symcon-Module
> umgesetzt. Die weiteren Ordner enthalten Besprechungsgrundlagen.
@@ -11,7 +11,7 @@ nur zusätzliche Properties, Variablen, Zustände und offene Punkte.
| Modul | Rolle |
| --- | --- |
| [Manager](Manager/README.md) | Leistungsverteilung und Anschlüsse (implementiert) |
| [Batterie](Batterie/README.md) | Laden und Entladen eines Speichers |
| [Batterie](Batterie/README.md) | Laden und Entladen eines Speichers (implementiert) |
| [Wassererwärmer](Wassererwaermer/README.md) | Mehrstufige elektrische Erwärmung (implementiert) |
| [Pufferspeicher](Pufferspeicher/README.md) | Heizstufen nach Heizkurve |
| [Verbraucher 1-Stufig](Verbraucher-1-Stufig/README.md) | Ein-/Aus-Verbraucher (implementiert) |