Files
admin 67fa2de818 Fix: InfluxDB-Host im smarthome-Netz heisst 'influxdb'
INFLUX_URL in docker-compose.prod.yml auf http://influxdb:8086 korrigiert
(verursachte 500 bei allen API-Routen, da Host 'influx' nicht aufloesbar).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 17:07:33 +02:00

4.9 KiB

Stromverbrauch (strom-next)

Next.js-App zur Visualisierung des Stromverbrauchs aus einer InfluxDB. Design/Layout angelehnt an das Projekt Werte-Log (Ansicht „Verlauf").

Datenquelle

  • InfluxDB Bucket strom, Measurement vzlogger, Feld arbeit (Zählerstand in Wh)
  • Der Wert ist ein kumulativer Zählerstand; der Verbrauch je Intervall ergibt sich aus der Differenz aufeinanderfolgender Zählerstände (difference in Flux).
  • Die Rohdaten haben 1-Sekunden-Auflösung. Für die langen Zeiträume wäre die Live-Aggregation zu langsam (Jahr ≈ 70 s), daher gibt es einen Downsampling-Task.

Downsampling-Task (InfluxDB)

Ein InfluxDB-Task arbeit_hourly_rollup (stündlich, in der InfluxDB unter Tasks zu finden) schreibt fortlaufend den letzten Zählerstand je Stunde als Measurement arbeit_hourly (Feld arbeit) zurück in den Bucket strom:

option task = {name: "arbeit_hourly_rollup", every: 1h, offset: 2m}

from(bucket: "strom")
  |> range(start: -3h)
  |> filter(fn: (r) => r._measurement == "vzlogger" and r._field == "arbeit")
  |> aggregateWindow(every: 1h, fn: last, createEmpty: false)
  |> set(key: "_measurement", value: "arbeit_hourly")
  |> to(bucket: "strom")
  • 24h-Chart liest die Rohdaten (vzlogger) → immer top-aktuell.
  • 7d/31d/365d lesen den Rollup (arbeit_hourly) → sub-sekunden-schnell.
  • Tages-/Stundenwerte: erst difference (stündlicher Verbrauch), dann aggregateWindow(sum) pro Tag/Stunde (zeitzonen-korrekt via Europe/Berlin). Liefert exakt dieselben Werte wie die Rohdaten-Aggregation.

Backfill (einmalig, schon ausgeführt)

Die Historie ab 2022-10-09 wurde einmalig in arbeit_hourly geschrieben. Falls erneut nötig (z. B. nach Datenlücke), jahresweise:

from(bucket:"strom")
  |> range(start: 2025-01-01T00:00:00Z, stop: 2026-01-01T00:00:00Z)
  |> filter(fn:(r)=>r._measurement=="vzlogger" and r._field=="arbeit")
  |> aggregateWindow(every:1h, fn:last, createEmpty:false)
  |> set(key:"_measurement", value:"arbeit_hourly")
  |> to(bucket:"strom")

Diagramme (alle als Balken-Diagramme)

Zeitraum Balken Auswahl
Letzte 24 Stunden 1 / Stunde Tag (leer = letzte 24h ab jetzt)
Letzte 7 Tage 1 / Stunde Tag
Letzte 31 Tage 1 / Tag Monat
Letzte 365 Tage 1 / Tag Jahr

X-Achse: Datum/Zeit · Y-Achse: kWh

E-Auto-Lade-Erkennung (31d)

Im 31d-Diagramm werden Tage rot markiert, an denen das E-Auto geladen wurde: Die Leistung (Feld leistung, W) lag länger als LADEN_MIN_HOURS (Default 2 h) ununterbrochen über LADEN_THRESHOLD_KW (Default 11 kW) — dem Anschlusswert des Autos. Erkennung serverseitig per Flux stateDuration auf den Sekundendaten (/api/laden?month=YYYY-MM); läuft ~15 s je Monat und wird daher gecacht (abgeschlossene Monate dauerhaft). Die Markierung wird asynchron nachgeladen, sodass die Balken sofort erscheinen. Schwelle/Dauer sind per Env einstellbar.

Setup

npm install
cp .env.local.example .env.local
# .env.local mit echtem INFLUX_TOKEN (und ggf. Feldname/Einheit) befüllen

.env.local

INFLUX_URL=http://nuccy:8086
INFLUX_TOKEN=...
INFLUX_ORG=citysensor
INFLUX_BUCKET=strom
INFLUX_MEASUREMENT=vzlogger
INFLUX_FIELD=arbeit
INFLUX_UNIT_FACTOR=0.001   # Zählerstand liegt in Wh vor

Den Feldnamen und die Einheit ggf. einmalig prüfen:

curl -s -XPOST "http://nuccy:8086/api/v2/query?org=citysensor" \
  -H "Authorization: Token $INFLUX_TOKEN" \
  -H "Accept: application/csv" \
  -H "Content-type: application/vnd.flux" \
  -d 'import "influxdata/influxdb/schema"
schema.fieldKeys(bucket: "strom", predicate: (r) => r._measurement == "arbeit")'

Starten (lokal)

npm run dev      # http://localhost:3000
npm run build    # Produktionsbuild
npm start

Docker / Deployment auf nuccy

Die App läuft als Container auf nuccy im externen Docker-Netzwerk smarthome und erreicht die InfluxDB dort unter dem Host influxdb (http://influxdb:8086).

Image bauen & in die Registry pushen (vom Entwicklungsrechner)

./deploy.sh           # Tag latest
./deploy.sh v1.2.0    # eigener Tag

Baut für linux/amd64 und pusht nach docker.citysensor.de/strom-next:<tag>.

Auf nuccy starten

docker-compose.prod.yml neben eine .env legen (aus .env.production.example) und das InfluxDB-Read-Token dort eintragen:

# .env
INFLUX_TOKEN=...
# optional: STROM_PORT=3000

Dann:

docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d

Die App ist anschließend auf nuccy unter Port 3000 (bzw. STROM_PORT) erreichbar. Alle InfluxDB-/Lade-Einstellungen sind in docker-compose.prod.yml gesetzt; nur das Token kommt aus der .env.