diff --git a/Bat_EV_SDL_V3_Beta/module.php b/Bat_EV_SDL_V3_Beta/module.php index dcf2ec1..bfa332b 100644 --- a/Bat_EV_SDL_V3_Beta/module.php +++ b/Bat_EV_SDL_V3_Beta/module.php @@ -791,128 +791,72 @@ private function CalculateBatteryDistribution(float $pEvW, float $pSdlW): array $totalPower_ist += (-1)*GetValue($bat->register_bat_power); } - // ---------------------------- - // ALT (nicht mehr gebraucht) -> AUSKOMMENTIERT - // ---------------------------- - /* - $sumReq = (abs($pEvW) + abs($pSdlW)); - $sumReqRel = ($pEvW + $pSdlW); - - if($sumReq==0){ - - $this->SetValue("Aktuelle_Leistung_EV", $totalPower_ist / 2); - $this->SetValue("Aktuelle_Leistung_SDL", $totalPower_ist / 2); - - }else{ - - if($pEvW>=0){ - $this->SetValue("Aktuelle_Leistung_EV",((1+($totalPower_ist-$sumReqRel) / $sumReq)) * $pEvW); - }else{ - $this->SetValue("Aktuelle_Leistung_EV",((1-($totalPower_ist-$sumReqRel) / $sumReq)) * $pEvW); - } - - if($pSdlW>=0){ - $this->SetValue("Aktuelle_Leistung_SDL",((1+($totalPower_ist-$sumReqRel) / $sumReq)) * $pSdlW); - }else{ - $this->SetValue("Aktuelle_Leistung_SDL",((1-($totalPower_ist-$sumReqRel) / $sumReq)) * $pSdlW); - } - } - */ - - // ---------------------------- - // NEU (genau deine gewünschte Logik) - // aktuelle - EV_SOLL = aktuelle SDL - // aktuelle - SDL_SOLL = aktuelle EV - // ---------------------------- - - - - - /* + // ===================================================== + // Stabilisierung "Aktuelle Leistung": Sample & Hold + // -> ändert sich nur wenn Sollwerte sich ändern + // ===================================================== $eps = 0.01; - $aktEV = 0.0; - $aktSDL = 0.0; + // Toleranz: wann gilt Soll als "gleich geblieben" (W) + $tolW = 0.5; - // Optional: Wenn einer 0 ist -> aktiver Kanal bekommt totalPower_ist - if (abs($pEvW) < $eps && abs($pSdlW) < $eps) { + // Letzte Sollwerte und Haltefaktor aus Buffer + $prevEvSoll = (float)$this->GetBufferSafe("Hold_EvSoll"); + $prevSdlSoll = (float)$this->GetBufferSafe("Hold_SdlSoll"); + $factorHold = (float)$this->GetBufferSafe("Hold_Factor"); - $aktEV = 0.0; - $aktSDL = 0.0; - - } elseif (abs($pEvW) < $eps) { - - $aktEV = 0.0; - $aktSDL = $totalPower_ist; - - } elseif (abs($pSdlW) < $eps) { - - $aktEV = $totalPower_ist; - $aktSDL = 0.0; - - } else { - - // Beide aktiv - $sameDirection = (($pEvW > 0 && $pSdlW > 0) || ($pEvW < 0 && $pSdlW < 0)); - - if ($sameDirection) { - // Regel A: gleiche Richtung -> Ist proportional nach |Soll| aufteilen - $sumAbs = abs($pEvW) + abs($pSdlW); - - if ($sumAbs < $eps) { - // Fallback - $aktEV = $totalPower_ist / 2.0; - $aktSDL = $totalPower_ist / 2.0; - } else { - $aktEV = $totalPower_ist * (abs($pEvW) / $sumAbs); - $aktSDL = $totalPower_ist - $aktEV; // Summe bleibt exakt totalPower_ist - } - - } else { - // Regel B: gegensätzliche Richtung -> Sollwerte anzeigen - $aktEV = $pEvW; - $aktSDL = $pSdlW; - } + // Initialwerte falls Buffer leer + if ($this->GetBufferSafe("Hold_Init") !== "1") { + $prevEvSoll = $pEvW; + $prevSdlSoll = $pSdlW; + $factorHold = 1.0; + $this->SetBuffer("Hold_Init", "1"); } - $this->SetValue("Aktuelle_Leistung_EV", (float)$aktEV); - $this->SetValue("Aktuelle_Leistung_SDL", (float)$aktSDL); - */ + // Prüfen ob Sollwerte sich geändert haben + $changed = + (abs($pEvW - $prevEvSoll) > $tolW) || + (abs($pSdlW - $prevSdlSoll) > $tolW); - $eps = 0.01; + // Beim Sollwechsel: neuen Faktor bestimmen und einfrieren + if ($changed) { + $sumSoll = (float)($pEvW + $pSdlW); - $sumSoll = (float)($pEvW + $pSdlW); - - if (abs($sumSoll) > $eps) { - // Normalfall: wir skalieren so, dass EV+SDL genau totalPower_ist ergibt - $factor = (float)($totalPower_ist / $sumSoll); - - $aktEV = (float)($pEvW * $factor); - $aktSDL = (float)($pSdlW * $factor); - - } else { - // Sonderfall: Soll hebt sich nahezu auf (sumSoll ~ 0) - // -> wenn Ist ebenfalls ~0: Soll anzeigen - if (abs($totalPower_ist) < 50.0) { // 50W Toleranz kannst du anpassen - $aktEV = (float)$pEvW; - $aktSDL = (float)$pSdlW; + if (abs($sumSoll) > $eps) { + $factorHold = (float)($totalPower_ist / $sumSoll); } else { - // Ist ist nicht 0 obwohl Sollsumme 0 -> Abweichung zuweisen (z.B. SDL) - $aktEV = (float)$pEvW; - $aktSDL = (float)($totalPower_ist - $aktEV); - // Alternative: Abweichung EV geben: - // $aktSDL = (float)$pSdlW; - // $aktEV = (float)($totalPower_ist - $aktSDL); + // Soll hebt sich auf / fast 0: keine Skalierung + $factorHold = 1.0; } + + // Faktor begrenzen (Schutz gegen Unsinn; ggf. anpassen) + $factorHold = max(-2.0, min(2.0, $factorHold)); + + // Sollwerte merken + $prevEvSoll = $pEvW; + $prevSdlSoll = $pSdlW; + + $this->SetBuffer("Hold_EvSoll", (string)$prevEvSoll); + $this->SetBuffer("Hold_SdlSoll", (string)$prevSdlSoll); + $this->SetBuffer("Hold_Factor", (string)$factorHold); } + // "Aktuelle" Leistungen aus gehaltenem Faktor berechnen + $aktEV = (float)($pEvW * $factorHold); + $aktSDL = (float)($pSdlW * $factorHold); + // Optional: wenn beide Soll = 0 -> beide aktuelle = 0 + if (abs($pEvW) <= $eps && abs($pSdlW) <= $eps) { + $aktEV = 0.0; + $aktSDL = 0.0; + } + + // Diese beiden Variablen stabil setzen (kein $this->SetValue!) $this->SetIdentValue("Aktuelle_Leistung_EV", (float)$aktEV); $this->SetIdentValue("Aktuelle_Leistung_SDL", (float)$aktSDL); - return $finalOutput; }