InfluxDB 2.x - Zeitstempel verstehen und umrechnen
In einem ersten Video bin ich auf die InfluxDB 2.x Grundlagen eingegangen. Dann folge ein Praixs-Video zu meinem PV-Dashboard. Beide Videos kamen sehr gut bei Euch an. Allerdings stolpere ich bei meinem täglichen Support im ioBroker-Forum immer wieder über die Zeitstempel-Thematik. Da dort immer vieles durcheinadner geworfen wird, klären wir heute ein paar Grundlagen zu Zeitstempeln und wie man korrekt mit den UTC-Zeitstempeln aus der Datenbank arbeitet.
Was Du benötigst?
- Eine bestehende InfluxDB 2.x Installation
Video
Statements
Wenn man Zeiträume selektiert, sollte man bei den Tagesgrenzen darauf achten, dass diese für die richtige Zeitzone gelten. Ansonsten wird UTC zurückgeliefert. Gruppiert man Daten ohne Zeitzonen-Angabe, wird ebenfalls UTC verwendet. Das folgende Statement liefert also zwei Zeilen zurück, obwohl die Daten in der Zeitzone Europe/Berlin
nur in genau einem Tag liegen.
from(bucket: "smarthome")
|> range(start: 2023-07-31T22:00:00.000Z, stop: 2023-08-01T21:59:59.999Z)
|> filter(fn: (r) => r._measurement == "energy-stats" and r._field == "importedWh")
|> difference()
|> aggregateWindow(every: 1d, fn: sum, timeSrc: "_start")
Es muss also die richtige Zeitzone gesetzt werden:
import "timezone"
option location = timezone.location(name: "Europe/Berlin")
Diese Option wird ebenfalls genutzt, wenn Zeitpunkte errechnet werden sollen (Anfang des Tages, Anfang der Woche oder des Monats):
import "generate"
import "timezone"
import "date"
option location = timezone.location(name: "Europe/Berlin")
dayStart = date.truncate(t: now(), unit: 1d) // entspricht today()
monthStart = date.truncate(t: today(), unit: 1mo)
yearStart = date.truncate(t: today(), unit: 1y)
last6Month = date.sub(from: today(), d: 6mo)
last6MonthStart = date.sub(from: date.truncate(t: today(), unit: 1mo), d: 6mo)
generate
.from(count: 1, fn: (n) => n + 1, start: 2023-01-01T00:00:00.000Z, stop: 2023-01-01T23:59:59.999Z)
|> map(fn: (r) => ({r with _value: last6MonthStart}))
|> drop(columns: ["_time"])
Insgesamt bietet das Date Package sehr viele Funktionen, um von einem Ausgangspunkte (z.B. heute) verschiedene Zeitpunkte zu errechnen. Im folgenden Beispiel hole ich mir die Daten für die letzten 6 vollendeten Monate. Der aktuell laufende Monat wird also nicht mit abgefragt!
import "generate"
import "timezone"
import "date"
option location = timezone.location(name: "Europe/Berlin")
monthStart = date.truncate(t: today(), unit: 1mo)
last6MonthStart = date.sub(from: monthStart, d: 6mo)
from(bucket: "smarthome")
|> range(start: last6MonthStart, stop: monthStart)
|> filter(fn: (r) => r._measurement == "energy-stats" and r._field == "importedWh")
|> difference()
|> aggregateWindow(every: 1mo, fn: sum, timeSrc: "_start")
Eine Besonderheit sind leider die Wochen. Als Anfang der Woche wird immer ein Donnerstag zurückgeliefert. Daher müssen wir den Wochenanfang etwas anders errechenn:
import "timezone"
import "date"
option location = timezone.location(name: "Europe/Berlin")
weekStart = date.sub(from: date.truncate(t: date.add(to: today(), d: 3d), unit: 1w), d: 3d)
Mehr dazu im Video!