diff --git a/Bat_EV_SDL _V2/module.php b/Bat_EV_SDL _V2/module.php index 5eba5bf..e766dae 100644 --- a/Bat_EV_SDL _V2/module.php +++ b/Bat_EV_SDL _V2/module.php @@ -2,7 +2,7 @@ class Bat_EV_SDL_V2 extends IPSModule { - private const HOURS = 0.5; // 30 Minuten Fenster + private const HOURS = 0.5; // 30 Minuten public function Create() { @@ -32,12 +32,8 @@ class Bat_EV_SDL_V2 extends IPSModule // Debug $this->RegisterVariableString("CalcJSON", "Berechnung (JSON)", "", 99); - // Cache Buffer - $this->RegisterBuffer("BatCacheHash", ""); - $this->RegisterBuffer("BatCacheJSON", "[]"); - - // Timer - $this->RegisterTimer("UpdateTimer", 0, 'GEF_Update($_IPS["TARGET"]);'); + // Timer: wichtig -> Prefix muss passen + $this->RegisterTimer("UpdateTimer", 0, 'Bat_EV_SDL_V2_Update($_IPS["TARGET"]);'); } public function ApplyChanges() @@ -47,7 +43,7 @@ class Bat_EV_SDL_V2 extends IPSModule $intervalMin = (int)$this->ReadPropertyInteger("UpdateInterval"); $this->SetTimerInterval("UpdateTimer", ($intervalMin > 0) ? $intervalMin * 60 * 1000 : 0); - // Cache neu bauen wenn Properties geändert wurden + // Cache neu bauen (force) $this->BuildBatteryCache(true); $this->Update(); @@ -77,7 +73,7 @@ class Bat_EV_SDL_V2 extends IPSModule // Cache nur neu bauen, wenn nötig $this->BuildBatteryCache(false); - $cache = json_decode($this->GetBuffer("BatCacheJSON"), true); + $cache = json_decode($this->GetBufferSafe("BatCacheJSON"), true); if (!is_array($cache) || empty($cache["bats"])) { $this->WriteAllZero("cache empty/invalid"); return; @@ -116,23 +112,21 @@ class Bat_EV_SDL_V2 extends IPSModule $real_kWh = $capKWh / 100.0 * $socPct; // vorkalkuliert: - $typ = (string)($c["typ"] ?? ("Bat " . ($i + 1))); - $underKWh = (float)($c["underKWh"] ?? 0.0); - $upKWh = (float)($c["upKWh"] ?? 0.0); - $SDL_kWh = (float)($c["SDL_kWh_total"] ?? 0.0); - $EV_kWh = (float)($c["EV_kWh_total"] ?? 0.0); + $typ = (string)($c["typ"] ?? ("Bat " . ($i + 1))); + $underKWh = (float)($c["underKWh"] ?? 0.0); + $upKWh = (float)($c["upKWh"] ?? 0.0); + $SDL_kWh = (float)($c["SDL_kWh_total"] ?? 0.0); + $EV_kWh = (float)($c["EV_kWh_total"] ?? 0.0); $sdlShareKW = (float)($c["sdlShareKW"] ?? 0.0); $evShareKW = (float)($c["evShareKW"] ?? 0.0); - // Defaults pro Batterie + // Defaults $EV_SOC = 0.0; $SDL_SOC = 0.0; - $sdlDisKW = 0.0; - $evDisKW = 0.0; - $sdlChKW = 0.0; - $evChKW = 0.0; + $sdlDisKW = 0.0; $evDisKW = 0.0; + $sdlChKW = 0.0; $evChKW = 0.0; $real_kWh_ev = 0.0; $real_kWh_sdl = 0.0; @@ -182,19 +176,17 @@ class Bat_EV_SDL_V2 extends IPSModule $real_kWh_sdl = $real_kWh; } - // Null/Full Abdeckung (wie vorher) + // Null/Full if ($real_kWh <= 0.0) { $sdlDisKW = 0.0; $real_kWh_ev = 0.0; $real_kWh_sdl = 0.0; } elseif ($real_kWh >= $capKWh) { $sdlChKW = 0.0; - $real_kWh_ev = $capKWh - 2.0 * $underKWh; $real_kWh_sdl = 2.0 * $underKWh; } - // Negative verhindern $real_kWh_ev = max(0.0, $real_kWh_ev); $real_kWh_sdl = max(0.0, $real_kWh_sdl); @@ -212,7 +204,6 @@ class Bat_EV_SDL_V2 extends IPSModule $SDL_kWh_ges += $SDL_kWh; $EV_kWh_ges += $EV_kWh; - // Debug pro Batterie $calc["batteries"][] = [ "idx" => $c["idx"] ?? $i, "typ" => $typ, @@ -239,11 +230,9 @@ class Bat_EV_SDL_V2 extends IPSModule ]; } - // Prozent gesamt $evPosPct = ($EV_kWh_ges > 0.0) ? ($real_kWh_ev_ges / $EV_kWh_ges * 100.0) : 0.0; $sdlPosPct = ($SDL_kWh_ges > 0.0) ? ($real_kWh_sdl_ges / $SDL_kWh_ges * 100.0) : 0.0; - // Werte setzen $this->SetIdentValue("SDL_Pos", round($sdlPosPct, 3)); $this->SetIdentValue("SoC_EV", round($evPosPct, 3)); @@ -275,10 +264,6 @@ class Bat_EV_SDL_V2 extends IPSModule } } - /** - * Baut Cache nur neu, wenn sich Inputs geändert haben. - * Cache enthält alles, was NICHT vom SoC abhängt. - */ private function BuildBatteryCache(bool $force): void { $batteriesRaw = $this->ReadPropertyString("Batteries"); @@ -291,24 +276,20 @@ class Bat_EV_SDL_V2 extends IPSModule "hours" => $hours ])); - $oldHash = $this->GetBuffer("BatCacheHash"); + $oldHash = $this->GetBufferSafe("BatCacheHash"); if (!$force && $oldHash === $hash) { - return; // nix zu tun + return; } $batteries = json_decode($batteriesRaw, true); - if (!is_array($batteries)) { - $batteries = []; - } + if (!is_array($batteries)) $batteries = []; - // Summe Batterie-Maxleistungen $sumBatPowerW = 0.0; foreach ($batteries as $b) { $p = (float)($b["powerbat"] ?? 0); if ($p > 0) $sumBatPowerW += $p; } - // Cache Grundstruktur $cache = [ "inputs" => [ "SDL_Leistung_W" => $sdlTotalW, @@ -334,18 +315,14 @@ class Bat_EV_SDL_V2 extends IPSModule $pBatkW = $pBatW / 1000.0; $capKWh = max(0.0, (float)($b["capazity"] ?? 0)); - if ($capKWh <= 0.0) { - continue; - } + if ($capKWh <= 0.0) continue; $socVarId = (int)($b["soc"] ?? 0); $typ = (string)($b["typ"] ?? ("Bat " . ($idx + 1))); - // Anteil SDL/EV über Leistungsanteil (wie vorher) $sdlShareKW = ($sumBatPowerkW > 0.0) ? ($sdlTotalkW / $sumBatPowerkW * $pBatkW) : 0.0; $evShareKW = $pBatkW - $sdlShareKW; - // untere Grenze $underKWh = $sdlShareKW * $hours; $underKWh = max(0.0, min($underKWh, $capKWh / 2.0)); @@ -378,7 +355,11 @@ class Bat_EV_SDL_V2 extends IPSModule $this->SendDebug("Cache", "Battery cache rebuilt (" . count($cache["bats"]) . " bats)", 0); } - // ---------------- Helpers ---------------- + private function GetBufferSafe(string $name): string + { + $v = $this->GetBuffer($name); + return is_string($v) ? $v : ""; + } private function WriteAllZero(string $reason): void {