Mit Influx und Grafana.
Wichtig: Ich habe Influx 2. Zum einen, weil Influx 2.x gegenüber 1.x "
Flux" hat (data scripting language), die auch
Monate als Zeitraum kennt. Unter Influx 1 konnte man Daten nur für 30 oder 31 Tage aufsummieren. Geht auch, ist aber etwas ungenau.
Zum anderen habe ich in Influx Tasks erstellt, die die Daten von einem "Bucket" (Datenbank) in einen anderen Bucket downsampeln. Also zum Bsp. nur einen Datenpunkt pro Stunde speichern. Das reduziert den Rechenaufwand deutlich.
Beides (Grafana und Influx) laufen bei mir auf einer NAS im Docker. Kann man aber bspw. auch auf dem gleichen Raspi wie openHAB installieren.
So eine Downsampling-Task (
wie gesagt, nicht zwingend erforderlich) sieht dann so aus:
Code: Alles auswählen
import "date"
option task = {name: "PV Ertrag", every: 1h0m0s}
fullHourTime = date.truncate(t: now(), unit: 1h)
startTime = date.sub(from: fullHourTime, d: 1h)
from(bucket: "openHAB")
|> range(start: startTime, stop: fullHourTime)
|> filter(fn: (r) => r["_measurement"] == "PVtotal")
|> filter(fn: (r) => r._field == "value")
|> difference()
|> aggregateWindow(every: 1h, fn: sum, createEmpty: false)
|> to(bucket: "openHAB_history", fieldFn: (r) => ({"PV_Ertrag": r._value}))
und der Abruf in Grafana als
Bar chart dann so:
Code: Alles auswählen
import "timezone"
option location = timezone.location(name: "Europe/Berlin")
from(bucket: "openHAB_history")
|> range(start: -365d)
|> filter(fn: (r) => r["_measurement"] == "PVtotal")
|> filter(fn: (r) => r._field == "value")
|> difference()
|> aggregateWindow(every: 1mo, fn: sum, timeSrc: "_start")
grafana.png
Am Anfang sehr fummelig das ganze; aber wenn man einmal den Bogen heraus hat, lässt es sich per STRG-C STRV-V sehr schnell auf alle anderen Daten adaptieren.
Die Tortendiagramme sind eben "Pie charts":
Code: Alles auswählen
from(bucket: "openHAB")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r["_measurement"] == "Bezug_xTage" or r["_measurement"] == "Eigenverbrauch_xTage")
|> filter(fn: (r) => r["_field"] == "value")
|> aggregateWindow(every: v.windowPeriod, fn: last, createEmpty: false)
|> yield(name: "last")
Und zuletzt der Aufruf in der Sitemap (die Adresse hierzu stellt Grafana bereit):
Code: Alles auswählen
Switch item=gChartIntervall2 label="[]" icon="deadline" mappings=[1="aktuell",2="Woche",3="Jahr"]
Webview icon=energy url="http://192.168.178.26:3000/d-solo/-4Py1lWgk/energie-aktuell?orgId=1&from=now-24h&panelId=4" height=6 visibility=[gChartIntervall2 == 1, gChartIntervall2 == NULL]
Webview icon=energy url="http://192.168.178.26:3000/d-solo/0L9FYfiRz/heizung?orgId=1&panelId=4&tab=axes&from=now-7d" height=6 visibility=[gChartIntervall2 == 2]
Webview icon=energy url="http://192.168.178.26:3000/d-solo/0L9FYfiRz/heizung?orgId=1&panelId=12&tab=axes&from=now-365d" height=6 visibility=[gChartIntervall2 == 3]
Text item=SolarGesamt
Interessant sind dann auch z.B. Einbindung des Sonnenstandes. Oder Vergleich der Monatswerte mit dem Vorjahr:
grafana2.png