foreach ($filteredTariffs as $t) { $startTs = intval($t['start_ts']); $endTs = intval($t['end_ts']); if ($startTs === 0 || $endTs === 0) continue; if ($startTs <= $currentStart && $currentStart <= $endTs) { $activeTariff = $t; IPS_LogMessage('Abrechnung', sprintf( " ✅ Tarif erkannt: %.2f Rp gültig %s → %s", floatval($t['price']), date('d.m.Y H:i', $startTs), date('d.m.Y H:i', $endTs) )); break; } } // 🔹 Falls kein aktiver Tarif → 0 Rp if (!$activeTariff) { IPS_LogMessage('Abrechnung', "⚠ Kein Tarif aktiv bei " . date('d.m.Y H:i', $currentStart) . " → 0 Rp"); $activeTariff = [ 'start_ts' => $currentStart, 'end_ts' => $to, 'price' => 0.0, 'unit_type'=> $type ]; } $tariffEnd = intval($activeTariff['end_ts']); $tariffPrice = floatval($activeTariff['price']); $tariffLabel = number_format($tariffPrice, 2, ',', ''); // 🔹 Start- & Endwerte aus Archiv $startValue = $this->GetValueAt($varId, $currentStart, true); if ($startValue === null) { IPS_LogMessage('Abrechnung', "⚠ Kein Startwert für " . date('d.m.Y H:i', $currentStart)); break; } $segmentEnd = ($tariffEnd < $to) ? $tariffEnd : $to; $endValue = $this->GetValueAt($varId, $segmentEnd, true); if ($endValue === null) { IPS_LogMessage('Abrechnung', "⚠ Kein Endwert für " . date('d.m.Y H:i', $segmentEnd)); break; } // 🔹 Verbrauch & Kosten $verbrauch = max(0, $endValue - $startValue); $kosten = round(($tariffPrice / 100) * $verbrauch, 2); $totalCost += $kosten; IPS_LogMessage('Abrechnung', sprintf( " 📊 Segment %d: %.3f → %.3f (Δ=%.3f) | Tarif=%.3f Rp | Kosten=%.2f CHF", $segmentIndex, $startValue, $endValue, $verbrauch, $tariffPrice, $kosten )); // 🔹 Tabellenzeile $rows .= " {$meter['name']} {$type} " . date('d.m.Y H:i', $currentStart) . " " . date('d.m.Y H:i', $segmentEnd) . " " . number_format($startValue, 2) . " " . number_format($endValue, 2) . " " . number_format($verbrauch, 2) . " {$tariffLabel} " . number_format($kosten, 2) . " "; // 🔹 Neuen Startpunkt setzen (FIX: +1 Sekunde nach Tarifende) if ($tariffEnd < $to) { $currentStart = $tariffEnd + 1; } else { break; } $segmentIndex++; } // Fallback, falls keine Segmente erzeugt wurden if ($rows === '') { IPS_LogMessage('Abrechnung', "⚠ Keine Segmente erzeugt, Fallback auf Gesamtzeitraum"); $startValue = $this->GetValueAt($varId, $from, false); $endValue = $this->GetValueAt($varId, $to, true); $verbrauch = max(0, $endValue - $startValue); $rows = " {$meter['name']} {$type} " . date('d.m.Y H:i', $from) . " " . date('d.m.Y H:i', $to) . " " . number_format($startValue, 2) . " " . number_format($endValue, 2) . " " . number_format($verbrauch, 2) . " 0 0.00 "; } IPS_LogMessage('Abrechnung', sprintf("✅ [AddMeterToPDFRow] Fertig: %.2f CHF total, %d Segmente", $totalCost, $segmentIndex - 1)); return ['row' => $rows, 'value' => $totalCost]; } }