From 6f76e6cd8650796bae627f15554476d5d285e2ec Mon Sep 17 00:00:00 2001 From: dh_Agent Date: Tue, 29 Sep 2026 07:55:31 +0000 Subject: [PATCH] fix(easee): Initialstatus der Ladestation laden --- CHANGELOG.md | 1 + EaseeGateway/module.php | 84 +++++++++++++++++++++++++---- tests/EaseeGatewayProtokollTest.php | 13 +++++ 3 files changed, 88 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c6ea0c2..3ca7411 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Alle wesentlichen Aenderungen an Enelix EMS werden in dieser Datei dokumentiert. - Stufenlose Leistungsbereiche fuer Batteriespeicher. - Ladefreigabe neuer Ladestationsinstanzen standardmaessig aktiviert. +- Easee-Ladestationen laden einen fehlenden Initialstatus ueber die Observations-API nach. - Vollstaendige PHP-, Struktur- und Symcon-Modultests fuer alle Module. ### Hinweise diff --git a/EaseeGateway/module.php b/EaseeGateway/module.php index f0df0b6..d491571 100644 --- a/EaseeGateway/module.php +++ b/EaseeGateway/module.php @@ -530,6 +530,25 @@ class EaseeGateway extends IPSModule return; } + $this->speichereBeobachtungImCache($seriennummer, $id, $wert); + + $this->SendDataToChildren(json_encode([ + 'DataID' => self::CHILD_EVENT_DATA_ID, + 'Buffer' => json_encode([ + 'type' => 'Observation', + 'serialNumber' => $seriennummer, + 'id' => $id, + 'value' => $wert, + 'timestamp' => time(), + ], JSON_THROW_ON_ERROR), + ], JSON_THROW_ON_ERROR)); + } + + private function speichereBeobachtungImCache( + string $seriennummer, + int $id, + $wert + ): void { $cache = $this->leseAttributArray('ObservationCache'); if (!isset($cache[$seriennummer]) || !is_array($cache[$seriennummer])) { $cache[$seriennummer] = []; @@ -545,21 +564,66 @@ class EaseeGateway extends IPSModule 'ObservationCache', json_encode($cache, JSON_THROW_ON_ERROR) ); + } - $this->SendDataToChildren(json_encode([ - 'DataID' => self::CHILD_EVENT_DATA_ID, - 'Buffer' => json_encode([ - 'type' => 'Observation', - 'serialNumber' => $seriennummer, - 'id' => $id, - 'value' => $wert, - 'timestamp' => time(), - ], JSON_THROW_ON_ERROR), - ], JSON_THROW_ON_ERROR)); + private function stelleAktuellenStatusSicher(string $seriennummer): void + { + $cache = $this->leseAttributArray('ObservationCache'); + $zustand = $cache[$seriennummer] ?? []; + if ( + (is_array($zustand) && array_key_exists('109', $zustand)) + || $this->ReadPropertyBoolean('Testmodus') + || $this->GetBuffer('SignalRReady') !== '1' + ) { + return; + } + + $antwort = $this->autorisierteApiAnfrage( + 'GET', + '/state/' . rawurlencode($seriennummer) . '/observations?ids=' + . rawurlencode(implode(',', EaseeGatewayProtokoll::BEOBACHTUNGEN)), + '' + ); + if (!($antwort['success'] ?? false)) { + $this->setzeLetztenFehler( + 'Easee-Status konnte nicht geladen werden: ' + . (string) ($antwort['error'] ?? 'Unbekannter API-Fehler.') + ); + return; + } + + $daten = json_decode((string) ($antwort['body'] ?? ''), true); + if (!is_array($daten)) { + $this->setzeLetztenFehler('Easee-Statusantwort ist ungueltig.'); + return; + } + $beobachtungen = EaseeGatewayProtokoll::extrahiereBeobachtungen( + $daten, + [$seriennummer], + $seriennummer + ); + $betriebsstatusGeladen = false; + foreach ($beobachtungen as $beobachtung) { + $this->speichereBeobachtungImCache( + $beobachtung['Seriennummer'], + $beobachtung['ID'], + $beobachtung['Wert'] + ); + $betriebsstatusGeladen = $betriebsstatusGeladen + || $beobachtung['ID'] === 109; + } + if (!$betriebsstatusGeladen) { + $this->setzeLetztenFehler( + 'Easee-Statusantwort enthaelt keinen Betriebsstatus (109).' + ); + return; + } + $this->setzeLetztenFehler(''); } private function erstelleStatusantwort(string $seriennummer): string { + $this->stelleAktuellenStatusSicher($seriennummer); $cache = $this->leseAttributArray('ObservationCache'); return json_encode([ 'success' => true, diff --git a/tests/EaseeGatewayProtokollTest.php b/tests/EaseeGatewayProtokollTest.php index 9e86ee9..9d96e8b 100644 --- a/tests/EaseeGatewayProtokollTest.php +++ b/tests/EaseeGatewayProtokollTest.php @@ -45,6 +45,19 @@ final class EaseeGatewayProtokollTest extends TestCase self::assertSame([], $beobachtungen); } + public function testRestBeobachtungenVerwendenAngefragteSeriennummer(): void + { + $beobachtungen = EaseeGatewayProtokoll::extrahiereBeobachtungen([ + ['id' => 109, 'value' => 1], + ['observationId' => 110, 'value' => 30], + ], ['EU2FGKEU'], 'EU2FGKEU'); + + self::assertSame([ + ['Seriennummer' => 'EU2FGKEU', 'ID' => 109, 'Wert' => 1], + ['Seriennummer' => 'EU2FGKEU', 'ID' => 110, 'Wert' => 30], + ], $beobachtungen); + } + public function testSeriennummerWirdNormalisiert(): void { self::assertSame(