Hallo Tobias,
ich hab jetzt mal die halbe Nacht davor gesessen und mir das angeschaut (so ne Erkältung hat auch seine Vorteile).
Aaaalsooo...

folgenden Lösungsvorschlag habe ich ersonnen (ist erstmal nur ein Vorschlag der bisher
für mich funktioniert):
Nehmen wir an wir wollen für die Daten vom 13.03.2015 die Stundendaten erhalten.
Das bedeutet, daß wir bei jedem Stundenwechsel uns als MINVAL den MAXVAL der Vorgängerstunde merken müssen und mit diesem rechnen - das wäre die erste Voraussetzung für korrekte Stundenwerte.
Nun haben wir aber ein Problem bei der ersten Stunde des Tages - hier fehlt uns ja der Wert der vorhergehenden Stunde weil diese ja nicht in der Selektions-Range liegt (Wert vor 13.03.2015 00:00:00).
Dies habe ich gelöst indem ich einfach die eigentliche Datenbankselektion erweitert habe.
Was benötigen wir also?
Ganz einfach:
Zusätzlich zu den Werten der aktuellen Zeitraum-Selektion benötigen wir zusätzlich einen einzelnen Datensatz mit dem Max-Wert aus der Datenbank mit dem Timestamp vor der Selektions-Zeitrange.
Wie kriegen wir das hin?
Hier hilft uns die Datenbank mit nem UNION ALL.
Hiermit können wir einfach den Datensatz mit dem Maxwert
vor der Zeitrange hinzuselektieren.
Für das aktuelle Beispiel sieht das so aus:
SELECT
max(DATE_FORMAT(TIMESTAMP, '%Y-%m-%d %H:%i:%s')) as TIMESTAMP,
max(DEVICE) as DEVICE,
max(TYPE) as TYPE,
max(EVENT) as EVENT,
max(READING) as READING,
max(VALUE) as VALUE,
max(UNIT) as UNIT
FROM
`history`
WHERE
`TIMESTAMP` < '2015-03-13 00:00:00' AND
`DEVICE` = 'Zaehler_GaWa' AND
`READING` = 'm3'
UNION ALL
SELECT
DATE_FORMAT(TIMESTAMP, '%Y-%m-%d %H:%i:%s'),
DEVICE,
TYPE,
EVENT,
READING,
VALUE,
UNIT
FROM
`history`
WHERE
`TIMESTAMP` >= '2015-03-13 00:00:00' and
`TIMESTAMP` <= '2015-03-13 23:59:59' AND
`DEVICE` = 'Zaehler_GaWa' AND
`READING` = 'm3'
ORDER BY TIMESTAMP
Jetzt haben wir aber ja natürlich einen zusätzlichen Datensatz in unserer Selektion mit drin der außerhalb unserer Zeitrange liegt.
Von diesem benötigen wir außer dem Wert eigentlich nichts - er soll noch nicht einmal mit ausgegeben werden.
Außerdem könnte es sein daß in der Datenbank gar kein Eintrag existiert der vor der Zeitrange liegt - in diesem Fall haben wir eben keinen zusätzlichen Eintrag in der DB der hinzuselektiert wird.
Das behandeln wir damit daß wir nachsehen ob der aktuelle Eintrag der bearbeitet wird VOR der FROM-Variable liegt und in dem Fall einfach nur den Wert merken und mit diesem Satz sonst nichts weiter machen:
if($sql_timestamp lt $from) {
if(Scalar::Util::looks_like_number($sql_value)){
#nur setzen wenn nummerisch
$minval = $sql_value if($sql_value < $minval);
$maxval = $sql_value if($sql_value > $maxval);
$lastv[$i] = $sql_value;
}
} else {
.....hier der ganze bisherige Code.....
}
Es gibt zusätzliche Anpassungen die von mir vorgenommen wurde - zum einen um "0"-Werte für Stunden dazwischen einzufügen für die es keine Werte gibt, zum andern um die SUM-Variable bei delta-h entsprechend korrekt zu setzen (hier wurden die Zählerwerte addiert anstatt die Stundenwerte).
Das ganze kann so ähnlich dann auch für delta-d umgesetzt werden - der Fall ist ähnlich gelagert.
Jetzt die Gretchen-Frage:
Meine Anpassungen funktionieren jetzt erstmal natürlich bei mir.
Um diese Punkte in das Modul einzuarbeiten wäre es u.U. sinnvoll wenn wir per PN oder Email kontakt aufnehmen würden - ich denke du kannst besser beurteilen ob das auch für andere Readings usw. korrekt wäre oder ob das evtl. doch weitere Probleme erzeugen würde...
Ich habe auch noch andere Ansätze (evtl. Die Berechnung der Stunden- bzw. Tageswerte in die Datenbank auszulagern) - aber die aktuelle Vorgehensweise war meines Erachtens mit den wenigsten Eingriffen in die generelle bisherige Vorgehensweise verbunden.
So - sehr viel Text - muss erstmal verdaut werden.

Wenn also generelles Interesse besteht an meinen Anpassungen kann ich dir diese sehr gerne zur Verfügung stellen - vielleicht ist es ja doch ein hilfreicher Ansatz...
Viele Grüße
Michael