@Powerdream
'Also ich hätte ein FluxQL-Beispiel für die Energie-Einspeisung pro Monat, das man sicher auf pro Tag für Verbrauch ändern kann. Datenquelle ist bei mir der Wert einer kumulierenden Summe der Energieerzeugung der PV-Anlage: yieldtotal
import "date"
// Truncate to start of current year
currentYearStart = date.truncate(t: now(), unit: 1y)
// Add 1 year → 1 January of next year
nextYearStart = date.add(d: 1y, to: currentYearStart)
from(bucket: "open-dtu")
|> range(start: -13mo, stop: nextYearStart)
|> filter(fn: (r) => r["_measurement"] == "photovoltaic")
|> filter(fn: (r) => r["_field"] == "yieldtotal")
|> filter(fn: (r) => r["device"] == "{{YOUR_DEVICE_ID_HERE}}")
|> filter(fn: (r) => r["status"] == "online")
|> aggregateWindow(every: 1mo, fn: last, createEmpty: false)
|> duplicate(column: "_value", as: "yieldtotal")
|> map(fn: (r) => ({r with _field: "yielddiff"}))
|> difference()
|> timeShift(duration: -1mo)
|> keep(columns: ["_time", "_value", "name"])
Diese Flux-Abfrage ist dafür konzipiert, den monatlichen Ertrag (Monthly Yield) der Photovoltaikanlage zu berechnen, basierend auf einem fortlaufenden Gesamtzähler yieldtotal.
Kurz gesagt: Sie wandelt einen ständig wachsenden Gesamtzähler in monatliche Werte um (d.h. wie viel Energie wurde in jedem einzelnen Monat produziert).
Hier ist die detaillierte Analyse Schritt für Schritt:
1. Zeitrahmen-Berechnung
import "date"
currentYearStart = date.truncate(t: now(), unit: 1y)
nextYearStart = date.add(d: 1y, to: currentYearStart)
-
Hier werden Variablen definiert, um den Zeitraum sauber auf das Kalenderjahr auszurichten.
-
Es wird der Start des aktuellen Jahres und der Start des nächsten Jahres berechnet.
2. Datenabruf & Filterung
from(bucket: "open-dtu")
|> range(start: -13mo, stop: nextYearStart)
|> filter(fn: (r) => r["_measurement"] == "photovoltaic")
|> filter(fn: (r) => r["_field"] == "yieldtotal")
|> filter(fn: (r) => r["device"] == "{{YOUR_DEVICE_ID_HERE}}")
|> filter(fn: (r) => r["status"] == "online")
-
range(start: -13mo)Es werden Daten der letzten 13 Monate geladen. Das ist wichtig, weil die Funktion difference() immer einen vorherigen Wert benötigt. Um den Januar-Ertrag zu berechnen, braucht man den Zählerstand vom Dezember.
-
_field == "yieldtotal" Es wird der Gesamtertrag seit Installation (Total Lifetime Yield) aus der InfluxDB abgerufen.
-
filter Filtert auf ein spezifisches Gerät (hier muss die ID noch eingetragen werden) und ich nehme nur Datenpunkte, wo der Status “online” war (nachts nicht
)
3. Aggregation (Das Herzstück)
|> aggregateWindow(every: 1mo, fn: last, createEmpty: false)
-
Das ist der wichtigste Schritt. Die Daten werden in 1-Monats-Fenster gruppiert.
-
fn: last: Es wird jeweils der allerletzte Wert des Monats genommen. Da yieldtotal eben eine ansteigende Summe ist, repräsentiert der letzte Wert im Januar den gesamten Ertrag bis Ende Januar.
4. Differenzbildung
|> duplicate(column: "_value", as: "yieldtotal")
|> map(fn: (r) => ({r with _field: "yielddiff"}))
|> difference()
-
difference() Dies berechnet den Unterschied zwischen den benachbarten Monaten.
- Beispiel: (Zählerstand Ende Februar) MINUS (Zählerstand Ende Januar) = Produktion im Februar.
-
Ohne diesen Schritt hättest Du nur eine stetig steigende Kurve. Mit diesem Schritt erhältst du die tatsächliche Produktion pro Monat.
5. Zeitkorrektur
|> timeShift(duration: -1mo)
-
Wenn InfluxDB Zeitfenster aggregiert, wird der Zeitstempel oft auf das Ende des Fensters gesetzt (z.B. bekommt der Januar-Wert den Zeitstempel 1. Februar).
-
Dieser timeShift schiebt das Ergebnis um einen Monat zurück, damit der Balken im Diagramm korrekt über “Januar” steht und nicht über “Februar”.
6. Aufräumen
|> keep(columns: ["_time", "_value", "name"])
- Am Ende werden nur die relevanten Spalten behalten, um die Tabelle übersichtlich zu halten.
Zusammenfassung der Logik
Stell Dir meinen Stromzähler vor:
-
Input: Der Zählerstand (Total) am Ende jeden Monats:
-
Jan: 1000 kWh
-
Feb: 1150 kWh
-
Mär: 1350 kWh
-
difference()macht daraus:
-
timeShift(-1mo) korrigiert das Datum:
- Der Wert 150 kWh wird dem Januar (oder Februar, je nach Logik des Fensters) zugeordnet, damit er graphisch im richtigen Monat erscheint.