From 558fd9aa4e57e8e4c5cdd147570c677ff050e904 Mon Sep 17 00:00:00 2001 From: DanielHaefliger Date: Fri, 12 Dec 2025 08:14:12 +0100 Subject: [PATCH] no message --- Abrechnung/module.php | 185 +++++++++++++++++++++--------------------- 1 file changed, 92 insertions(+), 93 deletions(-) diff --git a/Abrechnung/module.php b/Abrechnung/module.php index f98bac9..4ea4791 100644 --- a/Abrechnung/module.php +++ b/Abrechnung/module.php @@ -272,7 +272,7 @@ class Abrechnung extends IPSModule return; } - // 15-Minuten-Schritte + // 15-Minuten-Schritte for ($ts = $from; $ts < $to; $ts += 900) { $slotEnd = min($to, $ts + 900); @@ -281,122 +281,121 @@ class Abrechnung extends IPSModule $pSolar = $this->getTariffPriceAt($tariffs, ['Solartarif'], $ts); $pFeed = $this->getTariffPriceAt($tariffs, ['Einspeisetarif'], $ts); - foreach ($metersByUser as $userId => $meters) { + // ========================================================== + // 1) GLOBAL DELTAS EINMAL BERECHNEN + // ========================================================== + $globalImpTotal = 0.0; + $globalExpTotal = 0.0; + $globalSlot = []; - $impTotal = 0.0; - $expTotal = 0.0; - $slot = []; + foreach ($powerMeters as $m) { -// Deltas je Zähler des Users -foreach ($meters as $name => $mm) { + $name = $m['name']; + $impDelta = 0.0; + $expDelta = 0.0; - $impDelta = 0.0; - $expDelta = 0.0; + // IMPORT + if (!empty($m['var_consumption']) && IPS_VariableExists((int)$m['var_consumption'])) { + $impDelta = $this->getDeltaFromArchive((int)$m['var_consumption'], $ts, $slotEnd); + } - // IMPORT - if (!empty($mm['importVar'])) { - $varId = (int)$mm['importVar']; - if (IPS_VariableExists($varId)) { - $impDelta = $this->getDeltaFromArchive($varId, $ts, $slotEnd); - } - } + // EXPORT + if (!empty($m['var_feed']) && IPS_VariableExists((int)$m['var_feed'])) { + $expDelta = $this->getDeltaFromArchive((int)$m['var_feed'], $ts, $slotEnd); + } - // EXPORT - if (!empty($mm['exportVar'])) { - $varId = (int)$mm['exportVar']; - if (IPS_VariableExists($varId)) { - $expDelta = $this->getDeltaFromArchive($varId, $ts, $slotEnd); - } - } + if ($impDelta > 0.0 || $expDelta > 0.0) { + $globalSlot[$name] = [ + 'imp' => $impDelta, + 'exp' => $expDelta, + 'user_id' => (int)$m['user_id'] + ]; - // Nur hinzufügen, wenn Werte vorhanden sind - if ($impDelta > 0.0 || $expDelta > 0.0) { + $globalImpTotal += $impDelta; + $globalExpTotal += $expDelta; + } + } - $slot[$name] = [ - 'imp' => $impDelta, - 'exp' => $expDelta - ]; + // Wenn keine Imp/Exp vorhanden → nächster Slot + if ($globalImpTotal == 0.0 && $globalExpTotal == 0.0) { + continue; + } - $impTotal += $impDelta; - $expTotal += $expDelta; + // ========================================================== + // 2) Verhältnis PV / Netz + // ========================================================== + if ($globalImpTotal == 0.0 && $globalExpTotal > 0.0) { + // nur Export → PV deckt alles + $ratio = 0.0; + $pvCoversAll = true; - } + } elseif ($globalExpTotal == 0.0 && $globalImpTotal > 0.0) { + // nur Import → Netz deckt alles + $ratio = 0.0; + $pvCoversAll = false; -} + } elseif ($globalImpTotal <= $globalExpTotal) { + // PV produziert genug + $ratio = $globalExpTotal ? ($globalImpTotal / $globalExpTotal) : 0.0; + $pvCoversAll = true; - // Logging der Eingangswerte + } else { + // Netzbezug notwendig + $ratio = $globalImpTotal ? ($globalExpTotal / $globalImpTotal) : 0.0; + $pvCoversAll = false; + } - // Fall 1: Weder Import noch Export -> nichts zu berechnen - if ($impTotal == 0.0 && $expTotal == 0.0) { + // ========================================================== + // 3) PRO USER VERTEILEN + // ========================================================== + foreach ($globalSlot as $name => $v) { + $userId = $v['user_id']; + + // Falls User nicht im Cache ist → ignorieren + if (!isset($this->powerCostCache[$userId][$name])) { continue; } - // Verhältnis PV / Netz pro User - if ($impTotal == 0.0 && $expTotal > 0.0) { - // Kein Import, aber Export → PV deckt alles - $ratio = 0.0; - $pvCoversAll = true; + $imp = $v['imp']; + $exp = $v['exp']; - } elseif ($expTotal == 0.0 && $impTotal > 0.0) { - // Kein Export, aber Import → Netz deckt alles - $ratio = 0.0; - $pvCoversAll = false; + // Totale speichern + $this->powerCostCache[$userId][$name]['imp'] += $imp; + $this->powerCostCache[$userId][$name]['exp'] += $exp; - } elseif ($impTotal <= $expTotal) { - // PV produziert genug oder mehr - $ratio = $expTotal > 0 ? ($impTotal / $expTotal) : 0.0; - $pvCoversAll = true; + // PV deckt alles + if ($pvCoversAll) { + $this->powerCostCache[$userId][$name]['solar_bezug'] += $imp; + $this->powerCostCache[$userId][$name]['solareinspeisung'] += (1 - $ratio) * $exp; + $this->powerCostCache[$userId][$name]['solarverkauf'] += $ratio * $exp; + if ($pSolar !== null) { + $this->powerCostCache[$userId][$name]['cost_solar'] += ($imp * $pSolar) / 100.0; + } + if ($pFeed !== null) { + $this->powerCostCache[$userId][$name]['rev_feedin'] += ((1 - $ratio) * $exp * $pFeed) / 100.0; + $this->powerCostCache[$userId][$name]['rev_zev'] += ($ratio * $exp * $pSolar) / 100.0; + } + + // Netz deckt einen Teil } else { - // Import ist größer als Export → Netz deckt den Rest - $ratio = $impTotal > 0 ? ($expTotal / $impTotal) : 0.0; - $pvCoversAll = false; - } + $this->powerCostCache[$userId][$name]['solar_bezug'] += $ratio * $imp; + $this->powerCostCache[$userId][$name]['netz_bezug'] += (1 - $ratio) * $imp; + $this->powerCostCache[$userId][$name]['solarverkauf'] += $exp; - - - // Werte pro Zähler verteilen - foreach ($slot as $name => $v) { - $imp = $v['imp']; - $exp = $v['exp']; - - $this->powerCostCache[$userId][$name]['imp'] += $imp; - $this->powerCostCache[$userId][$name]['exp'] += $exp; - - if ($pvCoversAll) { - // PV deckt gesamten Verbrauch - $this->powerCostCache[$userId][$name]['solar_bezug'] += $imp; - $this->powerCostCache[$userId][$name]['solareinspeisung'] += (1 - $ratio) * $exp; - $this->powerCostCache[$userId][$name]['solarverkauf'] += $ratio * $exp; - - if ($pSolar !== null) { - $this->powerCostCache[$userId][$name]['cost_solar'] += ($imp * $pSolar) / 100.0; - } - if ($pFeed !== null) { - $this->powerCostCache[$userId][$name]['rev_feedin'] += ((1 - $ratio) * $exp * $pFeed) / 100.0; - $this->powerCostCache[$userId][$name]['rev_zev'] += (($ratio) * $exp * $pSolar) / 100.0; - - } - } else { - // Teil Netzbezug - $this->powerCostCache[$userId][$name]['solar_bezug'] += $ratio * $imp; - $this->powerCostCache[$userId][$name]['netz_bezug'] += (1 - $ratio) * $imp; - $this->powerCostCache[$userId][$name]['solarverkauf'] += $exp; - - if ($pGrid !== null) { - $this->powerCostCache[$userId][$name]['cost_grid'] += ((1 - $ratio) * $imp * $pGrid) / 100.0; - } - if ($pSolar !== null) { - $this->powerCostCache[$userId][$name]['cost_solar'] += ($ratio * $imp * $pSolar) / 100.0; - } - if ($pFeed !== null) { - $this->powerCostCache[$userId][$name]['rev_zev'] += ($exp * $pSolar) / 100.0; - - } + if ($pGrid !== null) { + $this->powerCostCache[$userId][$name]['cost_grid'] += ((1 - $ratio) * $imp * $pGrid) / 100.0; + } + if ($pSolar !== null) { + $this->powerCostCache[$userId][$name]['cost_solar'] += ($ratio * $imp * $pSolar) / 100.0; + } + if ($pFeed !== null) { + $this->powerCostCache[$userId][$name]['rev_zev'] += ($exp * $pSolar) / 100.0; } } } } + } private function GetCalculatedPowerCosts($userId)