From 644077897285399ab5a5f586e218973b3c07f12f Mon Sep 17 00:00:00 2001 From: "belevo\\mh" Date: Tue, 5 May 2026 14:45:29 +0200 Subject: [PATCH] no message --- Bat_EV_SDL_V4/form.json | 25 ++++++++++++- Bat_EV_SDL_V4/module.php | 80 ++++++++++++++++++++++++++++++---------- 2 files changed, 84 insertions(+), 21 deletions(-) diff --git a/Bat_EV_SDL_V4/form.json b/Bat_EV_SDL_V4/form.json index a7f59a9..463dd90 100644 --- a/Bat_EV_SDL_V4/form.json +++ b/Bat_EV_SDL_V4/form.json @@ -144,12 +144,35 @@ "caption": "Update Intervall", "suffix": "S", "minimum": 1, - "digits": 20 + "digits": 2 }, { "type": "CheckBox", "name": "FilterAktiv", "caption": "Filter für aktuelle EV/SDL Leistung aktiv. Dient für die Visualisierung, um Leistungssprünge zu vermeiden." + }, + { + "type": "NumberSpinner", + "name": "FilterTolerancePct", + "caption": "Filter Toleranz (%)", + "minimum": 0, + "maximum": 100, + "digits": 1 + }, + { + "type": "NumberSpinner", + "name": "FilterRampWPerSec", + "caption": "Filter Rampe (W/s)", + "minimum": 100, + "maximum": 20000, + "digits": 0 + }, + { + "type": "NumberSpinner", + "name": "FilterHits", + "caption": "Filter Treffer bis Übernahme", + "minimum": 1, + "maximum": 10 } ] } diff --git a/Bat_EV_SDL_V4/module.php b/Bat_EV_SDL_V4/module.php index 46f981b..fe539bc 100644 --- a/Bat_EV_SDL_V4/module.php +++ b/Bat_EV_SDL_V4/module.php @@ -15,6 +15,9 @@ class Bat_EV_SDL_V4 extends IPSModule $this->RegisterPropertyFloat("EV_Start_Pos_Config", 50.0); // % $this->RegisterPropertyInteger("UpdateInterval", 2); // Sekunden $this->RegisterPropertyBoolean("FilterAktiv", true); + $this->RegisterPropertyFloat("FilterTolerancePct", 15.0); // % + $this->RegisterPropertyFloat("FilterRampWPerSec", 2000.0); // W/s + $this->RegisterPropertyInteger("FilterHits", 1); // Status $this->RegisterVariableBoolean("State", "Aktiv", "~Switch", 1); @@ -545,8 +548,8 @@ class Bat_EV_SDL_V4 extends IPSModule $filterAktiv = $this->ReadPropertyBoolean("FilterAktiv"); if ($filterAktiv) { - $tolPct = 0.10; - $needHits = 1; + $tolPct = max(0.0, (float)$this->ReadPropertyFloat("FilterTolerancePct")) / 100.0; + $needHits = max(1, (int)$this->ReadPropertyInteger("FilterHits")); $fEV = $this->FilterCurrent("EV", $rawEV, $pEvW, abs($pEvW) * $tolPct, $needHits); $fSDL = $this->FilterCurrent("SDL", $rawSDL, $pSdlW, abs($pSdlW) * $tolPct, $needHits); } else { @@ -563,53 +566,80 @@ class Bat_EV_SDL_V4 extends IPSModule { $lastVal = (float)$this->GetBufferSafe("CUR_{$ch}_VAL"); $pending = (float)$this->GetBufferSafe("CUR_{$ch}_PEND"); - $hits = (int)$this->GetBufferSafe("CUR_{$ch}_HITS"); + $hits = (int)$this->GetBufferSafe("CUR_{$ch}_HITS"); + $lastTs = (float)$this->GetBufferSafe("CUR_{$ch}_TS"); + + $now = microtime(true); if ($this->GetBufferSafe("CUR_{$ch}_INIT") !== "1") { $lastVal = $raw; $pending = $target; $hits = 0; + $lastTs = $now; + $this->SetBuffer("CUR_{$ch}_INIT", "1"); $this->SetBuffer("CUR_{$ch}_VAL", (string)$lastVal); $this->SetBuffer("CUR_{$ch}_PEND", (string)$pending); $this->SetBuffer("CUR_{$ch}_HITS", (string)$hits); + $this->SetBuffer("CUR_{$ch}_TS", (string)$lastTs); + + return $lastVal; + } + + $dt = max(0.0, min(5.0, $now - $lastTs)); + $this->SetBuffer("CUR_{$ch}_TS", (string)$now); + + $maxRampWPerSec = max(100.0, (float)$this->ReadPropertyFloat("FilterRampWPerSec")); + + if (abs($target) < 0.5) { + $lastVal = $this->MoveTowards($lastVal, 0.0, $maxRampWPerSec * $dt); + + if (abs($lastVal) < 1.0) { + $lastVal = 0.0; + } + + $this->SetBuffer("CUR_{$ch}_VAL", (string)$lastVal); + $this->SetBuffer("CUR_{$ch}_PEND", (string)$target); + $this->SetBuffer("CUR_{$ch}_HITS", "0"); + + return $lastVal; } if (abs($target - $pending) > 0.5) { $pending = $target; $hits = 0; - $this->SetBuffer("CUR_{$ch}_PEND", (string)$pending); - $this->SetBuffer("CUR_{$ch}_HITS", (string)$hits); } - if (abs($pending) < 0.5) { - $lastVal = 0.0; - $hits = 0; + if (($pending > 0.0 && $raw < -50.0) || ($pending < 0.0 && $raw > 50.0)) { $this->SetBuffer("CUR_{$ch}_VAL", (string)$lastVal); - $this->SetBuffer("CUR_{$ch}_HITS", (string)$hits); - return $lastVal; - } - - if (($pending > 0.0 && $raw < 0.0) || ($pending < 0.0 && $raw > 0.0)) { + $this->SetBuffer("CUR_{$ch}_PEND", (string)$pending); $this->SetBuffer("CUR_{$ch}_HITS", "0"); + return $lastVal; } - $tolW = max(50.0, $tolW); + $tolW = max(100.0, $tolW); + if (abs($raw - $pending) <= $tolW) { $hits++; + if ($hits >= $needHits) { - $lastVal = $raw; + $lastVal = $this->MoveTowards($lastVal, $raw, $maxRampWPerSec * $dt); $hits = 0; - $this->SetBuffer("CUR_{$ch}_VAL", (string)$lastVal); } - $this->SetBuffer("CUR_{$ch}_HITS", (string)$hits); } else { - if ($hits !== 0) { - $this->SetBuffer("CUR_{$ch}_HITS", "0"); - } + $lastVal = $this->MoveTowards($lastVal, $pending, $maxRampWPerSec * $dt); + $hits = 0; } + if (abs($lastVal) < 1.0) { + $lastVal = 0.0; + } + + $this->SetBuffer("CUR_{$ch}_VAL", (string)$lastVal); + $this->SetBuffer("CUR_{$ch}_PEND", (string)$pending); + $this->SetBuffer("CUR_{$ch}_HITS", (string)$hits); + return $lastVal; } @@ -620,6 +650,7 @@ class Bat_EV_SDL_V4 extends IPSModule $this->SetBuffer("CUR_{$ch}_VAL", ""); $this->SetBuffer("CUR_{$ch}_PEND", ""); $this->SetBuffer("CUR_{$ch}_HITS", ""); + $this->SetBuffer("CUR_{$ch}_TS", ""); } } @@ -813,6 +844,15 @@ class Bat_EV_SDL_V4 extends IPSModule return $data; } + private function MoveTowards(float $current, float $target, float $maxStep): float + { + if (abs($target - $current) <= $maxStep) { + return $target; + } + + return $current + (($target > $current) ? $maxStep : -$maxStep); + } + private function SetIdentValue(string $ident, $value): void { $id = @$this->GetIDForIdent($ident);