diff --git a/Abrechnung/form.json b/Abrechnung/form.json index 3f952ea..97aa22f 100644 --- a/Abrechnung/form.json +++ b/Abrechnung/form.json @@ -108,9 +108,9 @@ "edit": { "type": "Select", "options": [ - { "caption": "Strombezug", "value": "Strombezug" }, - { "caption": "Stromproduktion", "value": "Stromproduktion" }, - { "caption": "Solarstrombezug", "value": "Solarstrombezug" }, + { "caption": "Netztarif", "value": "Netztarif" }, + { "caption": "Einspeisetarif", "value": "Einspeisetarif" }, + { "caption": "Solartarif", "value": "Solartarif" }, { "caption": "Warmwasser", "value": "Warmwasser" }, { "caption": "Kaltwasser", "value": "Kaltwasser" }, { "caption": "Wärme", "value": "Wärme" } diff --git a/Abrechnung/module.php b/Abrechnung/module.php index 0e9556c..eb56e63 100644 --- a/Abrechnung/module.php +++ b/Abrechnung/module.php @@ -141,7 +141,6 @@ class Abrechnung extends IPSModule private function CalculatePowerCosts($powerMeters, $tariffs, $userId, $from, $to) { - // Tabelle Kopf $html = " @@ -149,19 +148,18 @@ private function CalculatePowerCosts($powerMeters, $tariffs, $userId, $from, $to - - + + - - + "; - // Sammler je Zähler - $acc = []; // name => arrays + // Initialisierung + $acc = []; - // Index Zähler für User + // Benutzerzähler laden $meters = []; foreach ($powerMeters as $m) { if ($m['user_id'] != $userId) continue; @@ -174,14 +172,14 @@ private function CalculatePowerCosts($powerMeters, $tariffs, $userId, $from, $to $acc[$name] = [ 'imp'=>0.0,'exp'=>0.0, 'solar_bezug'=>0.0,'netz_bezug'=>0.0, - 'pv_einspeisung'=>0.0,'pv_verkauf'=>0.0, + 'solareinspeisung'=>0.0,'solarverkauf'=>0.0, 'cost_solar'=>0.0,'cost_grid'=>0.0, - 'rev_feedin'=>0.0,'rev_solar_sale'=>0.0 + 'rev_feedin'=>0.0 ]; } if (empty($meters)) { - $html .= "
ZählerExport (kWh) Solarbezug (kWh) Netzbezug (kWh)PV-Einspeisung (kWh)PV-Verkauf (kWh)Solareinspeisung (kWh)Solarverkauf (kWh) Kosten Solar (CHF) Kosten Netz (CHF)Ertrag Einspeise (CHF)Ertrag Verkauf (CHF)Ertrag Einspeisung (CHF) Summe (CHF)
Keine Stromzähler für diesen Benutzer

"; + $html .= "Keine Stromzähler für diesen Benutzer
"; return ['html'=>$html, 'sum'=>0.0]; } @@ -189,10 +187,15 @@ private function CalculatePowerCosts($powerMeters, $tariffs, $userId, $from, $to for ($ts = $from; $ts < $to; $ts += 900) { $slotEnd = min($to, $ts + 900); - // Deltas pro Zähler & Summen + // Tarife für diesen Zeitraum holen + $pGrid = $this->getTariffPriceAt($tariffs, ['Netztarif'], $ts); + $pSolar = $this->getTariffPriceAt($tariffs, ['Solartarif'], $ts); + $pFeed = $this->getTariffPriceAt($tariffs, ['Einspeisetarif'], $ts); + + // Deltas $impTotal = 0.0; $expTotal = 0.0; - $slot = []; // name => ['imp'=>x,'exp'=>y] + $slot = []; foreach ($meters as $name => $mm) { $impDelta = 0.0; @@ -205,79 +208,62 @@ private function CalculatePowerCosts($powerMeters, $tariffs, $userId, $from, $to $expDelta = $this->readDelta((int)$mm['exp'], $ts, $slotEnd); } - // kWh annehmen (oder deine Einheit – hier keine Umrechnung) - $impDelta = max(0.0, $impDelta); - $expDelta = max(0.0, $expDelta); - $slot[$name] = ['imp'=>$impDelta, 'exp'=>$expDelta]; $impTotal += $impDelta; $expTotal += $expDelta; } - // Tarife zum Slot-Start - $pGrid = $this->getTariffPriceAt($tariffs, ['netztarif','netzstrom','strombezug','netz'], $ts); // Rp/kWh - $pSolar = $this->getTariffPriceAt($tariffs, ['solar','solarstom','pv','eigenverbrauch'], $ts); // Rp/kWh - $pFeed = $this->getTariffPriceAt($tariffs, ['einspeisung','feedin','einspeisetarif'], $ts); // Rp/kWh - $pSolarSell = $this->getTariffPriceAt($tariffs, ['solarverkauf','pv-verkauf'], $ts); // Rp/kWh - if ($pSolarSell === null) $pSolarSell = $pSolar; // falls kein eigener Solarverkaufstarif + if ($impTotal <= 0 && $expTotal <= 0) continue; - // Falls alles 0 – Slot überspringen - if ($impTotal <= 0.0 && $expTotal <= 0.0) continue; - - // Case A: impTotal <= expTotal + // ===== Fall 1: import <= export ===== if ($impTotal <= $expTotal) { - $ratio = ($expTotal > 0.0) ? ($impTotal / $expTotal) : 0.0; + $ratio = ($expTotal > 0) ? ($impTotal / $expTotal) : 0; foreach ($meters as $name => $_) { $imp = $slot[$name]['imp']; $exp = $slot[$name]['exp']; - // Energiemengen + // Mengen $acc[$name]['imp'] += $imp; $acc[$name]['exp'] += $exp; - $acc[$name]['solar_bezug'] += $imp; // kompletter Import deckt sich aus PV (bis exp reicht) - $acc[$name]['netz_bezug'] += 0.0; - $acc[$name]['pv_verkauf'] += $ratio * $exp; // Anteil Export, der im Haus bleibt (verkauft als Solar) - $acc[$name]['pv_einspeisung'] += max(0.0, (1.0 - $ratio) * $exp); // Überschuss ins Netz - - // Kosten / Erträge (Rp → CHF) - $acc[$name]['cost_grid'] += 0.0; - if ($pSolarSell !== null) $acc[$name]['cost_solar'] += ($imp * $pSolarSell) / 100.0; - if ($pSolar !== null) $acc[$name]['rev_feedin'] += ($ratio * $exp * $pSolar) / 100.0; - if ($pFeed !== null) $acc[$name]['rev_solar_sale'] += (max(0.0, (1.0 - $ratio) * $exp) * $pFeed) / 100.0; - } - } - // Case B: impTotal > expTotal - else { - $ratio = ($impTotal > 0.0) ? ($expTotal / $impTotal) : 0.0; - - foreach ($meters as $name => $_) { - $imp = $slot[$name]['imp']; - $exp = $slot[$name]['exp']; - - // Energiemengen - $acc[$name]['imp'] += $imp; - $acc[$name]['exp'] += $exp; - - $acc[$name]['solar_bezug'] += $ratio * $imp; // Teil des Imports aus PV - $acc[$name]['netz_bezug'] += max(0.0, (1.0 - $ratio) * $imp); - $acc[$name]['pv_verkauf'] += $exp; // gesamter Export wird intern verkauft - // keine Einspeisung in diesem Zweig lt. Vorgabe + $acc[$name]['solar_bezug'] += $imp; + $acc[$name]['netz_bezug'] += 0; + $acc[$name]['solareinspeisung']+= (1 - $ratio) * $exp; + $acc[$name]['solarverkauf'] += $ratio * $exp; // Kosten / Erträge - if ($pGrid !== null) $acc[$name]['cost_grid'] += (max(0.0, (1.0 - $ratio) * $imp) * $pGrid) / 100.0; - if ($pSolar !== null) $acc[$name]['cost_solar'] += (($ratio * $imp) * $pSolar) / 100.0; - if ($pSolarSell !== null) $acc[$name]['rev_feedin'] += ($exp * $pSolarSell) / 100.0; // „Solareinspeiseertrag“ laut Vorgabe - // Solarverkauf-Ertrag bleibt hier 0 (lt. Spezifikation) + if ($pSolar !== null) $acc[$name]['cost_solar'] += ($imp * $pSolar) / 100; + if ($pFeed !== null) $acc[$name]['rev_feedin'] += ((1 - $ratio) * $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; } } } - // Ausgabe-Zeilen je Zähler + // Ausgabe $grand = 0.0; foreach ($acc as $name => $v) { - $sum = $v['cost_solar'] + $v['cost_grid'] - $v['rev_feedin'] - $v['rev_solar_sale']; + $sum = $v['cost_solar'] + $v['cost_grid'] - $v['rev_feedin']; $grand += $sum; $html .= " @@ -286,19 +272,17 @@ private function CalculatePowerCosts($powerMeters, $tariffs, $userId, $from, $to " . number_format($v['exp'], 3) . " " . number_format($v['solar_bezug'], 3) . " " . number_format($v['netz_bezug'], 3) . " - " . number_format($v['pv_einspeisung'], 3) . " - " . number_format($v['pv_verkauf'], 3) . " + " . number_format($v['solareinspeisung'], 3) . " + " . number_format($v['solarverkauf'], 3) . " " . number_format($v['cost_solar'], 2) . " " . number_format($v['cost_grid'], 2) . " " . number_format($v['rev_feedin'], 2) . " - " . number_format($v['rev_solar_sale'], 2) . " " . number_format($sum, 2) . " "; } - // Total $html .= " - Total Stromkosten: + Total Stromkosten: " . number_format($grand, 2) . "
"; @@ -307,6 +291,7 @@ private function CalculatePowerCosts($powerMeters, $tariffs, $userId, $from, $to + // ====================== Nebenkosten ====================== private function CalculateAdditionalCosts($waterMeters, $tariffs, $userId, $from, $to)