fix(ladestation): Regeluebergaenge stabilisieren
Tests / test (push) Successful in 50s

This commit is contained in:
dh
2026-10-01 13:01:32 +00:00
parent 8357e8dfab
commit 3ce9af4244
11 changed files with 427 additions and 119 deletions
+119 -59
View File
@@ -28,17 +28,17 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
private const STATUS_GATEWAY_GETRENNT = 202;
private const STATUS_WARTET_AUF_DATEN = 203;
private const STATUS_LADEFEHLER = 204;
private const REGELUEBERGANG_TIMEOUT_MS = 2000;
/** @var list<string> */
private const DIAGNOSE_VARIABLEN = [
'Istleistung',
'Leistungsquelle',
'Sollleistung',
'SollwertGueltig',
'Verfuegbar',
'AenderungMoeglich',
'Stoerung',
'Stoertext',
'Fahrzeugstatus',
'GatewayVerbunden',
'ApiMaximalstrom',
'EaseeAktiviert',
@@ -75,7 +75,6 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
'~Switch',
110
);
$this->RegisterVariableInteger('Fahrzeugstatus', 'Fahrzeugstatus', '', 120);
$this->RegisterVariableFloat('Ladestrom', 'Ladestrom', '', 130);
$this->RegisterVariableInteger('Phasenzahl', 'Phasenzahl', '', 140);
@@ -113,6 +112,7 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
$this->RegisterAttributeBoolean('LadestartFuerVerbindungGesendet', false);
$this->RegisterAttributeString('LetzterGeraetebefehl', '');
$this->RegisterAttributeString('LetzterStartbefehl', '');
$this->RegisterAttributeBoolean('RegeluebergangAktiv', false);
$this->RegisterTimer(
'Meldezyklus',
@@ -129,6 +129,11 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
0,
"IPS_RequestAction(\$_IPS['TARGET'], 'VorgabeTimeout', false);"
);
$this->RegisterTimer(
'RegeluebergangTimeout',
0,
"IPS_RequestAction(\$_IPS['TARGET'], 'RegeluebergangTimeout', false);"
);
$this->ConnectParent(self::EASEE_GATEWAY_MODULE_ID);
}
@@ -142,6 +147,7 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
$this->WriteAttributeBoolean('GatewayVerbunden', false);
$this->WriteAttributeInteger('LetzterGesetzterStrom', -1);
$this->WriteAttributeBoolean('LadestartFuerVerbindungGesendet', false);
$this->beendeRegeluebergang();
try {
$this->pruefeKonfiguration();
@@ -167,17 +173,27 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
{
switch ($ident) {
case 'Aktiv':
$this->SetValue('Aktiv', (bool) $wert);
if (!(bool) $wert) {
$aktiv = (bool) $wert;
$this->SetValue('Aktiv', $aktiv);
if ($aktiv) {
$this->starteRegeluebergang();
} else {
$this->beendeRegeluebergang();
$this->setzeZustand('SollwertGueltig', false);
}
$this->aktualisiere(true);
return;
case 'Ladefreigabe':
$this->WriteAttributeBoolean('ZustandLadefreigabe', (bool) $wert);
$this->setzeSichtbareVariable('Ladefreigabe', (bool) $wert);
$this->setzeZustand('SollwertGueltig', false);
$ladefreigabe = (bool) $wert;
$this->WriteAttributeBoolean('ZustandLadefreigabe', $ladefreigabe);
$this->setzeSichtbareVariable('Ladefreigabe', $ladefreigabe);
if ($ladefreigabe) {
$this->starteRegeluebergang();
} else {
$this->beendeRegeluebergang();
$this->setzeZustand('SollwertGueltig', false);
}
$this->aktualisiere(true);
return;
@@ -185,9 +201,11 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
$solarladen = EaseeLadestatus::solarladenErzwungen(
$this->ReadPropertyInteger('Betriebsmodus')
) ? true : (bool) $wert;
if ($solarladen !== $this->ReadAttributeBoolean('ZustandSolarladen')) {
$this->starteRegeluebergang();
}
$this->WriteAttributeBoolean('ZustandSolarladen', $solarladen);
$this->setzeSichtbareVariable('Solarladen', $solarladen);
$this->setzeZustand('SollwertGueltig', false);
$this->aktualisiere(true);
return;
@@ -201,6 +219,11 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
$this->aktualisiere(true);
return;
case 'RegeluebergangTimeout':
$this->beendeRegeluebergang();
$this->aktualisiere(true);
return;
case 'Melden':
if ((bool) $wert) {
$this->SetTimerInterval('RueckmeldungVerzoegert', 0);
@@ -288,7 +311,7 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
}
$this->WriteAttributeString('Betriebsart', $daten['Betriebsart']);
$this->aktualisiere(false);
$this->aktualisiere(false, false);
$sollleistung = $daten['Sollleistung_W'];
if ($sollleistung === null) {
if (
@@ -311,6 +334,7 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
);
}
$this->beendeRegeluebergang();
$this->WriteAttributeInteger('LetzteManagerID', $managerID);
$this->WriteAttributeInteger('LetzteVorgabeZeit', time());
$this->setzeZustand('Sollleistung', $sollleistung);
@@ -405,7 +429,10 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
$this->WriteAttributeInteger('LetzteBeobachtung', $zeitpunkt);
}
private function aktualisiere(bool $meldungPlanen): void
private function aktualisiere(
bool $meldungPlanen,
bool $steuerungAusfuehren = true
): void
{
try {
$status = EaseeLadestatus::ausBeobachtungen(
@@ -493,12 +520,21 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
}
$this->setzeStoerung($stoertext);
$regeluebergangAktiv = (bool) $this->GetValue('Aktiv')
&& $this->ReadAttributeBoolean('ZustandLadefreigabe')
&& $steuerbar
&& $status['FahrzeugVerbunden']
&& !$status['FahrzeugGeladen']
&& $this->ReadAttributeBoolean('RegeluebergangAktiv');
if ($gatewayVerbunden && $status['StatusGueltig']) {
$this->setzeLadestrom(
$this->bestimmeWirksameSollleistung($angebot),
$regelPhasenzahl,
$status['Fahrzeugstatus'] === 2
);
$sollleistung = $this->bestimmeWirksameSollleistung($angebot);
if ($steuerungAusfuehren && !$regeluebergangAktiv) {
$this->setzeLadestrom(
$sollleistung,
$regelPhasenzahl,
$status['Fahrzeugstatus'] === 2
);
}
} else {
$this->WriteAttributeInteger('LetzterGesetzterStrom', -1);
}
@@ -797,6 +833,23 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
return is_array($zuordnung) ? $zuordnung : [];
}
private function starteRegeluebergang(): void
{
if ($this->zugeordneteManagerIDs() === []) {
$this->beendeRegeluebergang();
return;
}
$this->WriteAttributeBoolean('RegeluebergangAktiv', true);
$this->SetTimerInterval('RegeluebergangTimeout', self::REGELUEBERGANG_TIMEOUT_MS);
}
private function beendeRegeluebergang(): void
{
$this->WriteAttributeBoolean('RegeluebergangAktiv', false);
$this->SetTimerInterval('RegeluebergangTimeout', 0);
}
private function pruefeKonfiguration(): void
{
foreach (['PrioritaetPV', 'PrioritaetPeak'] as $property) {
@@ -857,95 +910,63 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
private function aktualisiereVariablen(): void
{
if ($this->ReadPropertyBoolean('EinstellungenInVisu')) {
$this->RegisterVariableBoolean(
'Ladefreigabe',
'Ladefreigabe',
'~Switch',
150
);
$this->RegisterVariableBoolean(
'Solarladen',
'Solarladen',
'~Switch',
160
);
$this->EnableAction('Ladefreigabe');
$this->EnableAction('Solarladen');
$this->SetValue(
'Ladefreigabe',
$this->ReadAttributeBoolean('ZustandLadefreigabe')
);
$this->SetValue(
'Solarladen',
$this->ReadAttributeBoolean('ZustandSolarladen')
);
} else {
$this->entferneVariable('Ladefreigabe');
$this->entferneVariable('Solarladen');
}
if ($this->ReadPropertyBoolean('DiagnosevariablenAnzeigen')) {
$this->registriereVerbraucherDiagnose();
$this->RegisterVariableInteger('Fahrzeugstatus', 'Fahrzeugstatus', '', 200);
$this->RegisterVariableBoolean(
'GatewayVerbunden',
'Easee Gateway verbunden',
'~Switch',
200
);
$this->RegisterVariableInteger(
'ApiMaximalstrom',
'API-Maximalstrom',
'',
210
);
$this->RegisterVariableInteger('ApiMaximalstrom', 'API-Maximalstrom', '', 220);
$this->RegisterVariableBoolean(
'EaseeAktiviert',
'Easee aktiviert',
'~Switch',
220
230
);
$this->RegisterVariableBoolean(
'AutorisierungErforderlich',
'Autorisierung erforderlich',
'~Switch',
230
240
);
$this->RegisterVariableBoolean(
'RemoteStartErforderlich',
'Remote-Start erforderlich',
'~Switch',
240
250
);
$this->RegisterVariableBoolean(
'SmartCharging',
'Easee Smart Charging',
'~Switch',
250
260
);
$this->RegisterVariableInteger(
'GrundKeinLadestrom',
'Grund kein Ladestrom',
'',
260
270
);
$this->RegisterVariableString(
'LetzterGeraetebefehl',
'Letzter Geraetebefehl',
'',
270
280
);
$this->RegisterVariableString(
'LetzterStartbefehl',
'Letzter Startbefehl',
'',
280
290
);
$this->RegisterVariableString(
'LeistungsangebotDiagnose',
'Leistungsangebot',
'',
290
300
);
$this->SetValue(
'LeistungsangebotDiagnose',
@@ -983,6 +1004,40 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
$this->entferneVariable($ident);
}
}
if ($this->ReadPropertyBoolean('EinstellungenInVisu')) {
$this->RegisterVariableBoolean(
'Ladefreigabe',
'Ladefreigabe',
'~Switch',
150
);
$this->RegisterVariableBoolean(
'Solarladen',
'Solarladen',
'~Switch',
160
);
$this->RegisterVariableFloat('Istleistung', 'Istleistung', '', 170);
$this->RegisterVariableInteger('Sollleistung', 'Sollleistung', '', 180);
$this->EnableAction('Ladefreigabe');
$this->EnableAction('Solarladen');
$this->SetValue(
'Ladefreigabe',
$this->ReadAttributeBoolean('ZustandLadefreigabe')
);
$this->SetValue(
'Solarladen',
$this->ReadAttributeBoolean('ZustandSolarladen')
);
$this->SetValue('Istleistung', $this->ReadAttributeFloat('ZustandIstleistung'));
$this->SetValue('Sollleistung', $this->ReadAttributeInteger('ZustandSollleistung'));
} else {
$this->entferneVariable('Ladefreigabe');
$this->entferneVariable('Solarladen');
$this->entferneVariable('Istleistung');
$this->entferneVariable('Sollleistung');
}
}
private function entferneVariable(string $ident): void
@@ -1108,7 +1163,12 @@ class LadestationGateway extends IPSModule implements VerbraucherSchnittstelle
private function deaktiviereTimer(): void
{
foreach (['Meldezyklus', 'RueckmeldungVerzoegert', 'VorgabeTimeout'] as $timer) {
foreach ([
'Meldezyklus',
'RueckmeldungVerzoegert',
'VorgabeTimeout',
'RegeluebergangTimeout',
] as $timer) {
$this->SetTimerInterval($timer, 0);
}
}