no message

This commit is contained in:
mh
2026-05-12 13:30:31 +02:00
parent b013e90616
commit 6f335c1fc8
2 changed files with 175 additions and 41 deletions
+29 -5
View File
@@ -167,11 +167,32 @@
"type": "NumberSpinner",
"name": "UpdateInterval",
"caption": "Update Intervall",
"suffix": "S",
"suffix": " s",
"minimum": 1,
"digits": 0
},
{
"type": "Label",
"caption": "EV-SoC Nachberechnung:\n\nAlle X Stunden wird geprüft, ob der virtuelle SDL-SoC bei 50% liegt.\nWenn ja, wird der EV-SoC anhand der physischen Batterie-SoCs neu berechnet.\nDie EV-Toleranz verhindert kleine unnötige Korrekturen.\n\n0 Stunden = automatische EV-Neuberechnung deaktiviert."
},
{
"type": "NumberSpinner",
"name": "EV_Recalc_IntervalHours",
"caption": "EV SoC neu berechnen alle",
"suffix": " h",
"minimum": 0,
"maximum": 168,
"digits": 2
},
{
"type": "NumberSpinner",
"name": "EV_Recalc_TolerancePct",
"caption": "EV Recalc Toleranz",
"suffix": " %",
"minimum": 0,
"maximum": 100,
"digits": 2
},
{
"type": "CheckBox",
"name": "FilterAktiv",
@@ -184,7 +205,8 @@
{
"type": "NumberSpinner",
"name": "FilterTolerancePct",
"caption": "Filter Toleranz (%)",
"caption": "Filter Toleranz",
"suffix": " %",
"minimum": 0,
"maximum": 100,
"digits": 1
@@ -192,7 +214,8 @@
{
"type": "NumberSpinner",
"name": "FilterRampWPerSec",
"caption": "Filter Rampe (W/s)",
"caption": "Filter Rampe",
"suffix": " W/s",
"minimum": 100,
"maximum": 20000,
"digits": 0
@@ -202,7 +225,8 @@
"name": "FilterHits",
"caption": "Filter Treffer bis Übernahme",
"minimum": 1,
"maximum": 10
"maximum": 10,
"digits": 0
}
]
}
+110
View File
@@ -18,6 +18,8 @@ class Bat_EV_SDL_V4 extends IPSModule
$this->RegisterPropertyFloat("FilterTolerancePct", 15.0); // %
$this->RegisterPropertyFloat("FilterRampWPerSec", 2000.0); // W/s
$this->RegisterPropertyInteger("FilterHits", 1);
$this->RegisterPropertyFloat("EV_Recalc_IntervalHours", 6.0);
$this->RegisterPropertyFloat("EV_Recalc_TolerancePct", 2.0);
// Status
$this->RegisterVariableBoolean("State", "Aktiv", "~Switch", 1);
@@ -425,6 +427,7 @@ class Bat_EV_SDL_V4 extends IPSModule
$eSDL = ($sdlTotal > 0.0) ? $sdlTotal * $lastSdlPct / 100.0 : 0.0;
$eEV = ($evTotal > 0.0) ? $evTotal * $lastEvPct / 100.0 : 0.0;
$this->MaybeRecalculateEVFromPhysical($plan, $eSDL, $eEV, $sdlTotal, $evTotal);
$this->SetBuffer("Int_E_SDL_kWh", (string)$eSDL);
$this->SetBuffer("Int_E_EV_kWh", (string)$eEV);
$this->SetBuffer("Int_LastTs", (string)$now);
@@ -916,6 +919,113 @@ class Bat_EV_SDL_V4 extends IPSModule
}
private function MaybeRecalculateEVFromPhysical(array $plan, float $eSDL, float &$eEV, float $sdlTotal, float $evTotal): void
{
if ($evTotal <= 0.0 || $sdlTotal <= 0.0) {
return;
}
$intervalHours = max(0.0, (float)$this->ReadPropertyFloat("EV_Recalc_IntervalHours"));
if ($intervalHours <= 0.0) {
return;
}
$now = microtime(true);
$lastCheckTs = (float)$this->GetBufferSafe("EV_Recalc_LastCheckTs");
// Nur alle X Stunden prüfen
if (
$lastCheckTs > 0.0 &&
($now - $lastCheckTs) < ($intervalHours * 3600.0)
) {
return;
}
$this->SetBuffer("EV_Recalc_LastCheckTs", (string)$now);
// SDL muss bei 50% sein
$sdlPct = ($eSDL / $sdlTotal) * 100.0;
if (abs($sdlPct - 50.0) > 0.001) {
$this->SendDebug(
"EV_Recalc",
"Skip: SDL nicht bei 50%, aktuell=" . round($sdlPct, 3) . "%",
0
);
return;
}
$newEVkWh = 0.0;
foreach (($plan["bats"] ?? []) as $bat) {
$capKWh = (float)($bat["capKWh"] ?? 0.0);
$socVarId = (int)($bat["socVarId"] ?? 0);
$realSocPct = $this->ReadSocPercent($socVarId);
$realKWh = $capKWh * $realSocPct / 100.0;
$underKWh = (float)($bat["underKWh"] ?? 0.0);
// Maximales EV Fenster dieser Batterie
$evBatTotal = (float)($bat["EV_kWh_total"] ?? 0.0);
// EV Anteil relativ zur unteren Grenze
$evPart = $realKWh - $underKWh;
// Begrenzung:
// unter underKWh => 0
// über upKWh => max EV Fenster
$evPart = max(0.0, min($evBatTotal, $evPart));
$newEVkWh += $evPart;
}
// Global begrenzen
$newEVkWh = max(0.0, min($evTotal, $newEVkWh));
$newEVpct = ($evTotal > 0.0)
? ($newEVkWh / $evTotal * 100.0)
: 0.0;
$oldEVpct = ($evTotal > 0.0)
? ($eEV / $evTotal * 100.0)
: 0.0;
$tolPct = max(0.0, (float)$this->ReadPropertyFloat("EV_Recalc_TolerancePct"));
// Nur übernehmen wenn Differenz gross genug
if (abs($newEVpct - $oldEVpct) <= $tolPct) {
$this->SendDebug(
"EV_Recalc",
"Skip: Differenz innerhalb Toleranz. Alt=" .
round($oldEVpct, 3) .
"% Neu=" .
round($newEVpct, 3) .
"%",
0
);
return;
}
$eEV = $newEVkWh;
$this->SendDebug(
"EV_Recalc",
"EV neu berechnet. Alt=" .
round($oldEVpct, 3) .
"% Neu=" .
round($newEVpct, 3) .
"%",
0
);
}
private function RefreshDynamicPlanValues(array $plan): array
{
foreach ($plan["bats"] as &$bat) {