diff --git a/Abrechnung/module.php b/Abrechnung/module.php index 1843ee3..ea50eb1 100644 --- a/Abrechnung/module.php +++ b/Abrechnung/module.php @@ -186,119 +186,82 @@ private function CalculatePowerCosts($powerMeters, $tariffs, $userId, $from, $to } // 15-Minuten-Schritte - for ($ts = $from; $ts < $to; $ts += 900) { - $slotEnd = min($to, $ts + 900); + for ($ts = $from; $ts < $to; $ts += 900) { + $slotEnd = min($to, $ts + 900); - // Tarife abrufen - $pGrid = $this->getTariffPriceAt($tariffs, ['Netztarif'], $ts); - $pSolar = $this->getTariffPriceAt($tariffs, ['Solartarif'], $ts); - $pFeed = $this->getTariffPriceAt($tariffs, ['Einspeisetarif'], $ts); + $pGrid = $this->getTariffPriceAt($tariffs, ['Netztarif'], $ts); + $pSolar = $this->getTariffPriceAt($tariffs, ['Solartarif'], $ts); + $pFeed = $this->getTariffPriceAt($tariffs, ['Einspeisetarif'], $ts); - IPS_LogMessage('Abrechnung', sprintf("⏱ %s – %s | Tarife: Netz=%.3f Rp, Solar=%.3f Rp, Einspeise=%.3f Rp", - date('d.m.Y H:i', $ts), date('H:i', $slotEnd), - $pGrid ?? 0, $pSolar ?? 0, $pFeed ?? 0 - )); + $impTotal = 0.0; + $expTotal = 0.0; + $slot = []; - $impTotal = 0.0; - $expTotal = 0.0; - $slot = []; + foreach ($meters as $name => $mm) { + $impDelta = $expDelta = 0.0; - foreach ($meters as $name => $mm) { - $impDelta = 0.0; - $expDelta = 0.0; + if (!empty($mm['imp']) && IPS_VariableExists((int)$mm['imp'])) { + $impDelta = $this->readDelta((int)$mm['imp'], $ts, $slotEnd); + } + if (!empty($mm['exp']) && IPS_VariableExists((int)$mm['exp'])) { + $expDelta = $this->readDelta((int)$mm['exp'], $ts, $slotEnd); + } - if (!empty($mm['imp']) && IPS_VariableExists((int)$mm['imp'])) { - $impDelta = $this->readDelta((int)$mm['imp'], $ts, $slotEnd); - } - if (!empty($mm['exp']) && IPS_VariableExists((int)$mm['exp'])) { - $expDelta = $this->readDelta((int)$mm['exp'], $ts, $slotEnd); - } - - $slot[$name] = ['imp'=>$impDelta, 'exp'=>$expDelta]; + // Nur speichern, wenn wirklich Werte vorhanden + if ($impDelta > 0 || $expDelta > 0) { + $slot[$name] = ['imp' => $impDelta, 'exp' => $expDelta]; $impTotal += $impDelta; $expTotal += $expDelta; - IPS_LogMessage('Abrechnung', sprintf(" → %s: imp=%.4f, exp=%.4f", $name, $impDelta, $expDelta)); + IPS_LogMessage('Abrechnung', sprintf("🔹 %s: imp=%.5f, exp=%.5f", $name, $impDelta, $expDelta)); } + } - if ($impTotal <= 0 && $expTotal <= 0) continue; + if ($impTotal == 0 && $expTotal == 0) { + IPS_LogMessage('Abrechnung', "⏭ Kein Verbrauch im Intervall " . date('H:i', $ts) . "–" . date('H:i', $slotEnd)); + continue; + } + + // --- Verhältnis berechnen --- + if ($impTotal <= $expTotal && $expTotal > 0) { + $ratio = $impTotal / $expTotal; + IPS_LogMessage('Abrechnung', sprintf("⚙️ Fall 1: imp<=exp | imp=%.4f exp=%.4f ratio=%.4f", $impTotal, $expTotal, $ratio)); + } elseif ($impTotal > 0) { + $ratio = $expTotal / $impTotal; + IPS_LogMessage('Abrechnung', sprintf("⚙️ Fall 2: imp>exp | imp=%.4f exp=%.4f ratio=%.4f", $impTotal, $expTotal, $ratio)); + } else { + $ratio = 0; + IPS_LogMessage('Abrechnung', "⚙️ Keine gültige Division (impTotal/expTotal=0)"); + } + + // --- Verbrauch berechnen --- + foreach ($slot as $name => $v) { + $imp = $v['imp']; + $exp = $v['exp']; - // ===== Fall 1: import <= export ===== if ($impTotal <= $expTotal) { - $ratio = ($expTotal > 0) ? ($impTotal / $expTotal) : 0; - - foreach ($meters as $name => $_) { - $imp = $slot[$name]['imp']; - $exp = $slot[$name]['exp']; - - $acc[$name]['imp'] += $imp; - $acc[$name]['exp'] += $exp; - - $acc[$name]['solar_bezug'] += $imp; - $acc[$name]['netz_bezug'] += 0; - $acc[$name]['solareinspeisung']+= (1 - $ratio) * $exp; - $acc[$name]['solarverkauf'] += $ratio * $exp; - - if ($pSolar !== null) $acc[$name]['cost_solar'] += ($imp * $pSolar) / 100; - if ($pFeed !== null) $acc[$name]['rev_feedin'] += ((1 - $ratio) * $exp * $pFeed) / 100; - } - - IPS_LogMessage('Abrechnung', sprintf(" ⚙️ Fall 1 (imp<=exp): ratio=%.3f", $ratio)); + // Fall 1 + $acc[$name]['solar_bezug'] += $imp; + $acc[$name]['solareinspeisung']+= (1 - $ratio) * $exp; + $acc[$name]['solarverkauf'] += $ratio * $exp; + if ($pSolar !== null) $acc[$name]['cost_solar'] += ($imp * $pSolar) / 100; + if ($pFeed !== null) $acc[$name]['rev_feedin'] += ((1 - $ratio) * $exp * $pFeed) / 100; + } else { + // Fall 2 + $acc[$name]['solar_bezug'] += $ratio * $imp; + $acc[$name]['netz_bezug'] += (1 - $ratio) * $imp; + $acc[$name]['solarverkauf'] += $exp; + if ($pGrid !== null) $acc[$name]['cost_grid'] += ((1 - $ratio) * $imp * $pGrid) / 100; + if ($pSolar !== null) $acc[$name]['cost_solar'] += ($ratio * $imp * $pSolar) / 100; + if ($pFeed !== null) $acc[$name]['rev_feedin'] += ($exp * $pFeed) / 100; } - // ===== Fall 2: import > export ===== - else { - $ratio = ($impTotal > 0) ? ($expTotal / $impTotal) : 0; - - foreach ($meters as $name => $_) { - $imp = $slot[$name]['imp']; - $exp = $slot[$name]['exp']; - - $acc[$name]['imp'] += $imp; - $acc[$name]['exp'] += $exp; - - $acc[$name]['solar_bezug'] += $ratio * $imp; - $acc[$name]['netz_bezug'] += (1 - $ratio) * $imp; - $acc[$name]['solarverkauf'] += $exp; - - if ($pGrid !== null) $acc[$name]['cost_grid'] += ((1 - $ratio) * $imp * $pGrid) / 100; - if ($pSolar !== null) $acc[$name]['cost_solar'] += ($ratio * $imp * $pSolar) / 100; - if ($pFeed !== null) $acc[$name]['rev_feedin'] += ($exp * $pFeed) / 100; - } - - IPS_LogMessage('Abrechnung', sprintf(" ⚙️ Fall 2 (imp>exp): ratio=%.3f", $ratio)); - } + IPS_LogMessage('Abrechnung', sprintf( + "➡️ %s | imp=%.4f exp=%.4f ratio=%.4f grid=%.3f solar=%.3f feed=%.3f", + $name, $imp, $exp, $ratio, $pGrid ?? 0, $pSolar ?? 0, $pFeed ?? 0 + )); } - - // Ausgabe erzeugen - $grand = 0.0; - foreach ($acc as $name => $v) { - $sum = $v['cost_solar'] + $v['cost_grid'] - $v['rev_feedin']; - $grand += $sum; - - $html .= "