From eda14a74c631d1cc39d00e588e6542fecbd91fc6 Mon Sep 17 00:00:00 2001 From: "belevo\\mh" Date: Thu, 30 Apr 2026 15:01:14 +0200 Subject: [PATCH] no message --- Bat_EV_SDL_V3_Beta/module.php | 96 +++++++++++++++++------------------ 1 file changed, 46 insertions(+), 50 deletions(-) diff --git a/Bat_EV_SDL_V3_Beta/module.php b/Bat_EV_SDL_V3_Beta/module.php index 39c2a55..31c1c77 100644 --- a/Bat_EV_SDL_V3_Beta/module.php +++ b/Bat_EV_SDL_V3_Beta/module.php @@ -91,9 +91,12 @@ public function Update() if ($dtSec > 10.0) $dtSec = 10.0; $dtH = $dtSec / 3600.0; - // Sollwerte lesen - $pSdlSollW = (float)GetValue($this->GetIDForIdent("Nennleistung_Soll_SDL")); - $pEvSollW = (float)GetValue($this->GetIDForIdent("Nennleistung_Soll_EV")); + // ============================ + // WICHTIG: Integrator nutzt NUR aktuelle SDL-Leistung + // ============================ + $pSdlIstW_raw = (float)GetValue($this->GetIDForIdent("Aktuelle_Leistung_SDL")); + $epsW = 1.0; + $sdlActive = (abs($pSdlIstW_raw) > $epsW); $calc = [ "inputs" => $cache["inputs"] ?? [], @@ -114,7 +117,7 @@ public function Update() $EV_kWh_ges = 0.0; $totalCapKWh = 0.0; - // CFG-Summen (für Startpunkt / Anzeige) + // CFG-Summen (Startpunkt / Anzeige) $SDL_kWh_ges_cfg = 0.0; $SDL_start_kWh_cfg = 0.0; @@ -144,7 +147,8 @@ public function Update() $sdlIsEmpty = ($sdlVirtPct <= 0.1); $sdlIsFull = ($sdlVirtPct >= 99.9); - // Flags für Grenz-Anker (deine Logik) + // Flags für Grenz-Anker: + // (nur wenn SDL-Leistung tatsächlich Richtung Grenze fährt) $sdlHitUpperBySDL = false; $sdlHitLowerBySDL = false; @@ -168,7 +172,15 @@ public function Update() $underKWh = (float)($c["underKWh"] ?? 0.0); $upKWh = (float)($c["upKWh"] ?? 0.0); - + // Grenz-Anker nur wenn SDL wirklich in Richtung Grenze fährt: + // Laden (Ist > 0): oberhalb up -> Upper Hit + if ($real_kWh > $upKWh && $pSdlIstW_raw > 0.0) { + $sdlHitUpperBySDL = true; + } + // Entladen (Ist < 0): unterhalb under -> Lower Hit + if ($real_kWh < $underKWh && $pSdlIstW_raw < 0.0) { + $sdlHitLowerBySDL = true; + } // EV-Fenster (dynamisch erweitert bei SDL virt leer/voll) $evUnderKWh = $underKWh; @@ -184,7 +196,7 @@ public function Update() $evWindowKWh = max(0.0, $evUpKWh - $evUnderKWh); // Fensterkapazitäten / Limits aus Cache - $SDL_kWh = (float)($c["SDL_kWh_total"] ?? 0.0); // SDL-Fenster total (kWh) + $SDL_kWh = (float)($c["SDL_kWh_total"] ?? 0.0); // SDL-Fenster total (kWh) $EV_kWh = (float)($c["EV_kWh_total"] ?? 0.0); $sdlShareKW_laden = (float)($c["sdlShareKW_laden"] ?? 0.0); @@ -233,7 +245,6 @@ public function Update() $sdlChKW = $sdlShareKW_laden; $evChKW = 0.0; // EV darf oben nicht laden - // EV voll im Fenster, Rest ist SDL $real_kWh_ev = $evWindowKWh; $real_kWh_sdl = max(0.0, $real_kWh - $real_kWh_ev); @@ -329,19 +340,10 @@ public function Update() $evPosPct = max(0.0, min(100.0, $evPosPct)); $this->SetIdentValue("SoC_EV", round($evPosPct, 3)); - // ====================================== - // SDL aktiv? - // ====================================== - $epsW = 1.0; - $sdlActive = (abs($pSdlSollW) > $epsW); - // Maximalleistungen $maxSDL_ch = $sdlChKW_ges * 1000.0; $maxSDL_dis = $sdlDisKW_ges * 1000.0; - // Soll clamp - $pSdlSollW = max(-$maxSDL_dis, min($maxSDL_ch, $pSdlSollW)); - // CacheHash Change Reset $cacheHash = (string)$this->GetBufferSafe("BatCacheHash"); $intHash = (string)$this->GetBufferSafe("Int_CFG_HASH"); @@ -353,45 +355,39 @@ public function Update() if ($cacheHash !== "" && $cacheHash !== $intHash) { $Esdl_kWh = max(0.0, min($SDL_kWh_ges_cfg, $SDL_start_kWh_cfg)); - $dtH = 0.0; $this->SetBuffer("Int_LastTs", (string)$now); $this->SetBuffer("Int_CFG_HASH", $cacheHash); $this->SetBuffer("Int_Init_SDL", "1"); - $this->SendDebug("SDL", "Reset wegen CacheHash-Change auf Startpunkt: Esdl_kWh=" . round($Esdl_kWh, 3), 0); } - - - // ========================================================== - // FIX #2: Integrator mit IST-Leistung statt SOLL-Leistung - // ========================================================== - $totalIstW = $this->GetTotalBatteryPowerIstW(); // Gesamt-Batterie-Istleistung (W) - $pSdlIstW = 0.0; - - if ($sdlActive) { - // Wenn EV nicht aktiv: SDL = gesamte Istleistung - if (abs($pEvSollW) <= $epsW) { - $pSdlIstW = $totalIstW; - } else { - // EV und SDL beide aktiv: - $sameDir = (($pSdlSollW > 0 && $pEvSollW > 0) || ($pSdlSollW < 0 && $pEvSollW < 0)); - if ($sameDir) { - $share = abs($pSdlSollW) / (abs($pSdlSollW) + abs($pEvSollW)); - $pSdlIstW = $totalIstW * $share; - } else { - // gegenläufig: aus Gesamt-Ist nicht sauber trennbar -> nicht integrieren - $pSdlIstW = 0.0; - } - } + // ---------------------------------------------------------- + // OPTIONAL: Grenz-Anker, aber jetzt basierend auf IST-Richtung + // (verhindert Drift an echten Grenzen) + // ---------------------------------------------------------- + if ($sdlHitUpperBySDL || $sdlHitLowerBySDL) { + $Esdl_kWh = max(0.0, min($SDL_kWh_ges, $real_kWh_sdl_ges)); + $dtH = 0.0; + $this->SetBuffer("Int_LastTs", (string)$now); + $this->SendDebug( + "SDL", + "Grenz-Anker (IST): Esdl_kWh=" . round($Esdl_kWh, 3) . + " upper=" . ($sdlHitUpperBySDL ? "1" : "0") . + " lower=" . ($sdlHitLowerBySDL ? "1" : "0"), + 0 + ); } - // Ist clamp (wichtig) + // ========================================================== + // FIX #2 (dein Wunsch): Integration NUR mit aktueller SDL-Leistung + // ========================================================== + $pSdlIstW = $pSdlIstW_raw; + + // clamp Istleistung auf erlaubte SDL-Leistung (robust) $pSdlIstW = max(-$maxSDL_dis, min($maxSDL_ch, $pSdlIstW)); - // Integration - if ($sdlActive) { + if (abs($pSdlIstW) > $epsW) { $Esdl_kWh += (($pSdlIstW / 1000.0) * $dtH); } @@ -409,7 +405,7 @@ public function Update() $this->SetIdentValue("P_EV_laden", (int)round($evChKW_ges * 1000.0, 0)); $this->SetIdentValue("P_EV_entladen", (int)round($evDisKW_ges * 1000.0, 0)); - // Total JSON (inkl. Istwerte zur Kontrolle) + // Total JSON (mit Debug für IST) $calc["total"] = [ "SDL_SoC_pct" => round($sdlPosPct, 3), "EV_SoC_pct" => round($evPosPct, 3), @@ -430,10 +426,10 @@ public function Update() "SDL_HitUpperBySDL" => $sdlHitUpperBySDL, "SDL_HitLowerBySDL" => $sdlHitLowerBySDL, - // Debug / Kontrolle für Ist-Integration: - "SDL_Soll_W" => round($pSdlSollW, 0), - "SDL_Ist_W" => round($pSdlIstW, 0), - "Bat_Ist_W_total" => round($totalIstW, 0) + // Debug: + "SDL_Ist_W_raw" => round($pSdlIstW_raw, 0), + "SDL_Ist_W_used" => round($pSdlIstW, 0), + "dtSec" => round($dtSec, 3) ]; $this->SetIdentValue("CalcJSON", json_encode($calc, JSON_PRETTY_PRINT));