no message
This commit is contained in:
@@ -126,6 +126,19 @@ class Abrechnung extends IPSModule
|
|||||||
// ====================== Nebenkosten ======================
|
// ====================== Nebenkosten ======================
|
||||||
private function CalculatePowerCosts($powerMeters, $tariffs, $userId, $from, $to)
|
private function CalculatePowerCosts($powerMeters, $tariffs, $userId, $from, $to)
|
||||||
{
|
{
|
||||||
|
IPS_LogMessage("ABR", "====================== START CalculatePowerCosts ======================");
|
||||||
|
IPS_LogMessage("ABR", "UserId: $userId | From: $from (" . date("d.m.Y H:i", $from) . ") | To: $to (" . date("d.m.Y H:i", $to) . ")");
|
||||||
|
|
||||||
|
// ---- Tarife Debug ----
|
||||||
|
IPS_LogMessage("ABR", "Geladene Tarife:");
|
||||||
|
foreach ($tariffs as $t) {
|
||||||
|
IPS_LogMessage("ABR", " Tarif: type=" . ($t['unit_type'] ?? '?') .
|
||||||
|
" price=" . ($t['price'] ?? '?') .
|
||||||
|
" start=" . json_encode($t['start']) .
|
||||||
|
" end=" . json_encode($t['end']));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Stromzähler für diesen Benutzer sammeln ----
|
||||||
$html = "<table border='1' cellspacing='0' cellpadding='3' width='100%' style='font-size:8px;'>
|
$html = "<table border='1' cellspacing='0' cellpadding='3' width='100%' style='font-size:8px;'>
|
||||||
<tr style='background-color:#f0f0f0;'>
|
<tr style='background-color:#f0f0f0;'>
|
||||||
<th>Zähler</th>
|
<th>Zähler</th>
|
||||||
@@ -144,17 +157,23 @@ private function CalculatePowerCosts($powerMeters, $tariffs, $userId, $from, $to
|
|||||||
$acc = [];
|
$acc = [];
|
||||||
$meters = [];
|
$meters = [];
|
||||||
|
|
||||||
// Alle Stromzähler des Users vorbereiten
|
IPS_LogMessage("ABR", "Suche nach Stromzählern für userId=$userId");
|
||||||
|
|
||||||
foreach ($powerMeters as $m) {
|
foreach ($powerMeters as $m) {
|
||||||
if ($m['user_id'] != $userId) {
|
IPS_LogMessage("ABR", " Prüfe Zähler: name=" . $m['name'] . " user_id=" . $m['user_id']);
|
||||||
|
|
||||||
|
if ($m['user_id'] != $userId)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
$name = $m['name'];
|
$name = $m['name'];
|
||||||
$meters[$name] = [
|
$meters[$name] = [
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'imp' => $m['var_import'] ?? null,
|
'imp' => $m['var_import'] ?? null,
|
||||||
'exp' => $m['var_export'] ?? null
|
'exp' => $m['var_export'] ?? null
|
||||||
];
|
];
|
||||||
|
|
||||||
|
IPS_LogMessage("ABR", " → Zugeordnet: $name | ImportVar=" . $meters[$name]['imp'] . " ExportVar=" . $meters[$name]['exp']);
|
||||||
|
|
||||||
$acc[$name] = [
|
$acc[$name] = [
|
||||||
'imp' => 0.0,
|
'imp' => 0.0,
|
||||||
'exp' => 0.0,
|
'exp' => 0.0,
|
||||||
@@ -169,118 +188,146 @@ private function CalculatePowerCosts($powerMeters, $tariffs, $userId, $from, $to
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (empty($meters)) {
|
if (empty($meters)) {
|
||||||
|
IPS_LogMessage("ABR", "⚠ Keine Stromzähler für diesen Benutzer gefunden!");
|
||||||
$html .= "<tr><td colspan='11' align='center'>Keine Stromzähler für diesen Benutzer</td></tr></table><br>";
|
$html .= "<tr><td colspan='11' align='center'>Keine Stromzähler für diesen Benutzer</td></tr></table><br>";
|
||||||
return ['html' => $html, 'sum' => 0.0];
|
return ['html' => $html, 'sum' => 0.0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 15-Minuten-Schritte
|
IPS_LogMessage("ABR", "Gefundene Stromzähler: " . implode(", ", array_keys($meters)));
|
||||||
|
|
||||||
|
// ==== 15-MINUTEN INTERVALL-BERECHNUNG ====
|
||||||
|
IPS_LogMessage("ABR", "Beginne 15-Minuten Analyse...");
|
||||||
|
|
||||||
for ($ts = $from; $ts < $to; $ts += 900) {
|
for ($ts = $from; $ts < $to; $ts += 900) {
|
||||||
$slotEnd = min($to, $ts + 900);
|
$slotEnd = min($to, $ts + 900);
|
||||||
|
IPS_LogMessage("ABR", "----- Intervall " . date("d.m.Y H:i", $ts) . " - " . date("d.m.Y H:i", $slotEnd) . " -----");
|
||||||
|
|
||||||
// Tarife je Intervall (Rp/kWh)
|
// Tarife für dieses Intervall
|
||||||
$pGrid = $this->getTariffPriceAt($tariffs, ['Netztarif'], $ts);
|
$pGrid = $this->getTariffPriceAt($tariffs, ['Netztarif'], $ts);
|
||||||
$pSolar = $this->getTariffPriceAt($tariffs, ['Solartarif'], $ts);
|
$pSolar = $this->getTariffPriceAt($tariffs, ['Solartarif'], $ts);
|
||||||
$pFeed = $this->getTariffPriceAt($tariffs, ['Einspeisetarif'], $ts);
|
$pFeed = $this->getTariffPriceAt($tariffs, ['Einspeisetarif'], $ts);
|
||||||
|
|
||||||
|
IPS_LogMessage("ABR", " Tarife: Grid=" . var_export($pGrid, true) .
|
||||||
|
" Solar=" . var_export($pSolar, true) . " FeedIn=" . var_export($pFeed, true));
|
||||||
|
|
||||||
$impTotal = 0.0;
|
$impTotal = 0.0;
|
||||||
$expTotal = 0.0;
|
$expTotal = 0.0;
|
||||||
$slot = [];
|
$slot = [];
|
||||||
|
|
||||||
// Deltas pro Zähler für dieses Intervall holen
|
// --- Zählerwerte lesen ---
|
||||||
foreach ($meters as $name => $mm) {
|
foreach ($meters as $name => $mm) {
|
||||||
$impDelta = 0.0;
|
IPS_LogMessage("ABR", " → Zähler $name: Lade Werte Import=" . $mm['imp'] . " Export=" . $mm['exp']);
|
||||||
$expDelta = 0.0;
|
|
||||||
|
|
||||||
|
// Import delta
|
||||||
|
$impDelta = 0.0;
|
||||||
if (!empty($mm['imp']) && IPS_VariableExists((int)$mm['imp'])) {
|
if (!empty($mm['imp']) && IPS_VariableExists((int)$mm['imp'])) {
|
||||||
$impDelta = $this->readDelta((int)$mm['imp'], $ts, $slotEnd);
|
$impDelta = $this->readDelta((int)$mm['imp'], $ts, $slotEnd);
|
||||||
|
IPS_LogMessage("ABR", " Import-Delta = $impDelta");
|
||||||
|
} else {
|
||||||
|
IPS_LogMessage("ABR", " ⚠ Import-Variable existiert nicht!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Export delta
|
||||||
|
$expDelta = 0.0;
|
||||||
if (!empty($mm['exp']) && IPS_VariableExists((int)$mm['exp'])) {
|
if (!empty($mm['exp']) && IPS_VariableExists((int)$mm['exp'])) {
|
||||||
$expDelta = $this->readDelta((int)$mm['exp'], $ts, $slotEnd);
|
$expDelta = $this->readDelta((int)$mm['exp'], $ts, $slotEnd);
|
||||||
|
IPS_LogMessage("ABR", " Export-Delta = $expDelta");
|
||||||
|
} else {
|
||||||
|
IPS_LogMessage("ABR", " ⚠ Export-Variable existiert nicht!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($impDelta > 0 || $expDelta > 0) {
|
if ($impDelta > 0 || $expDelta > 0) {
|
||||||
$slot[$name] = ['imp' => $impDelta, 'exp' => $expDelta];
|
$slot[$name] = ['imp' => $impDelta, 'exp' => $expDelta];
|
||||||
$impTotal += $impDelta;
|
$impTotal += $impDelta;
|
||||||
$expTotal += $expDelta;
|
$expTotal += $expDelta;
|
||||||
|
|
||||||
|
IPS_LogMessage("ABR", " → Intervall Messung: imp=$impDelta exp=$expDelta");
|
||||||
|
} else {
|
||||||
|
IPS_LogMessage("ABR", " → Kein Verbrauch/Einspeisung im Intervall");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug-Logging (bei Bedarf auskommentieren)
|
IPS_LogMessage("ABR", " SUMME Intervall: impTotal=$impTotal | expTotal=$expTotal");
|
||||||
IPS_LogMessage('Abrechnung', sprintf(
|
|
||||||
"INTERVALL %s – %s | impTotal=%.5f expTotal=%.5f grid=%.3f solar=%.3f feed=%.3f",
|
|
||||||
date('H:i', $ts), date('H:i', $slotEnd),
|
|
||||||
$impTotal, $expTotal,
|
|
||||||
$pGrid ?? 0, $pSolar ?? 0, $pFeed ?? 0
|
|
||||||
));
|
|
||||||
|
|
||||||
if ($impTotal == 0 && $expTotal == 0) {
|
if ($impTotal == 0 && $expTotal == 0) {
|
||||||
|
IPS_LogMessage("ABR", " → Intervall übersprungen (keine Werte)");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- Verhältnis bestimmen ----
|
||||||
if ($impTotal <= $expTotal && $expTotal > 0) {
|
if ($impTotal <= $expTotal && $expTotal > 0) {
|
||||||
$ratio = $impTotal / $expTotal;
|
$ratio = $impTotal / $expTotal;
|
||||||
IPS_LogMessage('Abrechnung', sprintf("→ Fall 1 (imp<=exp) ratio=%.4f", $ratio));
|
IPS_LogMessage("ABR", " Fall: solar deckt Verbrauch → ratio=$ratio");
|
||||||
} elseif ($impTotal > 0) {
|
} elseif ($impTotal > 0) {
|
||||||
$ratio = $expTotal / $impTotal;
|
$ratio = $expTotal / $impTotal;
|
||||||
IPS_LogMessage('Abrechnung', sprintf("→ Fall 2 (imp>exp) ratio=%.4f", $ratio));
|
IPS_LogMessage("ABR", " Fall: teilweiser Netzbezug → ratio=$ratio");
|
||||||
} else {
|
} else {
|
||||||
|
IPS_LogMessage("ABR", " Fall: keine klare Zuordnung, ratio=0");
|
||||||
$ratio = 0.0;
|
$ratio = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zuweisung auf die einzelnen Zähler
|
// ---- Werte pro Zähler verrechnen ----
|
||||||
foreach ($slot as $name => $v) {
|
foreach ($slot as $name => $v) {
|
||||||
$imp = $v['imp'];
|
$imp = $v['imp'];
|
||||||
$exp = $v['exp'];
|
$exp = $v['exp'];
|
||||||
|
|
||||||
// ❗ NEU: Import/Export aufsummieren (bisher wurden sie nie erhöht!)
|
IPS_LogMessage("ABR", " → Verrechne für $name: imp=$imp exp=$exp ratio=$ratio");
|
||||||
|
|
||||||
|
// Summen Import/Export
|
||||||
$acc[$name]['imp'] += $imp;
|
$acc[$name]['imp'] += $imp;
|
||||||
$acc[$name]['exp'] += $exp;
|
$acc[$name]['exp'] += $exp;
|
||||||
|
|
||||||
if ($impTotal <= $expTotal) {
|
if ($impTotal <= $expTotal) {
|
||||||
// PV deckt alles (oder mehr als Verbrauch)
|
IPS_LogMessage("ABR", " → PV deckt alles");
|
||||||
|
|
||||||
$acc[$name]['solar_bezug'] += $imp;
|
$acc[$name]['solar_bezug'] += $imp;
|
||||||
$acc[$name]['solareinspeisung'] += (1 - $ratio) * $exp;
|
$acc[$name]['solareinspeisung'] += (1 - $ratio) * $exp;
|
||||||
$acc[$name]['solarverkauf'] += $ratio * $exp;
|
$acc[$name]['solarverkauf'] += $ratio * $exp;
|
||||||
|
|
||||||
if ($pSolar !== null) {
|
if ($pSolar !== null)
|
||||||
$acc[$name]['cost_solar'] += ($imp * $pSolar) / 100.0;
|
$acc[$name]['cost_solar'] += ($imp * $pSolar) / 100.0;
|
||||||
}
|
|
||||||
if ($pFeed !== null) {
|
if ($pFeed !== null)
|
||||||
$acc[$name]['rev_feedin'] += ((1 - $ratio) * $exp * $pFeed) / 100.0;
|
$acc[$name]['rev_feedin'] += ((1 - $ratio) * $exp * $pFeed) / 100.0;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Teilweise Netzbezug nötig
|
IPS_LogMessage("ABR", " → Netzbezug notwendig");
|
||||||
|
|
||||||
$acc[$name]['solar_bezug'] += $ratio * $imp;
|
$acc[$name]['solar_bezug'] += $ratio * $imp;
|
||||||
$acc[$name]['netz_bezug'] += (1 - $ratio) * $imp;
|
$acc[$name]['netz_bezug'] += (1 - $ratio) * $imp;
|
||||||
$acc[$name]['solarverkauf'] += $exp;
|
$acc[$name]['solarverkauf'] += $exp;
|
||||||
|
|
||||||
if ($pGrid !== null) {
|
if ($pGrid !== null)
|
||||||
$acc[$name]['cost_grid'] += ((1 - $ratio) * $imp * $pGrid) / 100.0;
|
$acc[$name]['cost_grid'] += ((1 - $ratio) * $imp * $pGrid) / 100.0;
|
||||||
}
|
|
||||||
if ($pSolar !== null) {
|
if ($pSolar !== null)
|
||||||
$acc[$name]['cost_solar'] += ($ratio * $imp * $pSolar) / 100.0;
|
$acc[$name]['cost_solar'] += ($ratio * $imp * $pSolar) / 100.0;
|
||||||
}
|
|
||||||
if ($pFeed !== null) {
|
if ($pFeed !== null)
|
||||||
$acc[$name]['rev_feedin'] += ($exp * $pFeed) / 100.0;
|
$acc[$name]['rev_feedin'] += ($exp * $pFeed) / 100.0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IPS_LogMessage('Abrechnung', sprintf(
|
IPS_LogMessage("ABR", " → Ergebnis $name: solar_bezug=" . $acc[$name]['solar_bezug'] .
|
||||||
" %s | imp=%.4f exp=%.4f ratio=%.4f → solarB=%.4f netzB=%.4f solarE=%.4f solarV=%.4f cGrid=%.4f cSolar=%.4f rFeed=%.4f",
|
" netz_bezug=" . $acc[$name]['netz_bezug'] .
|
||||||
$name, $imp, $exp, $ratio,
|
" solarE=" . $acc[$name]['solareinspeisung'] .
|
||||||
$acc[$name]['solar_bezug'], $acc[$name]['netz_bezug'],
|
" solarV=" . $acc[$name]['solarverkauf'] .
|
||||||
$acc[$name]['solareinspeisung'], $acc[$name]['solarverkauf'],
|
" costGrid=" . $acc[$name]['cost_grid'] .
|
||||||
$acc[$name]['cost_grid'], $acc[$name]['cost_solar'], $acc[$name]['rev_feedin']
|
" costSolar=" . $acc[$name]['cost_solar'] .
|
||||||
));
|
" revFeed=" . $acc[$name]['rev_feedin']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IPS_LogMessage("ABR", "-------------------------------------------------------------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Tabelle am Ende aufbauen ---
|
IPS_LogMessage("ABR", "==== END 15-Minuten Analyse ====");
|
||||||
|
|
||||||
|
// ---- Tabelle aufbauen ----
|
||||||
$sum = 0.0;
|
$sum = 0.0;
|
||||||
foreach ($acc as $name => $a) {
|
foreach ($acc as $name => $a) {
|
||||||
$subtotal = $a['cost_grid'] + $a['cost_solar'] - $a['rev_feedin'];
|
$subtotal = $a['cost_grid'] + $a['cost_solar'] - $a['rev_feedin'];
|
||||||
$sum += $subtotal;
|
$sum += $subtotal;
|
||||||
|
|
||||||
|
IPS_LogMessage("ABR", "FINAL $name: " . json_encode($a));
|
||||||
|
|
||||||
$html .= "<tr>
|
$html .= "<tr>
|
||||||
<td>{$name}</td>
|
<td>{$name}</td>
|
||||||
<td align='right'>" . number_format($a['imp'], 3) . "</td>
|
<td align='right'>" . number_format($a['imp'], 3) . "</td>
|
||||||
@@ -296,6 +343,8 @@ private function CalculatePowerCosts($powerMeters, $tariffs, $userId, $from, $to
|
|||||||
</tr>";
|
</tr>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IPS_LogMessage("ABR", "====================== END CalculatePowerCosts ======================");
|
||||||
|
|
||||||
$html .= "<tr style='background-color:#f9f9f9; font-weight:bold;'>
|
$html .= "<tr style='background-color:#f9f9f9; font-weight:bold;'>
|
||||||
<td colspan='10' align='right'>Total Stromkosten:</td>
|
<td colspan='10' align='right'>Total Stromkosten:</td>
|
||||||
<td align='right'>" . number_format($sum, 2) . "</td>
|
<td align='right'>" . number_format($sum, 2) . "</td>
|
||||||
|
|||||||
Reference in New Issue
Block a user