feat(batterie): Nachladeleistung begrenzen
Tests / test (push) Successful in 48s

This commit is contained in:
dh
2026-10-01 15:56:23 +00:00
parent 6cd7bf19f5
commit 8d83b083bf
9 changed files with 173 additions and 14 deletions
+11 -4
View File
@@ -82,19 +82,26 @@ Messwert, ist er veraltet oder liegt der Ladezustand ausserhalb von 0 bis
ReserveLadezustand entspricht der bisherigen Peakshaving-Reserve.
MindestLadezustand schuetzt vor weiterer Entladung.
LadezustandHysterese ersetzt die bisher fest im Code hinterlegte
2-Prozent-Hysterese.
2-Prozent-Hysterese. NachladenMitMaximalleistung verwendet standardmaessig die
dynamische maximale Ladeleistung. Wird der Schalter deaktiviert, begrenzt
MaximaleNachladeleistung das schutzbedingte Nachladen in W. Der wirksame Wert
wird nie hoeher als die dynamische Ladegrenze der Batterie.
Die bisherigen betriebsartabhaengigen Angebote bleiben erhalten:
- Im PV-Betrieb steht oberhalb der Reserve der durchgaengige Bereich von der
maximalen Entlade- bis zur maximalen Ladeleistung zur Verfuegung.
- Unterhalb der Reserve wird die maximale Ladeleistung als fester Wert angeboten.
- Unterhalb der Reserve wird die wirksame Nachladeleistung als fester Wert
angeboten.
- Bei vollem Speicher wird der durchgaengige Bereich von der maximalen
Entladeleistung bis 0 W angeboten.
- Im Peakbetrieb wird oberhalb der Reserve der aus Netz- und aktueller
Batterieleistung berechnete Entladewert angeboten.
- Innerhalb der Reserve-Hysterese und unterhalb des Mindestladezustands werden
Laden und Entladen wie bisher eingeschraenkt.
Laden und Entladen wie bisher eingeschraenkt; die positive Grenze ist dabei
hoechstens die konfigurierte Nachladeleistung.
- Oberhalb der Reserve ohne aktive Hysterese bleibt der normale Ladebereich
unveraendert und wird nicht durch die Nachladegrenze reduziert.
## Manager und Zeitverhalten
@@ -133,7 +140,7 @@ verwirft die aktuelle Vorgabe und schreibt eine Leistung von 0.
1. Batterietyp und Steuerung auswaehlen.
2. Alle fuenf Messwertvariablen zuordnen.
3. Die automatisch eingeblendeten Registervariablen zuordnen.
4. Reserve, Mindestladezustand und Hysterese pruefen.
4. Reserve, Mindestladezustand, Hysterese und Nachladeleistung pruefen.
5. Diagnosevariablen und Logging fuer die Erstinbetriebnahme aktivieren.
6. Die Batterie im Manager zuordnen.
7. Aktiv einschalten.
+14
View File
@@ -137,6 +137,20 @@
"minimum": 0,
"maximum": 100,
"digits": 1
},
{
"type": "CheckBox",
"name": "NachladenMitMaximalleistung",
"caption": "Beim Nachladen maximale Ladeleistung verwenden",
"onChange": "IPS_RequestAction($id, 'FormNachladenMitMaximalleistung', $NachladenMitMaximalleistung);"
},
{
"type": "NumberSpinner",
"name": "MaximaleNachladeleistung",
"caption": "Maximale Nachladeleistung",
"suffix": " W",
"minimum": 1,
"visible": false
}
]
},
+47 -2
View File
@@ -86,6 +86,8 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
$this->RegisterPropertyFloat('ReserveLadezustand', 20.0);
$this->RegisterPropertyFloat('MindestLadezustand', 10.0);
$this->RegisterPropertyFloat('LadezustandHysterese', 2.0);
$this->RegisterPropertyBoolean('NachladenMitMaximalleistung', true);
$this->RegisterPropertyInteger('MaximaleNachladeleistung', 0);
$this->RegisterPropertyInteger('MesswertMaxAlter', 60);
$this->RegisterPropertyInteger('Aenderungssperre', 4);
$this->RegisterPropertyBoolean('DiagnosevariablenAnzeigen', false);
@@ -185,6 +187,11 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
$formular['elements'],
$this->ReadPropertyInteger('Batterietyp')
);
$this->setzeFormfeldSichtbar(
$formular['elements'],
'MaximaleNachladeleistung',
!$this->ReadPropertyBoolean('NachladenMitMaximalleistung')
);
return json_encode($formular, JSON_THROW_ON_ERROR);
}
@@ -251,6 +258,14 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
$this->aktualisiereFormRegisterfelder((int) $wert);
return;
case 'FormNachladenMitMaximalleistung':
$this->UpdateFormField(
'MaximaleNachladeleistung',
'visible',
!(bool) $wert
);
return;
case 'ManagerdatenEmpfangen':
if (!is_string($wert)) {
throw new InvalidArgumentException(
@@ -382,7 +397,10 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
$messwerte['Netzleistung'],
$messwerte['Istleistung'],
$messwerte['MaxLaden'],
$messwerte['MaxEntladen']
$messwerte['MaxEntladen'],
$this->ReadPropertyBoolean('NachladenMitMaximalleistung')
? null
: (float) $this->ReadPropertyInteger('MaximaleNachladeleistung')
)
: [0];
@@ -776,6 +794,14 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
}
}
if (!$this->ReadPropertyBoolean('NachladenMitMaximalleistung')
&& $this->ReadPropertyInteger('MaximaleNachladeleistung') <= 0
) {
throw new InvalidArgumentException(
'MaximaleNachladeleistung muss groesser als 0 W sein.'
);
}
BatterieRegler::hystereseAktiv(
50.0,
$this->ReadPropertyFloat('ReserveLadezustand'),
@@ -793,7 +819,10 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
0.0,
0.0,
1.0,
1.0
1.0,
$this->ReadPropertyBoolean('NachladenMitMaximalleistung')
? null
: (float) $this->ReadPropertyInteger('MaximaleNachladeleistung')
);
foreach (self::MESSWERT_PROPERTIES as $property) {
@@ -1096,6 +1125,22 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
$this->setzeZustand('Stoertext', $text);
}
/** @param array<int, mixed> $elemente */
private function setzeFormfeldSichtbar(
array &$elemente,
string $name,
bool $sichtbar
): void {
foreach ($elemente as &$element) {
if (($element['name'] ?? '') === $name) {
$element['visible'] = $sichtbar;
}
if (isset($element['items']) && is_array($element['items'])) {
$this->setzeFormfeldSichtbar($element['items'], $name, $sichtbar);
}
}
}
/** @param array<int, mixed> $elemente */
private function setzeRegisterfelderSichtbar(
array &$elemente,