From d9dd087602fcd60c98d875ceabf8d8493a4bdd21 Mon Sep 17 00:00:00 2001 From: Homelab Cursor Date: Wed, 24 Jun 2026 16:48:36 +0200 Subject: [PATCH] Klima-Bewertung: Telegraf Shelly-Ingest + Grafana-Dashboard Shelly PM Mini Gen3 Leistung (klima_flur_oben/unten) nach InfluxDB sensors/power; Grafana-Dashboard klima-bewertung korreliert Watt mit Raumtemperaturen. --- infra/grafana/klima-bewertung.json | 291 +++++++++++++++++++++++++++++ infra/telegraf/README.md | 25 +++ infra/telegraf/klima.conf | 54 ++++++ infra/telegraf/openwb.conf | 2 +- infra/telegraf/satellites.conf | 2 +- 5 files changed, 372 insertions(+), 2 deletions(-) create mode 100644 infra/grafana/klima-bewertung.json create mode 100644 infra/telegraf/klima.conf diff --git a/infra/grafana/klima-bewertung.json b/infra/grafana/klima-bewertung.json new file mode 100644 index 000000000..b08284a33 --- /dev/null +++ b/infra/grafana/klima-bewertung.json @@ -0,0 +1,291 @@ +{ + "annotations": { "list": [] }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 1, + "id": null, + "links": [ + { + "title": "Satelliten-Temperaturen", + "type": "link", + "url": "/d/satelliten-temps/satelliten-temperaturen" + } + ], + "liveNow": false, + "panels": [ + { + "gridPos": { "h": 3, "w": 24, "x": 0, "y": 0 }, + "id": 100, + "options": { + "code": { "language": "markdown", "showLineNumbers": false, "showMiniMap": false }, + "content": "**Klimatisierung bewerten:** Oben Leistung (W) der Klimaanlagen — unten Raumtemperaturen.\n\n- **Klima läuft + Räume fallen** → wirkt\n- **Klima läuft + Räume stagnieren** → schlechte Verteilung / zu große Last\n- **Klima aus + Räume fallen** → natürliche Abkühlung\n\n`klima_flur_unten` (Panasonic) erscheint automatisch, sobald Shelly + MQTT aktiv.", + "mode": "markdown" + }, + "title": "Hinweis", + "type": "text" + }, + { + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "drawStyle": "line", + "fillOpacity": 15, + "lineWidth": 2, + "showPoints": "never", + "spanNulls": true + }, + "unit": "watt" + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 16, "x": 0, "y": 3 }, + "id": 1, + "options": { + "legend": { "calcs": ["lastNotNull", "max", "mean"], "displayMode": "table", "placement": "bottom" }, + "tooltip": { "mode": "multi", "sort": "desc" } + }, + "targets": [ + { + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "query": "SELECT mean(\"watt\") FROM \"power\" WHERE $timeFilter GROUP BY \"node\", time($__interval) fill(null)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series" + } + ], + "title": "Klima-Leistung (W)", + "type": "timeseries" + }, + { + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "thresholds" }, + "thresholds": { + "mode": "absolute", + "steps": [ + { "color": "blue", "value": null }, + { "color": "green", "value": 100 }, + { "color": "orange", "value": 800 }, + { "color": "red", "value": 2000 } + ] + }, + "unit": "watt" + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 8, "x": 16, "y": 3 }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { "calcs": ["lastNotNull"], "fields": "", "values": false } + }, + "targets": [ + { + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "query": "SELECT last(\"watt\") FROM \"power\" WHERE $timeFilter GROUP BY \"node\"", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series" + } + ], + "title": "Aktuelle Leistung", + "type": "stat" + }, + { + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "custom": { "drawStyle": "line", "fillOpacity": 8, "lineWidth": 2, "showPoints": "never", "spanNulls": true }, + "unit": "watt" + }, + "overrides": [ + { + "matcher": { "id": "byRegexp", "options": "/.*temp.*/" }, + "properties": [ + { "id": "unit", "value": "celsius" }, + { "id": "custom.axisPlacement", "value": "right" }, + { "id": "color", "value": { "fixedColor": "light-blue", "mode": "fixed" } } + ] + } + ] + }, + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 11 }, + "id": 3, + "options": { + "legend": { "calcs": [], "displayMode": "list", "placement": "bottom" }, + "tooltip": { "mode": "multi", "sort": "none" } + }, + "targets": [ + { + "alias": "Leistung Split oben", + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "query": "SELECT mean(\"watt\") FROM \"power\" WHERE \"node\"='klima_flur_oben' AND $timeFilter GROUP BY time($__interval) fill(null)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series" + }, + { + "alias": "Temp flur_oben", + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "query": "SELECT mean(\"value\") FROM \"temperature\" WHERE \"node\"='flur_oben' AND $timeFilter GROUP BY time($__interval) fill(null)", + "rawQuery": true, + "refId": "B", + "resultFormat": "time_series" + } + ], + "title": "Flur oben: Leistung vs. Temperatur", + "type": "timeseries" + }, + { + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "custom": { "drawStyle": "line", "fillOpacity": 8, "lineWidth": 2, "showPoints": "never", "spanNulls": true }, + "unit": "watt" + }, + "overrides": [ + { + "matcher": { "id": "byRegexp", "options": "/.*temp.*/" }, + "properties": [ + { "id": "unit", "value": "celsius" }, + { "id": "custom.axisPlacement", "value": "right" }, + { "id": "color", "value": { "fixedColor": "light-green", "mode": "fixed" } } + ] + } + ] + }, + "gridPos": { "h": 8, "w": 12, "x": 12, "y": 11 }, + "id": 4, + "options": { + "legend": { "calcs": [], "displayMode": "list", "placement": "bottom" }, + "tooltip": { "mode": "multi", "sort": "none" } + }, + "targets": [ + { + "alias": "Leistung Panasonic unten", + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "query": "SELECT mean(\"watt\") FROM \"power\" WHERE \"node\"='klima_flur_unten' AND $timeFilter GROUP BY time($__interval) fill(null)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series" + }, + { + "alias": "Temp flur_unten", + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "query": "SELECT mean(\"value\") FROM \"temperature\" WHERE \"node\"='flur_unten' AND $timeFilter GROUP BY time($__interval) fill(null)", + "rawQuery": true, + "refId": "B", + "resultFormat": "time_series" + } + ], + "title": "Flur unten: Leistung vs. Temperatur (Panasonic folgt)", + "type": "timeseries" + }, + { + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "custom": { "drawStyle": "line", "fillOpacity": 5, "lineWidth": 1, "showPoints": "never", "spanNulls": true }, + "unit": "celsius" + }, + "overrides": [] + }, + "gridPos": { "h": 10, "w": 24, "x": 0, "y": 19 }, + "id": 5, + "options": { + "legend": { "calcs": ["lastNotNull", "min", "max"], "displayMode": "table", "placement": "right" }, + "tooltip": { "mode": "multi", "sort": "desc" } + }, + "targets": [ + { + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "query": "SELECT mean(\"value\") FROM \"temperature\" WHERE $timeFilter AND (\"node\"='flur_oben' OR \"node\"='flur_unten' OR \"node\"='wohnstube' OR \"node\"='schlafzimmer' OR \"node\"='gaestezimmer' OR \"node\"='kueche' OR \"node\"='trockenraum') GROUP BY \"node\", time($__interval) fill(null)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series" + } + ], + "title": "Raumtemperaturen — Wohnbereich (24h)", + "type": "timeseries" + }, + { + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "fieldConfig": { + "defaults": { + "custom": { "align": "auto", "cellOptions": { "type": "auto" } }, + "unit": "celsius" + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 12, "x": 0, "y": 29 }, + "id": 6, + "options": { + "cellHeight": "sm", + "footer": { "show": false }, + "showHeader": true + }, + "targets": [ + { + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "query": "SELECT last(\"value\") AS \"aktuell\", min(\"value\") AS \"min\", max(\"value\") AS \"max\", mean(\"value\") AS \"mittel\" FROM \"temperature\" WHERE $timeFilter AND (\"node\"='flur_oben' OR \"node\"='flur_unten' OR \"node\"='wohnstube' OR \"node\"='schlafzimmer' OR \"node\"='gaestezimmer' OR \"node\"='kueche' OR \"node\"='trockenraum') GROUP BY \"node\"", + "rawQuery": true, + "refId": "A", + "resultFormat": "table" + } + ], + "title": "Raumtemperaturen — Übersicht", + "transformations": [{ "id": "organize", "options": { "renameByName": { "node": "Raum" } } }], + "type": "table" + }, + { + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "fieldConfig": { + "defaults": { + "color": { "mode": "palette-classic" }, + "custom": { "drawStyle": "bars", "fillOpacity": 80, "lineWidth": 1 }, + "unit": "kwatth" + }, + "overrides": [] + }, + "gridPos": { "h": 8, "w": 12, "x": 12, "y": 29 }, + "id": 7, + "options": { + "legend": { "calcs": ["sum"], "displayMode": "table", "placement": "bottom" }, + "tooltip": { "mode": "multi", "sort": "desc" } + }, + "targets": [ + { + "datasource": { "type": "influxdb", "uid": "ffptl25vzylfke" }, + "query": "SELECT difference(last(\"energy_wh_total\")) / 1000 FROM \"power\" WHERE $timeFilter GROUP BY \"node\", time(1h) fill(null)", + "rawQuery": true, + "refId": "A", + "resultFormat": "time_series" + } + ], + "title": "Klima-Verbrauch (kWh/h, aus Shelly-Zähler)", + "type": "timeseries" + } + ], + "refresh": "30s", + "schemaVersion": 39, + "tags": ["klima", "sensors", "homelab"], + "templating": { "list": [] }, + "time": { "from": "now-24h", "to": "now" }, + "timepicker": {}, + "timezone": "browser", + "title": "Klimatisierung", + "uid": "klima-bewertung", + "version": 1, + "weekStart": "" +} diff --git a/infra/telegraf/README.md b/infra/telegraf/README.md index 519df7640..d6512b503 100644 --- a/infra/telegraf/README.md +++ b/infra/telegraf/README.md @@ -46,3 +46,28 @@ pct exec 143 -- systemctl restart telegraf # Verifikation: pct exec 143 -- influx -database sensors -execute 'SHOW MEASUREMENTS' ``` + +## klima.conf (ab 24.06.2026) + +Shelly PM Mini Gen3 Leistungsmessung der Klimaanlagen -> DB `sensors`, Measurement `power`. + +| Tag | Bedeutung | +|-----|-----------| +| `node` | `klima_flur_oben` (Split oben), `klima_flur_unten` (Panasonic, vorbereitet) | +| `geraet` | `split_ac` / `panasonic` | + +MQTT-Topics (Shelly Prefix): +- `klima_flur_oben/status/pm1:0` +- `klima_flur_unten/status/pm1:0` + +Felder: `watt` (apower), `voltage`, `current`, `energy_wh_total` (Wh kumuliert). + +Grafana-Dashboard: `Klimatisierung` (UID `klima-bewertung`) unter `/d/klima-bewertung/klimatisierung` + +Deploy: +```bash +pct push 143 klima.conf /etc/telegraf/telegraf.d/klima.conf +# satellites.conf + openwb.conf namepass/namedrop aktualisieren (power) +pct exec 143 -- systemctl restart telegraf +pct push 143 klima-bewertung.json /etc/grafana/provisioning/dashboards/klima-bewertung.json +``` diff --git a/infra/telegraf/klima.conf b/infra/telegraf/klima.conf new file mode 100644 index 000000000..708101f7f --- /dev/null +++ b/infra/telegraf/klima.conf @@ -0,0 +1,54 @@ +# Shelly PM Mini Gen3 — Klima-Leistungsmessung -> InfluxDB 'sensors' (via satellites.conf-Output). +# Topics: /status/pm1:0 (Shelly Gen3 JSON, Feld apower in Watt) +# Aktiv: klima_flur_oben (Split-Klima Flur oben) +# Vorbereitet: klima_flur_unten (Panasonic, folgt) + +# --- Split-Klima Flur oben --- +[[inputs.mqtt_consumer]] + servers = ["tcp://127.0.0.1:1883"] + topics = ["klima_flur_oben/status/pm1:0"] + name_override = "power" + data_format = "json_v2" + [inputs.mqtt_consumer.tags] + node = "klima_flur_oben" + geraet = "split_ac" + [[inputs.mqtt_consumer.json_v2]] + [[inputs.mqtt_consumer.json_v2.field]] + path = "apower" + rename = "watt" + type = "float" + [[inputs.mqtt_consumer.json_v2.field]] + path = "voltage" + type = "float" + [[inputs.mqtt_consumer.json_v2.field]] + path = "current" + type = "float" + [[inputs.mqtt_consumer.json_v2.field]] + path = "aenergy.total" + rename = "energy_wh_total" + type = "float" + +# --- Panasonic Flur unten (vorbereitet, Daten sobald Shelly/MQTT aktiv) --- +[[inputs.mqtt_consumer]] + servers = ["tcp://127.0.0.1:1883"] + topics = ["klima_flur_unten/status/pm1:0"] + name_override = "power" + data_format = "json_v2" + [inputs.mqtt_consumer.tags] + node = "klima_flur_unten" + geraet = "panasonic" + [[inputs.mqtt_consumer.json_v2]] + [[inputs.mqtt_consumer.json_v2.field]] + path = "apower" + rename = "watt" + type = "float" + [[inputs.mqtt_consumer.json_v2.field]] + path = "voltage" + type = "float" + [[inputs.mqtt_consumer.json_v2.field]] + path = "current" + type = "float" + [[inputs.mqtt_consumer.json_v2.field]] + path = "aenergy.total" + rename = "energy_wh_total" + type = "float" diff --git a/infra/telegraf/openwb.conf b/infra/telegraf/openwb.conf index 5204fdaa2..3e6f19f58 100644 --- a/infra/telegraf/openwb.conf +++ b/infra/telegraf/openwb.conf @@ -1,7 +1,7 @@ [[outputs.influxdb]] urls = ["http://127.0.0.1:8086"] database = "iobroker" - namedrop = ["temperature", "io_state"] + namedrop = ["temperature", "io_state", "power"] [[inputs.mqtt_consumer]] servers = ["tcp://192.168.178.104:1883"] diff --git a/infra/telegraf/satellites.conf b/infra/telegraf/satellites.conf index fdc318245..dfc90526a 100644 --- a/infra/telegraf/satellites.conf +++ b/infra/telegraf/satellites.conf @@ -4,7 +4,7 @@ [[outputs.influxdb]] urls = ["http://127.0.0.1:8086"] database = "sensors" - namepass = ["temperature", "io_state"] + namepass = ["temperature", "io_state", "power"] # --- Raum-Satelliten: /temp --- [[inputs.mqtt_consumer]]