Kreisdiagramm sollten schneller geladen werden.

This commit is contained in:
belevo\mh
2025-12-22 13:29:25 +01:00
parent 81b0b6ee50
commit 355dc3833c

View File

@@ -153,48 +153,96 @@ class Energy_Pie extends IPSModule
$this->RecalculateAndPush(); $this->RecalculateAndPush();
return $this->GetVisualizationTile(); return $this->GetVisualizationTile();
} }
private function readDelta(int $varId, int $tStart, int $tEnd, array &$dbg): float private function readDelta(int $varId, int $tStart, int $tEnd, array &$dbg): float
{ {
$dbg = [ $dbg = [
'varId' => $varId, 'varId' => $varId,
'archiveId' => 0, 'archiveId' => 0,
'count' => 0, 'count' => 0, // hier: wie viele AC-Calls erfolgreich Werte lieferten (nicht Anzahl Rohwerte)
'first' => null, 'vStart' => null,
'last' => null, 'vEnd' => null,
'vStart' => null, 'tsStart' => null,
'vEnd' => null 'tsEnd' => null
]; ];
if ($varId <= 0 || !IPS_VariableExists($varId)) {
return 0.0; if ($varId <= 0 || !IPS_VariableExists($varId)) {
} return 0.0;
$archiveID = IPS_GetInstanceListByModuleID('{43192F0B-135B-4CE7-A0A7-1475603F3060}')[0] ?? 0;
$dbg['archiveId'] = $archiveID;
if ($archiveID <= 0) {
return 0.0;
}
$values = @AC_GetLoggedValues($archiveID, $varId, $tStart - 86400, $tEnd + 86400, 0);
if (empty($values)) {
return 0.0;
}
usort($values, static fn($a, $b) => (int)$a['TimeStamp'] <=> (int)$b['TimeStamp']);
$dbg['count'] = count($values);
$dbg['first'] = (float)$values[0]['Value'];
$dbg['last'] = (float)$values[count($values) - 1]['Value'];
$vStart = null;
$vEnd = null;
foreach ($values as $v) {
$ts = (int)$v['TimeStamp'];
if ($ts <= $tStart) $vStart = (float)$v['Value'];
if ($ts <= $tEnd) $vEnd = (float)$v['Value'];
if ($ts > $tEnd) break;
}
if ($vStart === null) $vStart = $dbg['first'];
if ($vEnd === null) $vEnd = $dbg['last'];
$dbg['vStart'] = $vStart;
$dbg['vEnd'] = $vEnd;
$diff = $vEnd - $vStart;
return ($diff < 0) ? 0.0 : (float)$diff;
} }
$archiveID = IPS_GetInstanceListByModuleID('{43192F0B-135B-4CE7-A0A7-1475603F3060}')[0] ?? 0;
$dbg['archiveId'] = $archiveID;
if ($archiveID <= 0) {
return 0.0;
}
// Liefert den letzten geloggten Wert <= $toTs.
// Wir starten mit einem kleinen Suchfenster (1 Tag) und vergrößern bei Bedarf.
$getLastUpTo = function (int $toTs) use ($archiveID, $varId): ?array {
$windows = [
86400, // 1 Tag
7 * 86400, // 1 Woche
31 * 86400, // 1 Monat
365 * 86400, // 1 Jahr
];
foreach ($windows as $w) {
$from = $toTs - $w;
if ($from < 0) $from = 0;
// Limit = 1: wir wollen nur einen Wert
$vals = @AC_GetLoggedValues($archiveID, $varId, $from, $toTs, 1);
if (!empty($vals)) {
// In der Praxis liefert Symcon bei Limit=1 den "letzten" im Bereich.
// Wir nehmen trotzdem defensiv den Eintrag mit dem größten TimeStamp.
$best = $vals[0];
$bestTs = (int)$best['TimeStamp'];
foreach ($vals as $v) {
$ts = (int)$v['TimeStamp'];
if ($ts > $bestTs) { $bestTs = $ts; $best = $v; }
}
return $best;
}
}
// letzter Versuch: gesamtes Archiv bis toTs (kann bei "total" groß sein, aber passiert nur wenn oben nix gefunden wurde)
$vals = @AC_GetLoggedValues($archiveID, $varId, 0, $toTs, 1);
if (!empty($vals)) {
$best = $vals[0];
$bestTs = (int)$best['TimeStamp'];
foreach ($vals as $v) {
$ts = (int)$v['TimeStamp'];
if ($ts > $bestTs) { $bestTs = $ts; $best = $v; }
}
return $best;
}
return null;
};
// vStart = letzter Wert <= tStart
$a = $getLastUpTo($tStart);
if ($a !== null) {
$dbg['count']++;
$dbg['vStart'] = (float)$a['Value'];
$dbg['tsStart'] = (int)$a['TimeStamp'];
} else {
return 0.0;
}
// vEnd = letzter Wert <= tEnd
$b = $getLastUpTo($tEnd);
if ($b !== null) {
$dbg['count']++;
$dbg['vEnd'] = (float)$b['Value'];
$dbg['tsEnd'] = (int)$b['TimeStamp'];
} else {
return 0.0;
}
$diff = (float)$dbg['vEnd'] - (float)$dbg['vStart'];
return ($diff < 0) ? 0.0 : $diff;
}
private function getLastLogTimestamp(int $varId): int private function getLastLogTimestamp(int $varId): int
{ {
if ($varId <= 0 || !IPS_VariableExists($varId)) { if ($varId <= 0 || !IPS_VariableExists($varId)) {