Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d83b083bf | ||
|
|
6cd7bf19f5 |
+11
-4
@@ -82,19 +82,26 @@ Messwert, ist er veraltet oder liegt der Ladezustand ausserhalb von 0 bis
|
|||||||
ReserveLadezustand entspricht der bisherigen Peakshaving-Reserve.
|
ReserveLadezustand entspricht der bisherigen Peakshaving-Reserve.
|
||||||
MindestLadezustand schuetzt vor weiterer Entladung.
|
MindestLadezustand schuetzt vor weiterer Entladung.
|
||||||
LadezustandHysterese ersetzt die bisher fest im Code hinterlegte
|
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:
|
Die bisherigen betriebsartabhaengigen Angebote bleiben erhalten:
|
||||||
|
|
||||||
- Im PV-Betrieb steht oberhalb der Reserve der durchgaengige Bereich von der
|
- Im PV-Betrieb steht oberhalb der Reserve der durchgaengige Bereich von der
|
||||||
maximalen Entlade- bis zur maximalen Ladeleistung zur Verfuegung.
|
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
|
- Bei vollem Speicher wird der durchgaengige Bereich von der maximalen
|
||||||
Entladeleistung bis 0 W angeboten.
|
Entladeleistung bis 0 W angeboten.
|
||||||
- Im Peakbetrieb wird oberhalb der Reserve der aus Netz- und aktueller
|
- Im Peakbetrieb wird oberhalb der Reserve der aus Netz- und aktueller
|
||||||
Batterieleistung berechnete Entladewert angeboten.
|
Batterieleistung berechnete Entladewert angeboten.
|
||||||
- Innerhalb der Reserve-Hysterese und unterhalb des Mindestladezustands werden
|
- 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
|
## Manager und Zeitverhalten
|
||||||
|
|
||||||
@@ -133,7 +140,7 @@ verwirft die aktuelle Vorgabe und schreibt eine Leistung von 0.
|
|||||||
1. Batterietyp und Steuerung auswaehlen.
|
1. Batterietyp und Steuerung auswaehlen.
|
||||||
2. Alle fuenf Messwertvariablen zuordnen.
|
2. Alle fuenf Messwertvariablen zuordnen.
|
||||||
3. Die automatisch eingeblendeten Registervariablen 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.
|
5. Diagnosevariablen und Logging fuer die Erstinbetriebnahme aktivieren.
|
||||||
6. Die Batterie im Manager zuordnen.
|
6. Die Batterie im Manager zuordnen.
|
||||||
7. Aktiv einschalten.
|
7. Aktiv einschalten.
|
||||||
|
|||||||
@@ -137,6 +137,20 @@
|
|||||||
"minimum": 0,
|
"minimum": 0,
|
||||||
"maximum": 100,
|
"maximum": 100,
|
||||||
"digits": 1
|
"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
@@ -86,6 +86,8 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
|
|||||||
$this->RegisterPropertyFloat('ReserveLadezustand', 20.0);
|
$this->RegisterPropertyFloat('ReserveLadezustand', 20.0);
|
||||||
$this->RegisterPropertyFloat('MindestLadezustand', 10.0);
|
$this->RegisterPropertyFloat('MindestLadezustand', 10.0);
|
||||||
$this->RegisterPropertyFloat('LadezustandHysterese', 2.0);
|
$this->RegisterPropertyFloat('LadezustandHysterese', 2.0);
|
||||||
|
$this->RegisterPropertyBoolean('NachladenMitMaximalleistung', true);
|
||||||
|
$this->RegisterPropertyInteger('MaximaleNachladeleistung', 0);
|
||||||
$this->RegisterPropertyInteger('MesswertMaxAlter', 60);
|
$this->RegisterPropertyInteger('MesswertMaxAlter', 60);
|
||||||
$this->RegisterPropertyInteger('Aenderungssperre', 4);
|
$this->RegisterPropertyInteger('Aenderungssperre', 4);
|
||||||
$this->RegisterPropertyBoolean('DiagnosevariablenAnzeigen', false);
|
$this->RegisterPropertyBoolean('DiagnosevariablenAnzeigen', false);
|
||||||
@@ -185,6 +187,11 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
|
|||||||
$formular['elements'],
|
$formular['elements'],
|
||||||
$this->ReadPropertyInteger('Batterietyp')
|
$this->ReadPropertyInteger('Batterietyp')
|
||||||
);
|
);
|
||||||
|
$this->setzeFormfeldSichtbar(
|
||||||
|
$formular['elements'],
|
||||||
|
'MaximaleNachladeleistung',
|
||||||
|
!$this->ReadPropertyBoolean('NachladenMitMaximalleistung')
|
||||||
|
);
|
||||||
|
|
||||||
return json_encode($formular, JSON_THROW_ON_ERROR);
|
return json_encode($formular, JSON_THROW_ON_ERROR);
|
||||||
}
|
}
|
||||||
@@ -251,6 +258,14 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
|
|||||||
$this->aktualisiereFormRegisterfelder((int) $wert);
|
$this->aktualisiereFormRegisterfelder((int) $wert);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case 'FormNachladenMitMaximalleistung':
|
||||||
|
$this->UpdateFormField(
|
||||||
|
'MaximaleNachladeleistung',
|
||||||
|
'visible',
|
||||||
|
!(bool) $wert
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
|
||||||
case 'ManagerdatenEmpfangen':
|
case 'ManagerdatenEmpfangen':
|
||||||
if (!is_string($wert)) {
|
if (!is_string($wert)) {
|
||||||
throw new InvalidArgumentException(
|
throw new InvalidArgumentException(
|
||||||
@@ -382,7 +397,10 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
|
|||||||
$messwerte['Netzleistung'],
|
$messwerte['Netzleistung'],
|
||||||
$messwerte['Istleistung'],
|
$messwerte['Istleistung'],
|
||||||
$messwerte['MaxLaden'],
|
$messwerte['MaxLaden'],
|
||||||
$messwerte['MaxEntladen']
|
$messwerte['MaxEntladen'],
|
||||||
|
$this->ReadPropertyBoolean('NachladenMitMaximalleistung')
|
||||||
|
? null
|
||||||
|
: (float) $this->ReadPropertyInteger('MaximaleNachladeleistung')
|
||||||
)
|
)
|
||||||
: [0];
|
: [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(
|
BatterieRegler::hystereseAktiv(
|
||||||
50.0,
|
50.0,
|
||||||
$this->ReadPropertyFloat('ReserveLadezustand'),
|
$this->ReadPropertyFloat('ReserveLadezustand'),
|
||||||
@@ -793,7 +819,10 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
|
|||||||
0.0,
|
0.0,
|
||||||
0.0,
|
0.0,
|
||||||
1.0,
|
1.0,
|
||||||
1.0
|
1.0,
|
||||||
|
$this->ReadPropertyBoolean('NachladenMitMaximalleistung')
|
||||||
|
? null
|
||||||
|
: (float) $this->ReadPropertyInteger('MaximaleNachladeleistung')
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach (self::MESSWERT_PROPERTIES as $property) {
|
foreach (self::MESSWERT_PROPERTIES as $property) {
|
||||||
@@ -1096,6 +1125,22 @@ class Batterie extends IPSModule implements VerbraucherSchnittstelle
|
|||||||
$this->setzeZustand('Stoertext', $text);
|
$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 */
|
/** @param array<int, mixed> $elemente */
|
||||||
private function setzeRegisterfelderSichtbar(
|
private function setzeRegisterfelderSichtbar(
|
||||||
array &$elemente,
|
array &$elemente,
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ Alle wesentlichen Aenderungen an Enelix EMS werden in dieser Datei dokumentiert.
|
|||||||
- Ladestationen halten beim Aktivieren und Umschalten von Solarladen den bisherigen Strom bis zur neuen Manager-Vorgabe; die Stand-alone-Phasenprobe verwendet nur noch 6 A.
|
- Ladestationen halten beim Aktivieren und Umschalten von Solarladen den bisherigen Strom bis zur neuen Manager-Vorgabe; die Stand-alone-Phasenprobe verwendet nur noch 6 A.
|
||||||
- Fahrzeugstatus ist bei beiden Ladestationsvarianten eine Diagnosevariable, Ist- und Sollleistung gehoeren zu den optionalen Visualisierungseinstellungen.
|
- Fahrzeugstatus ist bei beiden Ladestationsvarianten eine Diagnosevariable, Ist- und Sollleistung gehoeren zu den optionalen Visualisierungseinstellungen.
|
||||||
- Stufenlose Leistungsbereiche fuer Batteriespeicher.
|
- Stufenlose Leistungsbereiche fuer Batteriespeicher.
|
||||||
|
- Schutzbedingtes Nachladen der Batterie kann wahlweise auf die dynamische Maximalleistung oder eine benutzerdefinierte Watt-Grenze begrenzt werden.
|
||||||
- Ladefreigabe neuer Ladestationsinstanzen standardmaessig aktiviert.
|
- Ladefreigabe neuer Ladestationsinstanzen standardmaessig aktiviert.
|
||||||
- Stand-alone-Ladestationen erkennen nach einer einstellbaren Beobachtungszeit den niedrigeren Fahrzeug-Maximalstrom und begrenzen ihr Leistungsangebot ohne Ladeunterbruch.
|
- Stand-alone-Ladestationen erkennen nach einer einstellbaren Beobachtungszeit den niedrigeren Fahrzeug-Maximalstrom und begrenzen ihr Leistungsangebot ohne Ladeunterbruch.
|
||||||
- Easee-Ladestationen laden einen fehlenden Initialstatus ueber die Observations-API nach und starten bei noch unbekannter Ausgangsphase konservativ einphasig.
|
- Easee-Ladestationen laden einen fehlenden Initialstatus ueber die Observations-API nach und starten bei noch unbekannter Ausgangsphase konservativ einphasig.
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ EinstellungenInVisu und LoggingEin stammen aus VerbraucherBasisTrait.
|
|||||||
| ReserveLadezustand | Float | 20 | Peakshaving-Reserve in Prozent |
|
| ReserveLadezustand | Float | 20 | Peakshaving-Reserve in Prozent |
|
||||||
| MindestLadezustand | Float | 10 | Untere Entladegrenze in Prozent |
|
| MindestLadezustand | Float | 10 | Untere Entladegrenze in Prozent |
|
||||||
| LadezustandHysterese | Float | 2 | Hysterese oberhalb der Reserve |
|
| LadezustandHysterese | Float | 2 | Hysterese oberhalb der Reserve |
|
||||||
|
| NachladenMitMaximalleistung | Boolean | true | Verwendet fuer schutzbedingtes Nachladen die dynamische maximale Ladeleistung |
|
||||||
|
| MaximaleNachladeleistung | Integer | 0 | Benutzerdefinierte Nachladegrenze in W; bei deaktivierter Maximalleistung muss der Wert groesser als 0 sein |
|
||||||
| MesswertMaxAlter | Integer | 60 | Maximales Messwertalter in Sekunden |
|
| MesswertMaxAlter | Integer | 60 | Maximales Messwertalter in Sekunden |
|
||||||
| Aenderungssperre | Integer | 4 | Sperrzeit nach Sollwertaenderung |
|
| Aenderungssperre | Integer | 4 | Sperrzeit nach Sollwertaenderung |
|
||||||
| DiagnosevariablenAnzeigen | Boolean | false | Technische Variablen einblenden |
|
| DiagnosevariablenAnzeigen | Boolean | false | Technische Variablen einblenden |
|
||||||
@@ -81,9 +83,12 @@ wird.
|
|||||||
|
|
||||||
PV und Peak verwenden weiterhin die bisherige SoC-Logik. Feste Schutz- oder
|
PV und Peak verwenden weiterhin die bisherige SoC-Logik. Feste Schutz- oder
|
||||||
Peakvorgaben bleiben Einzelwerte; frei regelbare Angebote werden als Bereiche
|
Peakvorgaben bleiben Einzelwerte; frei regelbare Angebote werden als Bereiche
|
||||||
gemeldet. Die Hysterese wird als persistenter Modulzustand gefuehrt. Bei
|
gemeldet. Bei schutzbedingtem Nachladen innerhalb oder unterhalb der Reserve
|
||||||
Wechselrichtersteuerung, lokaler Deaktivierung oder ungueltigen Messwerten
|
begrenzt MaximaleNachladeleistung die positive Angebotsgrenze, wenn
|
||||||
lautet das Angebot [0].
|
NachladenMitMaximalleistung deaktiviert ist. Der normale Ladebereich oberhalb
|
||||||
|
der Reserve bleibt unveraendert. Die Hysterese wird als persistenter Modulzustand
|
||||||
|
gefuehrt. Bei Wechselrichtersteuerung, lokaler Deaktivierung oder ungueltigen
|
||||||
|
Messwerten lautet das Angebot [0].
|
||||||
|
|
||||||
## Variablen
|
## Variablen
|
||||||
|
|
||||||
|
|||||||
+10
-5
@@ -52,7 +52,8 @@ final class BatterieRegler
|
|||||||
float $netzleistungW,
|
float $netzleistungW,
|
||||||
float $istleistungW,
|
float $istleistungW,
|
||||||
float $maxLadenW,
|
float $maxLadenW,
|
||||||
float $maxEntladenW
|
float $maxEntladenW,
|
||||||
|
?float $maxNachladenW = null
|
||||||
): array {
|
): array {
|
||||||
self::pruefeLadezustandsgrenzen($reserve, 0.0);
|
self::pruefeLadezustandsgrenzen($reserve, 0.0);
|
||||||
if ($minimum < 0.0 || $minimum > 100.0 || $minimum > $reserve) {
|
if ($minimum < 0.0 || $minimum > 100.0 || $minimum > $reserve) {
|
||||||
@@ -61,12 +62,16 @@ final class BatterieRegler
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
self::pruefeLeistungsgrenzen($maxLadenW, $maxEntladenW);
|
self::pruefeLeistungsgrenzen($maxLadenW, $maxEntladenW);
|
||||||
|
if ($maxNachladenW !== null && $maxNachladenW < 0.0) {
|
||||||
|
throw new InvalidArgumentException('Maximale Nachladeleistung darf nicht negativ sein.');
|
||||||
|
}
|
||||||
|
|
||||||
if (!$aktiv || !$enelixSteuert) {
|
if (!$aktiv || !$enelixSteuert) {
|
||||||
return [0];
|
return [0];
|
||||||
}
|
}
|
||||||
|
|
||||||
$maxLaden = (int) floor($maxLadenW);
|
$maxLaden = (int) floor($maxLadenW);
|
||||||
|
$maxNachladen = (int) floor(min($maxLadenW, $maxNachladenW ?? $maxLadenW));
|
||||||
$maxEntladen = (int) floor($maxEntladenW);
|
$maxEntladen = (int) floor($maxEntladenW);
|
||||||
if ($peakbetrieb) {
|
if ($peakbetrieb) {
|
||||||
if ($ladezustand > $reserve && !$hystereseAktiv) {
|
if ($ladezustand > $reserve && !$hystereseAktiv) {
|
||||||
@@ -80,10 +85,10 @@ final class BatterieRegler
|
|||||||
return self::leistungsbereich(-$maxEntladen, 0);
|
return self::leistungsbereich(-$maxEntladen, 0);
|
||||||
}
|
}
|
||||||
if ($ladezustand > $minimum) {
|
if ($ladezustand > $minimum) {
|
||||||
return self::leistungsbereich(-$maxEntladen, $maxLaden);
|
return self::leistungsbereich(-$maxEntladen, $maxNachladen);
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::leistungsbereich(0, $maxLaden);
|
return self::leistungsbereich(0, $maxNachladen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($ladezustand > 99.0) {
|
if ($ladezustand > 99.0) {
|
||||||
@@ -93,10 +98,10 @@ final class BatterieRegler
|
|||||||
return self::leistungsbereich(-$maxEntladen, $maxLaden);
|
return self::leistungsbereich(-$maxEntladen, $maxLaden);
|
||||||
}
|
}
|
||||||
if ($ladezustand >= $reserve && $hystereseAktiv) {
|
if ($ladezustand >= $reserve && $hystereseAktiv) {
|
||||||
return self::leistungsbereich(0, $maxLaden);
|
return self::leistungsbereich(0, $maxNachladen);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [$maxLaden];
|
return [$maxNachladen];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -83,6 +83,30 @@ final class BatterieModulstrukturTest extends TestCase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testNachladebegrenzungIstImFormularKonfigurierbar(): void
|
||||||
|
{
|
||||||
|
$modul = (string) file_get_contents(self::MODULPFAD . 'module.php');
|
||||||
|
$formular = (string) file_get_contents(self::MODULPFAD . 'form.json');
|
||||||
|
|
||||||
|
self::assertStringContainsString(
|
||||||
|
"RegisterPropertyBoolean('NachladenMitMaximalleistung', true)",
|
||||||
|
$modul
|
||||||
|
);
|
||||||
|
self::assertStringContainsString(
|
||||||
|
"RegisterPropertyInteger('MaximaleNachladeleistung', 0)",
|
||||||
|
$modul
|
||||||
|
);
|
||||||
|
self::assertStringContainsString(
|
||||||
|
"'FormNachladenMitMaximalleistung'",
|
||||||
|
$formular
|
||||||
|
);
|
||||||
|
self::assertStringContainsString(
|
||||||
|
'"name": "MaximaleNachladeleistung"',
|
||||||
|
$formular
|
||||||
|
);
|
||||||
|
self::assertStringContainsString('"suffix": " W"', $formular);
|
||||||
|
}
|
||||||
|
|
||||||
public function testLoggingDiagnoseUndAktionsbuttonsSindVorhanden(): void
|
public function testLoggingDiagnoseUndAktionsbuttonsSindVorhanden(): void
|
||||||
{
|
{
|
||||||
$modul = (string) file_get_contents(self::MODULPFAD . 'module.php');
|
$modul = (string) file_get_contents(self::MODULPFAD . 'module.php');
|
||||||
|
|||||||
@@ -82,6 +82,38 @@ final class BatterieReglerTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testNachladeleistungBegrenztNurSchutzbedingtesLaden(): void
|
||||||
|
{
|
||||||
|
self::assertSame(
|
||||||
|
[400],
|
||||||
|
BatterieRegler::leistungsangebot(
|
||||||
|
true, true, false, 19.0, 20.0, 10.0, true,
|
||||||
|
0.0, 0.0, 1000.0, 1000.0, 400.0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
self::assertSame(
|
||||||
|
[['Von_W' => 0, 'Bis_W' => 400]],
|
||||||
|
BatterieRegler::leistungsangebot(
|
||||||
|
true, true, true, 10.0, 20.0, 10.0, true,
|
||||||
|
0.0, 0.0, 1000.0, 1000.0, 400.0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
self::assertSame(
|
||||||
|
[['Von_W' => -1000, 'Bis_W' => 400]],
|
||||||
|
BatterieRegler::leistungsangebot(
|
||||||
|
true, true, true, 15.0, 20.0, 10.0, true,
|
||||||
|
0.0, 0.0, 1000.0, 1000.0, 400.0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
self::assertSame(
|
||||||
|
[['Von_W' => -1000, 'Bis_W' => 1000]],
|
||||||
|
BatterieRegler::leistungsangebot(
|
||||||
|
true, true, false, 50.0, 20.0, 10.0, false,
|
||||||
|
0.0, 0.0, 1000.0, 1000.0, 400.0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testWechselrichtersteuerungBietetNurNull(): void
|
public function testWechselrichtersteuerungBietetNurNull(): void
|
||||||
{
|
{
|
||||||
self::assertSame(
|
self::assertSame(
|
||||||
|
|||||||
@@ -163,6 +163,32 @@ PHP
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$test->runCase(
|
||||||
|
'Benutzerdefinierte Nachladeleistung begrenzt das Schutzangebot',
|
||||||
|
static function (TestContext $test) use (
|
||||||
|
$batterieID,
|
||||||
|
$ladezustandID,
|
||||||
|
$managerdatenSenden
|
||||||
|
): void {
|
||||||
|
$test->configureInstance($batterieID, [
|
||||||
|
'Batteriemanagement' => 2,
|
||||||
|
'NachladenMitMaximalleistung' => false,
|
||||||
|
'MaximaleNachladeleistung' => 400,
|
||||||
|
]);
|
||||||
|
IPS_RequestAction($batterieID, 'Aktiv', true);
|
||||||
|
SetValue($ladezustandID, 19.0);
|
||||||
|
$managerdatenSenden('PV', null);
|
||||||
|
|
||||||
|
$angebotID = $test->objectByIdent('LeistungsangebotDiagnose', $batterieID);
|
||||||
|
$test->waitUntil(
|
||||||
|
static fn (): bool => json_decode(
|
||||||
|
(string) GetValue($angebotID),
|
||||||
|
true
|
||||||
|
) === [400]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
$test->runCase(
|
$test->runCase(
|
||||||
'Wechselrichtersteuerung setzt Leistung auf null und Automatikmodus',
|
'Wechselrichtersteuerung setzt Leistung auf null und Automatikmodus',
|
||||||
static function (TestContext $test) use (
|
static function (TestContext $test) use (
|
||||||
|
|||||||
@@ -209,10 +209,25 @@ return static function (TestContext $test): void {
|
|||||||
'Sollleistung_W' => $leistung,
|
'Sollleistung_W' => $leistung,
|
||||||
], JSON_THROW_ON_ERROR));
|
], JSON_THROW_ON_ERROR));
|
||||||
};
|
};
|
||||||
|
$warteAufGeraetebefehl = static function (
|
||||||
|
int $stationId,
|
||||||
|
string $urlTeil
|
||||||
|
) use ($test): string {
|
||||||
|
$deadline = microtime(true) + 3.0;
|
||||||
|
do {
|
||||||
|
$befehl = (string) GetValue($test->objectByIdent('LetzterGeraetebefehl', $stationId));
|
||||||
|
if (str_contains($befehl, $urlTeil)) {
|
||||||
|
return $befehl;
|
||||||
|
}
|
||||||
|
IPS_Sleep(50);
|
||||||
|
} while (microtime(true) < $deadline);
|
||||||
|
|
||||||
|
return $befehl;
|
||||||
|
};
|
||||||
|
|
||||||
$test->runCase('Alle drei Geraetevarianten erkennen Fahrzeug und Phasen', static function (
|
$test->runCase('Alle drei Geraetevarianten erkennen Fahrzeug und Phasen', static function (
|
||||||
TestContext $test
|
TestContext $test
|
||||||
) use ($definitionen, $stationen): void {
|
) use ($definitionen, $stationen, $warteAufGeraetebefehl): void {
|
||||||
foreach ($stationen as $name => $stationId) {
|
foreach ($stationen as $name => $stationId) {
|
||||||
IPS_RequestAction($stationId, 'Aktiv', true);
|
IPS_RequestAction($stationId, 'Aktiv', true);
|
||||||
$test->assertSame(true, GetValue($test->objectByIdent('FahrzeugVerbunden', $stationId)));
|
$test->assertSame(true, GetValue($test->objectByIdent('FahrzeugVerbunden', $stationId)));
|
||||||
@@ -222,7 +237,10 @@ return static function (TestContext $test): void {
|
|||||||
);
|
);
|
||||||
$test->assertSame(false, GetValue($test->objectByIdent('FahrzeugGeladen', $stationId)));
|
$test->assertSame(false, GetValue($test->objectByIdent('FahrzeugGeladen', $stationId)));
|
||||||
IPS_RequestAction($stationId, 'Solarladen', false);
|
IPS_RequestAction($stationId, 'Solarladen', false);
|
||||||
$befehl = (string) GetValue($test->objectByIdent('LetzterGeraetebefehl', $stationId));
|
$befehl = $warteAufGeraetebefehl(
|
||||||
|
$stationId,
|
||||||
|
$definitionen[$name]['BefehlUrlTeil']
|
||||||
|
);
|
||||||
$diagnose = json_encode([
|
$diagnose = json_encode([
|
||||||
'Aktiv' => GetValue($test->objectByIdent('Aktiv', $stationId)),
|
'Aktiv' => GetValue($test->objectByIdent('Aktiv', $stationId)),
|
||||||
'Ladefreigabe' => GetValue($test->objectByIdent('Ladefreigabe', $stationId)),
|
'Ladefreigabe' => GetValue($test->objectByIdent('Ladefreigabe', $stationId)),
|
||||||
|
|||||||
Reference in New Issue
Block a user