From abd6016491891e0035435ae69b95bd80b544ec64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=A4fliger?= Date: Wed, 5 Nov 2025 07:29:04 +0100 Subject: [PATCH] no message --- Abrechnung/module.php | 98 ++++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 39 deletions(-) diff --git a/Abrechnung/module.php b/Abrechnung/module.php index 714ed2e..c29b340 100644 --- a/Abrechnung/module.php +++ b/Abrechnung/module.php @@ -243,92 +243,112 @@ private function GetValueAt(int $varId, int $timestamp, bool $nearestAfter = fal private function AddMeterToPDFRow($meter, $tariffs, $from, $to, $type) { - $startValTotal = $this->GetValueAt($meter['var_consumption'], $from, false); - $endValTotal = $this->GetValueAt($meter['var_consumption'], $to, true); - - IPS_LogMessage('Abrechnung', "Meter {$meter['name']} ($type) von " . date('d.m.Y H:i', $from) . " bis " . date('d.m.Y H:i', $to) . ": start=$startValTotal, end=$endValTotal"); - - if ($startValTotal === null || $endValTotal === null) { - return ['row' => '', 'value' => 0]; - } - - $totalDiff = max(0, $endValTotal - $startValTotal); - if ($totalDiff <= 0) { - return ['row' => '', 'value' => 0]; - } - $rows = ''; $totalCost = 0.0; - // Filtere Tarife nur für den relevanten Typ (z. B. Strom / Wasser) - $tariffs = array_filter($tariffs, function($t) use ($type) { + $varId = $meter['var_consumption']; + if (!IPS_VariableExists($varId)) { + IPS_LogMessage('Abrechnung', "❌ Variable {$varId} für {$meter['name']} nicht gefunden"); + return ['row' => '', 'value' => 0]; + } + + // Filtere Tarife für diesen Typ (z. B. "Strombezug" oder "Warmwasser") + $tariffs = array_filter($tariffs, function ($t) use ($type) { return strtolower($t['unit_type']) == strtolower($type); }); + if (empty($tariffs)) { + IPS_LogMessage('Abrechnung', "⚠ Keine passenden Tarife für $type gefunden"); + return ['row' => '', 'value' => 0]; + } + // Sortiere Tarife chronologisch - usort($tariffs, function($a, $b) { + usort($tariffs, function ($a, $b) { return strtotime($a['start']) <=> strtotime($b['start']); }); - $currentStart = $from; - $currentStartVal = $startValTotal; - - while ($currentStart < $to) { - // passenden Tarif zum aktuellen Zeitpunkt finden + $current = $from; + while ($current < $to) { + // passenden Tarif für aktuellen Zeitpunkt finden $activeTariff = null; foreach ($tariffs as $t) { $tariffStart = strtotime($t['start']); $tariffEnd = strtotime($t['end']); - if ($currentStart >= $tariffStart && $currentStart < $tariffEnd) { + if ($current >= $tariffStart && $current < $tariffEnd) { $activeTariff = $t; break; } } + // wenn kein aktiver Tarif gefunden → Nulltarif bis nächster Start oder Rechnungsende if ($activeTariff === null) { - // kein Tarif gefunden – nehme Nulltarif bis zum nächsten bekannten Start oder Ende $nextTariffStart = $to; foreach ($tariffs as $t) { $ts = strtotime($t['start']); - if ($ts > $currentStart && $ts < $nextTariffStart) { + if ($ts > $current && $ts < $nextTariffStart) { $nextTariffStart = $ts; } } + $segmentStart = $current; $segmentEnd = min($nextTariffStart, $to); $segmentTariff = 0.0; } else { + $segmentStart = $current; $segmentEnd = min(strtotime($activeTariff['end']), $to); $segmentTariff = floatval($activeTariff['price']); } - // Verbrauchsanteil über Zeitverhältnis - $segmentFraction = ($segmentEnd - $currentStart) / ($to - $from); - $segmentDiff = $totalDiff * $segmentFraction; + // Zählerstände direkt aus Archiv + $startVal = $this->GetValueAt($varId, $segmentStart, false); + $endVal = $this->GetValueAt($varId, $segmentEnd, true); - $segmentStartVal = $currentStartVal; - $segmentEndVal = $segmentStartVal + $segmentDiff; + if ($startVal === null || $endVal === null) { + IPS_LogMessage('Abrechnung', "⚠ Keine Werte im Archiv gefunden für {$meter['name']} ($type)"); + $current = $segmentEnd; + continue; + } - $segmentCostCHF = ($segmentTariff / 100) * $segmentDiff; + $diff = max(0, $endVal - $startVal); + $costCHF = ($segmentTariff / 100) * $diff; $rows .= " {$meter['name']} $type - " . date('d.m.Y H:i', $currentStart) . " + " . date('d.m.Y H:i', $segmentStart) . " " . date('d.m.Y H:i', $segmentEnd) . " - " . number_format($segmentStartVal, 2) . " - " . number_format($segmentEndVal, 2) . " - " . number_format($segmentDiff, 2) . " + " . number_format($startVal, 2) . " + " . number_format($endVal, 2) . " + " . number_format($diff, 2) . " " . number_format($segmentTariff, 2) . " - " . number_format($segmentCostCHF, 2) . " + " . number_format($costCHF, 2) . " "; - $totalCost += $segmentCostCHF; - $currentStart = $segmentEnd; - $currentStartVal = $segmentEndVal; + $totalCost += $costCHF; + $current = $segmentEnd; + } + + if ($rows == '') { + // Falls keine Tarifzeile ermittelt wurde + $startVal = $this->GetValueAt($varId, $from, false); + $endVal = $this->GetValueAt($varId, $to, true); + $diff = max(0, $endVal - $startVal); + $rows .= " + + {$meter['name']} + $type + " . date('d.m.Y H:i', $from) . " + " . date('d.m.Y H:i', $to) . " + " . number_format($startVal, 2) . " + " . number_format($endVal, 2) . " + " . number_format($diff, 2) . " + 0 + 0.00 + "; } return ['row' => $rows, 'value' => $totalCost]; } + } \ No newline at end of file