no message

This commit is contained in:
dh
2026-08-25 15:36:10 +02:00
parent 21d14d52ed
commit 1526b48ef2
4 changed files with 82 additions and 54 deletions
+8 -4
View File
@@ -67,10 +67,14 @@ Iststrom mal `1.11`, wird der erreichbare Maximalstrom aus `Iststrom * 1.11`
gelernt und `PowerSteps` noch im selben Zyklus neu aufgebaut. Der Lernwert gelernt und `PowerSteps` noch im selben Zyklus neu aufgebaut. Der Lernwert
bleibt bis zum Ausstecken, einem neuen Fahrzeug oder einem Phasenwechsel aktiv. bleibt bis zum Ausstecken, einem neuen Fahrzeug oder einem Phasenwechsel aktiv.
Fällt der berechnete Wert bei Typ 1 bis 4 unter 6 A, wird Fällt der berechnete Wert unter 6 A, wird `Auto fertig geladen` gesetzt und
`Auto fertig geladen` gesetzt und nur `[0]` angeboten. Easee verwendet dafür nur `[0]` angeboten. Bei Easee gilt das nur bei verbundenem Gateway und
ausschließlich Observation 109. Eine Sollvorgabe von 0 W setzt die Zähler Fahrzeugstatus 4 oder 6: Das Modul muss dabei trotz positiver Sollvorgabe
zurück und kann weder eine Strombegrenzung noch ein Ladeende auslösen. 90 Sekunden lang einen Iststrom messen, der mit Faktor `1.11` unter 6 A
bleibt. Status 4 oder 6 allein wird nicht als Ladeende gewertet. Eine
Sollvorgabe von 0 W setzt die Zähler zurück und kann weder eine
Strombegrenzung noch ein Ladeende auslösen. Das bestätigte Ladeende bleibt bis
zum Ausstecken gespeichert.
Beim Update bestehender Instanzen wird die frühere Eigenschaft `Token_Easee` Beim Update bestehender Instanzen wird die frühere Eigenschaft `Token_Easee`
aus Kompatibilitätsgründen intern beibehalten, aber nicht mehr verwendet oder aus Kompatibilitätsgründen intern beibehalten, aber nicht mehr verwendet oder
+33 -23
View File
@@ -531,10 +531,18 @@ class Ladestation extends IPSModule
return in_array($stationType, [1, 2, 3, 4, 5, 6], true); return in_array($stationType, [1, 2, 3, 4, 5, 6], true);
} }
private function HasReliableFullStatus(int $stationType): bool private function CanUseAdaptiveFullDetection(int $stationType): bool
{ {
// Easee meldet das Ladeende eindeutig über Observation 109. if (!$this->UsesEaseeGateway($stationType)) {
return in_array($stationType, [5, 6], true); return true;
}
// Easee-Status 4 bedeutet "pausiert/gestoppt", Status 6 bedeutet,
// dass die Station auf eine Stromaufnahme des Fahrzeugs wartet. Beide
// sind nur zusammen mit positivem Soll und einer 90 Sekunden lang
// bestätigten, zu geringen Stromaufnahme ein Ladeende-Kandidat.
return $this->GetValue("Easee_Gateway_Connected") &&
in_array((int)$this->GetValue("Fahrzeugstatus"), [4, 6], true);
} }
private function SetAdaptiveReferenceMaxCurrent(float $apiMaxCurrent): float private function SetAdaptiveReferenceMaxCurrent(float $apiMaxCurrent): float
@@ -669,6 +677,13 @@ class Ladestation extends IPSModule
$actualPower = abs( $actualPower = abs(
(float)$this->GetValue("Ladeleistung_Effektiv") (float)$this->GetValue("Ladeleistung_Effektiv")
); );
// Ohne messbaren Strom ist keine Phasenerkennung möglich. Vor allem
// darf eine Ladepause die zuletzt bekannte Phase nicht auf 1-phasig
// umschalten. Die Ladeende-Erkennung läuft separat weiter.
if ($actualPower < 100.0) {
return false;
}
$onePhaseExpectedPower = $requestedCurrent * 230.0; $onePhaseExpectedPower = $requestedCurrent * 230.0;
$threePhaseExpectedPower = $requestedCurrent * 1.71 * 400.0; $threePhaseExpectedPower = $requestedCurrent * 1.71 * 400.0;
$isOnePhase = $actualPower < $isOnePhase = $actualPower <
@@ -687,7 +702,7 @@ class Ladestation extends IPSModule
($actualPower / $phaseDivisor); ($actualPower / $phaseDivisor);
if ( if (
$detectedCurrent < 6.0 && $detectedCurrent < 6.0 &&
!$this->HasReliableFullStatus($stationType) $this->CanUseAdaptiveFullDetection($stationType)
) { ) {
$this->SetBuffer( $this->SetBuffer(
"AdaptiveLearnedMaxCurrent", "AdaptiveLearnedMaxCurrent",
@@ -710,14 +725,18 @@ class Ladestation extends IPSModule
0.0, 0.0,
(float)$this->GetValue("Aktuelle_Leistung") (float)$this->GetValue("Aktuelle_Leistung")
); );
$actualPower = abs(
(float)$this->GetValue("Ladeleistung_Effektiv")
);
$hasKnownPhase = $stationType === 4 ||
$this->GetBuffer("AdaptivePhaseKnown") === "1";
$canEvaluate = $this->UsesAdaptiveCurrentDetection($stationType) && $canEvaluate = $this->UsesAdaptiveCurrentDetection($stationType) &&
$ladebereit && $ladebereit &&
$this->GetValue("Car_detected") && $this->GetValue("Car_detected") &&
!$this->GetValue("Car_is_full") && !$this->GetValue("Car_is_full") &&
$this->GetValue("Idle") && $this->GetValue("Idle") &&
($stationType === 4 || ($hasKnownPhase || $actualPower < 100.0) &&
$this->GetBuffer("AdaptivePhaseKnown") === "1") &&
$requestedPower > 0 && $requestedPower > 0 &&
$this->IsAdaptiveChargingEnabled($stationType) && $this->IsAdaptiveChargingEnabled($stationType) &&
$this->HasFreshAdaptiveMeasurement($stationType); $this->HasFreshAdaptiveMeasurement($stationType);
@@ -729,9 +748,7 @@ class Ladestation extends IPSModule
$phaseDivisor = $this->GetValue("Is_1_ph") ? 230.0 : 1.71 * 400.0; $phaseDivisor = $this->GetValue("Is_1_ph") ? 230.0 : 1.71 * 400.0;
$requestedCurrent = $requestedPower / $phaseDivisor; $requestedCurrent = $requestedPower / $phaseDivisor;
$actualCurrent = abs( $actualCurrent = $actualPower / $phaseDivisor;
(float)$this->GetValue("Ladeleistung_Effektiv")
) / $phaseDivisor;
if ( if (
$requestedCurrent <= $requestedCurrent <=
@@ -762,10 +779,7 @@ class Ladestation extends IPSModule
); );
if ($learnedMaxCurrent < 6.0) { if ($learnedMaxCurrent < 6.0) {
// Bei Easee hat der eindeutige API-Ladeendestatus Vorrang. Ein if (!$this->CanUseAdaptiveFullDetection($stationType)) {
// Kommunikations- oder Freigabefehler darf dort kein Ladeende
// simulieren.
if ($this->HasReliableFullStatus($stationType)) {
return false; return false;
} }
@@ -905,7 +919,7 @@ class Ladestation extends IPSModule
return $this->ApplyDirectStationDetection( return $this->ApplyDirectStationDetection(
$carDetected, $carDetected,
$chargerOpMode === 4, false,
$isOnePhase, $isOnePhase,
$maxCurrent $maxCurrent
); );
@@ -1062,14 +1076,10 @@ class Ladestation extends IPSModule
} }
$this->SetValue("Car_detected", true); $this->SetValue("Car_detected", true);
if ($this->HasReliableFullStatus($this->ReadPropertyInteger("Ladestation"))) { $this->SetValue(
$this->SetValue("Car_is_full", $carIsFull); "Car_is_full",
} else { $carIsFull || ($wasDetected && !$phaseChanged && $wasFull)
$this->SetValue( );
"Car_is_full",
$carIsFull || ($wasDetected && !$phaseChanged && $wasFull)
);
}
if (!$wasDetected || $phaseChanged) { if (!$wasDetected || $phaseChanged) {
if ($this->GetValue("Is_1_ph")) { if ($this->GetValue("Is_1_ph")) {
@@ -1633,7 +1643,7 @@ class Ladestation extends IPSModule
if ( if (
$maxCurrent < 6.0 && $maxCurrent < 6.0 &&
!$this->HasReliableFullStatus( $this->CanUseAdaptiveFullDetection(
$this->ReadPropertyInteger("Ladestation") $this->ReadPropertyInteger("Ladestation")
) )
) { ) {
+8 -4
View File
@@ -67,10 +67,14 @@ Iststrom mal `1.11`, wird der erreichbare Maximalstrom aus `Iststrom * 1.11`
gelernt und `PowerSteps` noch im selben Zyklus neu aufgebaut. Der Lernwert gelernt und `PowerSteps` noch im selben Zyklus neu aufgebaut. Der Lernwert
bleibt bis zum Ausstecken, einem neuen Fahrzeug oder einem Phasenwechsel aktiv. bleibt bis zum Ausstecken, einem neuen Fahrzeug oder einem Phasenwechsel aktiv.
Fällt der berechnete Wert bei Typ 1 bis 4 unter 6 A, wird Fällt der berechnete Wert unter 6 A, wird `Auto fertig geladen` gesetzt und
`Auto fertig geladen` gesetzt und nur `[0]` angeboten. Easee verwendet dafür nur `[0]` angeboten. Bei Easee gilt das nur bei verbundenem Gateway und
ausschließlich Observation 109. Eine Sollvorgabe von 0 W setzt die Zähler Fahrzeugstatus 4 oder 6: Das Modul muss dabei trotz positiver Sollvorgabe
zurück und kann weder eine Strombegrenzung noch ein Ladeende auslösen. 90 Sekunden lang einen Iststrom messen, der mit Faktor `1.11` unter 6 A
bleibt. Status 4 oder 6 allein wird nicht als Ladeende gewertet. Eine
Sollvorgabe von 0 W setzt die Zähler zurück und kann weder eine
Strombegrenzung noch ein Ladeende auslösen. Das bestätigte Ladeende bleibt bis
zum Ausstecken gespeichert.
## Einrichtung ## Einrichtung
+33 -23
View File
@@ -551,10 +551,18 @@ class Ladestation_v2 extends IPSModule
return in_array($stationType, [1, 2, 3, 4, 5, 6], true); return in_array($stationType, [1, 2, 3, 4, 5, 6], true);
} }
private function HasReliableFullStatus(int $stationType): bool private function CanUseAdaptiveFullDetection(int $stationType): bool
{ {
// Easee meldet das Ladeende eindeutig über Observation 109. if (!$this->UsesEaseeGateway($stationType)) {
return in_array($stationType, [5, 6], true); return true;
}
// Easee-Status 4 bedeutet "pausiert/gestoppt", Status 6 bedeutet,
// dass die Station auf eine Stromaufnahme des Fahrzeugs wartet. Beide
// sind nur zusammen mit positivem Soll und einer 90 Sekunden lang
// bestätigten, zu geringen Stromaufnahme ein Ladeende-Kandidat.
return $this->GetValue("Easee_Gateway_Connected") &&
in_array((int)$this->GetValue("Fahrzeugstatus"), [4, 6], true);
} }
private function SetAdaptiveReferenceMaxCurrent(float $apiMaxCurrent): float private function SetAdaptiveReferenceMaxCurrent(float $apiMaxCurrent): float
@@ -689,6 +697,13 @@ class Ladestation_v2 extends IPSModule
$actualPower = abs( $actualPower = abs(
(float)$this->GetValue("Ladeleistung_Effektiv") (float)$this->GetValue("Ladeleistung_Effektiv")
); );
// Ohne messbaren Strom ist keine Phasenerkennung möglich. Vor allem
// darf eine Ladepause die zuletzt bekannte Phase nicht auf 1-phasig
// umschalten. Die Ladeende-Erkennung läuft separat weiter.
if ($actualPower < 100.0) {
return false;
}
$onePhaseExpectedPower = $requestedCurrent * 230.0; $onePhaseExpectedPower = $requestedCurrent * 230.0;
$threePhaseExpectedPower = $requestedCurrent * 1.71 * 400.0; $threePhaseExpectedPower = $requestedCurrent * 1.71 * 400.0;
$isOnePhase = $actualPower < $isOnePhase = $actualPower <
@@ -707,7 +722,7 @@ class Ladestation_v2 extends IPSModule
($actualPower / $phaseDivisor); ($actualPower / $phaseDivisor);
if ( if (
$detectedCurrent < 6.0 && $detectedCurrent < 6.0 &&
!$this->HasReliableFullStatus($stationType) $this->CanUseAdaptiveFullDetection($stationType)
) { ) {
$this->SetBuffer( $this->SetBuffer(
"AdaptiveLearnedMaxCurrent", "AdaptiveLearnedMaxCurrent",
@@ -730,14 +745,18 @@ class Ladestation_v2 extends IPSModule
0.0, 0.0,
(float)$this->GetValue("Aktuelle_Leistung") (float)$this->GetValue("Aktuelle_Leistung")
); );
$actualPower = abs(
(float)$this->GetValue("Ladeleistung_Effektiv")
);
$hasKnownPhase = $stationType === 4 ||
$this->GetBuffer("AdaptivePhaseKnown") === "1";
$canEvaluate = $this->UsesAdaptiveCurrentDetection($stationType) && $canEvaluate = $this->UsesAdaptiveCurrentDetection($stationType) &&
$ladebereit && $ladebereit &&
$this->GetValue("Car_detected") && $this->GetValue("Car_detected") &&
!$this->GetValue("Car_is_full") && !$this->GetValue("Car_is_full") &&
$this->GetValue("Idle") && $this->GetValue("Idle") &&
($stationType === 4 || ($hasKnownPhase || $actualPower < 100.0) &&
$this->GetBuffer("AdaptivePhaseKnown") === "1") &&
$requestedPower > 0 && $requestedPower > 0 &&
$this->IsAdaptiveChargingEnabled($stationType) && $this->IsAdaptiveChargingEnabled($stationType) &&
$this->HasFreshAdaptiveMeasurement($stationType); $this->HasFreshAdaptiveMeasurement($stationType);
@@ -749,9 +768,7 @@ class Ladestation_v2 extends IPSModule
$phaseDivisor = $this->GetValue("Is_1_ph") ? 230.0 : 1.71 * 400.0; $phaseDivisor = $this->GetValue("Is_1_ph") ? 230.0 : 1.71 * 400.0;
$requestedCurrent = $requestedPower / $phaseDivisor; $requestedCurrent = $requestedPower / $phaseDivisor;
$actualCurrent = abs( $actualCurrent = $actualPower / $phaseDivisor;
(float)$this->GetValue("Ladeleistung_Effektiv")
) / $phaseDivisor;
if ( if (
$requestedCurrent <= $requestedCurrent <=
@@ -782,10 +799,7 @@ class Ladestation_v2 extends IPSModule
); );
if ($learnedMaxCurrent < 6.0) { if ($learnedMaxCurrent < 6.0) {
// Bei Easee hat der eindeutige API-Ladeendestatus Vorrang. Ein if (!$this->CanUseAdaptiveFullDetection($stationType)) {
// Kommunikations- oder Freigabefehler darf dort kein Ladeende
// simulieren.
if ($this->HasReliableFullStatus($stationType)) {
return false; return false;
} }
@@ -925,7 +939,7 @@ class Ladestation_v2 extends IPSModule
return $this->ApplyDirectStationDetection( return $this->ApplyDirectStationDetection(
$carDetected, $carDetected,
$chargerOpMode === 4, false,
$isOnePhase, $isOnePhase,
$maxCurrent $maxCurrent
); );
@@ -1082,14 +1096,10 @@ class Ladestation_v2 extends IPSModule
} }
$this->SetValue("Car_detected", true); $this->SetValue("Car_detected", true);
if ($this->HasReliableFullStatus($this->ReadPropertyInteger("Ladestation"))) { $this->SetValue(
$this->SetValue("Car_is_full", $carIsFull); "Car_is_full",
} else { $carIsFull || ($wasDetected && !$phaseChanged && $wasFull)
$this->SetValue( );
"Car_is_full",
$carIsFull || ($wasDetected && !$phaseChanged && $wasFull)
);
}
if (!$wasDetected || $phaseChanged) { if (!$wasDetected || $phaseChanged) {
if ($this->GetValue("Is_1_ph")) { if ($this->GetValue("Is_1_ph")) {
@@ -1646,7 +1656,7 @@ class Ladestation_v2 extends IPSModule
if ( if (
$maxCurrent < 6.0 && $maxCurrent < 6.0 &&
!$this->HasReliableFullStatus( $this->CanUseAdaptiveFullDetection(
$this->ReadPropertyInteger("Ladestation") $this->ReadPropertyInteger("Ladestation")
) )
) { ) {