From eed1e585d6fcacafd5e2ef6d85944c0143767d95 Mon Sep 17 00:00:00 2001 From: "belevo\\mh" Date: Thu, 22 Jan 2026 14:48:36 +0100 Subject: [PATCH] no message --- Bat_EV_SDL/module.php | 81 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 68 insertions(+), 13 deletions(-) diff --git a/Bat_EV_SDL/module.php b/Bat_EV_SDL/module.php index 5faadde..2f624f9 100644 --- a/Bat_EV_SDL/module.php +++ b/Bat_EV_SDL/module.php @@ -28,6 +28,11 @@ class Bat_EV_SDL extends IPSModule $this->RegisterVariableFloat("P_SDL_max", "P SDL max (W)", "", 20); $this->RegisterVariableFloat("P_EV_max", "P EV max (W)", "", 21); + $this->RegisterVariableFloat("P_EV_laden", "P EV laden max (W)", "", 22); + $this->RegisterVariableFloat("P_EV_entladen", "P EV entladen max (W)", "", 23); + $this->RegisterVariableFloat("P_SDL_laden", "P SDL laden max (W)", "", 24); + $this->RegisterVariableFloat("P_SDL_entladen", "P SDL entladen max (W)", "", 25); + // Optional: Voller JSON-Dump zum Debuggen/Weiterverarbeiten $this->RegisterVariableString("CalcJSON", "Berechnung (JSON)", "", 99); @@ -94,7 +99,9 @@ class Bat_EV_SDL extends IPSModule } $sdlPowerW = (int)$this->ReadPropertyInteger("SDL_Leistung"); - $reserveH = 0.5; // FIX: SDL muss immer 30 Minuten laden/entladen können + if ($sdlPowerW < 0) $sdlPowerW = 0; + + $reserveH = 0.5; // FIX: 30 Minuten // 1) Summe Max-Leistung aller Batterien $sumBatPowerW = 0; @@ -116,18 +123,25 @@ class Bat_EV_SDL extends IPSModule $this->SendDebug("Update", "SDL_Leistung ($sdlPowerW W) > SummeBatPower ($sumBatPowerW W) -> begrenze.", 0); $sdlPowerW = $sumBatPowerW; } - if ($sdlPowerW < 0) $sdlPowerW = 0; - // Summen + // Summen für Energiesicht $sumSDLPowerW = 0.0; $sumEVPowerW = 0.0; - $sumSDLcapKWh = 0.0; // SDL-Topf Kapazität (Reserveenergie) + $sumSDLcapKWh = 0.0; // SDL-Topf Kapazität (Reserveenergie 30 min) $sumEVcapKWh = 0.0; // EV-Topf Kapazität (Rest) $sumSDLkWh = 0.0; // aktueller Füllstand SDL $sumEVkWh = 0.0; // aktueller Füllstand EV + // Neue Leistungs-Maxwerte (wie dein Beispiel) + $P_EV_laden_W = 0.0; + $P_EV_entladen_W = 0.0; + $P_SDL_laden_W = 0.0; + $P_SDL_entladen_W = 0.0; + + $eps = 0.0001; + $calc = []; // 2) Pro Batterie rechnen @@ -153,6 +167,9 @@ class Bat_EV_SDL extends IPSModule $pSDL_W = min($pSDL_W_raw, (float)$pBatW); if ($pSDL_W < 0) $pSDL_W = 0.0; + // EV Anteil Leistung (W) ist Rest + $pEV_W = max(0.0, $pBatW - $pSDL_W); + // SDL Reserveenergie für 30 Minuten (kWh) $eSDLcap_kWh = ($pSDL_W * $reserveH) / 1000.0; @@ -165,7 +182,7 @@ class Bat_EV_SDL extends IPSModule // Gesamtenergie in der Batterie (kWh) $eTotal_kWh = ($socPct / 100.0) * $capKWh; - // Aufteilung Energie: SDL zuerst füllen (damit SDL "sicher" ist) + // Aufteilung Energie: SDL zuerst füllen $eSDL_kWh = min($eTotal_kWh, $eSDLcap_kWh); $eEV_kWh = max(0.0, $eTotal_kWh - $eSDL_kWh); @@ -174,10 +191,7 @@ class Bat_EV_SDL extends IPSModule $eEV_kWh = $eEVcap_kWh; } - // Power-Limits - $pEV_W = max(0.0, $pBatW - $pSDL_W); - - // Summieren + // Summieren Energiesicht $sumSDLPowerW += $pSDL_W; $sumEVPowerW += $pEV_W; @@ -187,6 +201,28 @@ class Bat_EV_SDL extends IPSModule $sumSDLkWh += $eSDL_kWh; $sumEVkWh += $eEV_kWh; + // 3) Maxwerte Leistung (dein gewünschtes Verhalten) + + // EV laden: nur wenn im EV-Topf noch Platz ist + if (($eEVcap_kWh - $eEV_kWh) > $eps) { + $P_EV_laden_W += $pEV_W; + } + + // EV entladen: nur wenn im EV-Topf Energie drin ist + if ($eEV_kWh > $eps) { + $P_EV_entladen_W += $pEV_W; + } + + // SDL laden: nur wenn im SDL-Topf noch Platz ist + if (($eSDLcap_kWh - $eSDL_kWh) > $eps) { + $P_SDL_laden_W += $pSDL_W; + } + + // SDL entladen: HART -> nur wenn SDL-Topf voll ist (30min Garantie) + if (($eSDL_kWh + $eps) >= $eSDLcap_kWh) { + $P_SDL_entladen_W += $pSDL_W; + } + // Detail pro Batterie $calc[] = [ "typ" => $typ, @@ -203,25 +239,38 @@ class Bat_EV_SDL extends IPSModule "eEVcap_kWh" => round($eEVcap_kWh, 3), "eEV_kWh" => round($eEV_kWh, 3), - "pEV_W" => round($pEV_W, 0) + "pEV_W" => round($pEV_W, 0), + + // hilfreiche Debug-Felder für deine Maxwerte-Logik + "canEVcharge" => (($eEVcap_kWh - $eEV_kWh) > $eps), + "canEVdischarge" => ($eEV_kWh > $eps), + "canSDLcharge" => (($eSDLcap_kWh - $eSDL_kWh) > $eps), + "canSDLdischarge_30min" => (($eSDL_kWh + $eps) >= $eSDLcap_kWh) ]; } - // 3) Gesamt-SoC für SDL/EV (bezogen auf jeweilige Topf-Kapazität) + // 4) Gesamt-SoC für SDL/EV (bezogen auf jeweilige Topf-Kapazität) $socSDL = ($sumSDLcapKWh > 0.0) ? ($sumSDLkWh / $sumSDLcapKWh) * 100.0 : 0.0; $socEV = ($sumEVcapKWh > 0.0) ? ($sumEVkWh / $sumEVcapKWh) * 100.0 : 0.0; - // 4) Setzen der Ergebnisvariablen + // 5) Setzen der Ergebnisvariablen (Energie + SoC) SetValue($this->GetIDForIdent("kWh_SDL"), round($sumSDLkWh, 3)); SetValue($this->GetIDForIdent("kWh_EV"), round($sumEVkWh, 3)); SetValue($this->GetIDForIdent("SoC_SDL"), round($socSDL, 2)); SetValue($this->GetIDForIdent("SoC_EV"), round($socEV, 2)); + // "statische" Power-Grenzen (ohne Füllstand) – bleiben nützlich SetValue($this->GetIDForIdent("P_SDL_max"), round($sumSDLPowerW, 0)); SetValue($this->GetIDForIdent("P_EV_max"), round($sumEVPowerW, 0)); - // 5) Debug / Buffer + // 6) Neue Power-Maxwerte (abhängig von Füllstand/Platz) + SetValue($this->GetIDForIdent("P_EV_laden"), round($P_EV_laden_W, 0)); + SetValue($this->GetIDForIdent("P_EV_entladen"), round($P_EV_entladen_W, 0)); + SetValue($this->GetIDForIdent("P_SDL_laden"), round($P_SDL_laden_W, 0)); + SetValue($this->GetIDForIdent("P_SDL_entladen"), round($P_SDL_entladen_W, 0)); + + // 7) Debug / Buffer $out = [ "SDL_W" => $sdlPowerW, "Reserve_h" => $reserveH, @@ -239,6 +288,11 @@ class Bat_EV_SDL extends IPSModule "P_SDL_max_W" => round($sumSDLPowerW, 0), "P_EV_max_W" => round($sumEVPowerW, 0), + "P_EV_laden_W" => round($P_EV_laden_W, 0), + "P_EV_entladen_W" => round($P_EV_entladen_W, 0), + "P_SDL_laden_W" => round($P_SDL_laden_W, 0), + "P_SDL_entladen_W" => round($P_SDL_entladen_W, 0), + "batteries" => $calc ]; @@ -249,6 +303,7 @@ class Bat_EV_SDL extends IPSModule $this->SendDebug("Update", $json, 0); } + /* =========================== * 5) Helper * =========================== */