fix(ladestation): Fahrzeugstrom nach Lernzeit begrenzen
Tests / test (push) Successful in 56s

This commit is contained in:
dh
2026-09-29 12:47:23 +00:00
parent b3b868cd2a
commit ace1821213
9 changed files with 247 additions and 21 deletions
+92 -3
View File
@@ -34,6 +34,7 @@ class LadestationStandAlone extends IPSModule implements VerbraucherSchnittstell
'AenderungMoeglich',
'Stoerung',
'Stoertext',
'FahrzeugMaximalstrom',
'LetzterGeraetebefehl',
'LeistungsangebotDiagnose',
];
@@ -50,6 +51,7 @@ class LadestationStandAlone extends IPSModule implements VerbraucherSchnittstell
$this->RegisterPropertyString('Benutzername', '');
$this->RegisterPropertyString('Passwort', '');
$this->RegisterPropertyInteger('MaximalerLadestrom', 16);
$this->RegisterPropertyInteger('FahrzeugstromErkennungszeit', 90);
$this->RegisterPropertyInteger('Abfrageintervall', 5);
$this->RegisterPropertyBoolean('Ladefreigabe', true);
$this->RegisterPropertyBoolean('Solarladen', true);
@@ -88,6 +90,9 @@ class LadestationStandAlone extends IPSModule implements VerbraucherSchnittstell
$this->RegisterAttributeInteger('LetzteVorgabeZeit', 0);
$this->RegisterAttributeInteger('LetzterGesetzterStrom', -1);
$this->RegisterAttributeBoolean('LadeleistungSeitFreigabeErkannt', false);
$this->RegisterAttributeInteger('ErkannterMaximalstrom', 32);
$this->RegisterAttributeInteger('FahrzeugstromKandidat', 0);
$this->RegisterAttributeInteger('FahrzeugstromKandidatSeit', 0);
$this->RegisterTimer(
'Statuszyklus',
@@ -122,6 +127,11 @@ class LadestationStandAlone extends IPSModule implements VerbraucherSchnittstell
$this->setzeZustand('FahrzeugGeladen', false);
$this->WriteAttributeInteger('LetzterGesetzterStrom', -1);
$this->WriteAttributeBoolean('LadeleistungSeitFreigabeErkannt', false);
$this->WriteAttributeInteger(
'ErkannterMaximalstrom',
$this->ReadPropertyInteger('MaximalerLadestrom')
);
$this->setzeFahrzeugstromKandidatZurueck();
try {
$this->pruefeKonfiguration();
@@ -245,7 +255,11 @@ class LadestationStandAlone extends IPSModule implements VerbraucherSchnittstell
$verbunden = $this->ReadAttributeBoolean('ZustandFahrzeugVerbunden');
$geladen = $this->ReadAttributeBoolean('ZustandFahrzeugGeladen');
$phasenzahl = $this->ReadAttributeInteger('ZustandPhasenzahl');
$maximalstrom = $this->ReadPropertyInteger('MaximalerLadestrom');
$maximalstrom = min(
$this->ReadPropertyInteger('MaximalerLadestrom'),
max(6, $this->ReadAttributeInteger('ErkannterMaximalstrom'))
);
$this->setzeSichtbareVariable('FahrzeugMaximalstrom', $maximalstrom);
$solarladen = $this->ReadAttributeBoolean('ZustandSolarladen');
$peakbetrieb = $this->ReadAttributeString('Betriebsart')
=== Nachrichtenvertrag::BETRIEBSART_PEAK;
@@ -317,12 +331,59 @@ class LadestationStandAlone extends IPSModule implements VerbraucherSchnittstell
} elseif ($status['Ladestrom_A'] >= 3.5) {
$this->WriteAttributeBoolean('LadeleistungSeitFreigabeErkannt', true);
}
$this->aktualisiereFahrzeugstromgrenze($status);
foreach ($status as $ident => $wert) {
$this->setzeZustand($ident, $wert);
}
}
/** @param array<string, int|float|bool> $status */
private function aktualisiereFahrzeugstromgrenze(array $status): void
{
$konfigurierterMaximalstrom = $this->ReadPropertyInteger('MaximalerLadestrom');
if (!$status['FahrzeugVerbunden']) {
$this->WriteAttributeInteger('ErkannterMaximalstrom', $konfigurierterMaximalstrom);
$this->setzeSichtbareVariable('FahrzeugMaximalstrom', $konfigurierterMaximalstrom);
$this->setzeFahrzeugstromKandidatZurueck();
return;
}
$kandidat = LadestationRegler::ermittleFahrzeugMaximalstrom(
$this->ReadAttributeInteger('LetzterGesetzterStrom'),
(float) $status['Ladestrom_A'],
$konfigurierterMaximalstrom
);
if ($kandidat === null
|| $kandidat >= $this->ReadAttributeInteger('ErkannterMaximalstrom')
) {
$this->setzeFahrzeugstromKandidatZurueck();
return;
}
$jetzt = time();
if ($this->ReadAttributeInteger('FahrzeugstromKandidat') !== $kandidat) {
$this->WriteAttributeInteger('FahrzeugstromKandidat', $kandidat);
$this->WriteAttributeInteger('FahrzeugstromKandidatSeit', $jetzt);
return;
}
if (($jetzt - $this->ReadAttributeInteger('FahrzeugstromKandidatSeit'))
< $this->ReadPropertyInteger('FahrzeugstromErkennungszeit')
) {
return;
}
$this->WriteAttributeInteger('ErkannterMaximalstrom', $kandidat);
$this->setzeSichtbareVariable('FahrzeugMaximalstrom', $kandidat);
$this->setzeFahrzeugstromKandidatZurueck();
}
private function setzeFahrzeugstromKandidatZurueck(): void
{
$this->WriteAttributeInteger('FahrzeugstromKandidat', 0);
$this->WriteAttributeInteger('FahrzeugstromKandidatSeit', 0);
}
/** @param list<int> $angebot */
private function bestimmeWirksameSollleistung(array $angebot): int
{
@@ -332,6 +393,14 @@ class LadestationStandAlone extends IPSModule implements VerbraucherSchnittstell
return $sollleistung;
}
$this->setzeZustand('SollwertGueltig', false);
$ersatz = 0;
foreach ($angebot as $leistungswert) {
if ($leistungswert > $sollleistung) {
break;
}
$ersatz = $leistungswert;
}
return $ersatz;
}
if (!$this->ReadAttributeBoolean('ZustandSolarladen') && $angebot !== [0]) {
@@ -351,6 +420,7 @@ class LadestationStandAlone extends IPSModule implements VerbraucherSchnittstell
return;
}
$this->WriteAttributeBoolean('LadeleistungSeitFreigabeErkannt', false);
$this->setzeFahrzeugstromKandidatZurueck();
$transport = new LadestationTransport(
fn (array $anfrage): string => $this->fuehreHttpAnfrageAus($anfrage)
@@ -586,7 +656,12 @@ class LadestationStandAlone extends IPSModule implements VerbraucherSchnittstell
throw new InvalidArgumentException($property . ' muss mindestens 0 sein.');
}
}
foreach (['Meldeintervall', 'VorgabeTimeout', 'Abfrageintervall'] as $property) {
foreach ([
'Meldeintervall',
'VorgabeTimeout',
'Abfrageintervall',
'FahrzeugstromErkennungszeit',
] as $property) {
if ($this->ReadPropertyInteger($property) <= 0) {
throw new InvalidArgumentException($property . ' muss groesser als 0 sein.');
}
@@ -642,12 +717,26 @@ class LadestationStandAlone extends IPSModule implements VerbraucherSchnittstell
$this->registriereVerbraucherDiagnose();
$this->RegisterVariableString('LetzterGeraetebefehl', 'Letzter Geraetebefehl', '', 200);
$this->RegisterVariableString('LeistungsangebotDiagnose', 'Leistungsangebot', '', 210);
$this->RegisterVariableInteger(
'FahrzeugMaximalstrom',
'Erkannter Fahrzeug-Maximalstrom',
'',
220
);
$this->SetValue(
'FahrzeugMaximalstrom',
$this->ReadAttributeInteger('ErkannterMaximalstrom')
);
$this->SetValue(
'LeistungsangebotDiagnose',
$this->ReadAttributeString('Leistungsangebot')
);
foreach (self::DIAGNOSE_VARIABLEN as $ident) {
if (!in_array($ident, ['LetzterGeraetebefehl', 'LeistungsangebotDiagnose'], true)) {
if (!in_array($ident, [
'LetzterGeraetebefehl',
'LeistungsangebotDiagnose',
'FahrzeugMaximalstrom',
], true)) {
$this->setzeSichtbareVariable($ident, $this->leseZustand($ident));
}
}