weather day-report: visuelles Report-Layout statt Markdown-Textblock

Die markdown-html-Tabellenzelle rendert in Grafana 13 als Klartext (eine
ueberlaufende Zeile). Ersetzt durch native Panels:
- farbcodiertes Bewertungs-Banner (stat, background-color per Mapping)
- 8 Kennzahl-Karten mit Mini-Sparkline (T min/max, Regen, UV, Boee,
  Luftfeuchte, Luftdruck, Solar) inkl. Thresholds in Blau/Cyan/Amber/Gruen
- 2 Tagescharts: Temperatur (Aussen/Gefuehlt/Taupunkt) und Solar+UV
Gleiche $__timeFilter-Queries wie das Wetterarchiv-Dashboard.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-20 09:34:56 +02:00
parent 536a6fd0cd
commit d99082a3a7
@@ -4,7 +4,7 @@
"tags": ["weather", "ecowitt", "homeassistant", "report"], "tags": ["weather", "ecowitt", "homeassistant", "report"],
"timezone": "Europe/Berlin", "timezone": "Europe/Berlin",
"schemaVersion": 39, "schemaVersion": 39,
"version": 2, "version": 3,
"refresh": "", "refresh": "",
"time": { "from": "now-1d/d", "to": "now/d" }, "time": { "from": "now-1d/d", "to": "now/d" },
"templating": { "list": [] }, "templating": { "list": [] },
@@ -17,37 +17,42 @@
"id": 2, "id": 2,
"title": "", "title": "",
"type": "text", "type": "text",
"gridPos": { "h": 4, "w": 24, "x": 0, "y": 0 }, "gridPos": { "h": 3, "w": 24, "x": 0, "y": 0 },
"options": { "options": {
"mode": "markdown", "mode": "markdown",
"content": "## Tag auswählen\n\n**Standard:** gestern (ganzer Tag, Europe/Berlin).\n\n**Anderen Tag:** Zeitbereich oben rechts → *Absolute time range* → z. B. From `2026-06-15 00:00:00`, To `2026-06-16 00:00:00` → **Apply** (Zeiten gelten in Europe/Berlin).\n\n**Alle Tage als Liste:** [Wetter-Tagesberichte](/d/ha-weather-report-history) dort jeden Tag per Klick öffnen." "content": "**Wetterbericht Tag auswählen.** Standard: **gestern** (ganzer Tag, Europe/Berlin). Anderen Tag: Zeitbereich oben rechts → *Absolute time range* → z. B. From `2026-06-15 00:00:00`, To `2026-06-16 00:00:00`. Alle Tage als Liste: **[Wetter-Tagesberichte](/d/ha-weather-report-history)** (Datum anklicken)."
} }
}, },
{ {
"id": 1, "id": 3,
"title": "Tagesbericht", "title": "Bewertung des Tages",
"type": "table", "type": "stat",
"gridPos": { "h": 16, "w": 24, "x": 0, "y": 4 }, "gridPos": { "h": 4, "w": 24, "x": 0, "y": 3 },
"datasource": { "type": "influxdb", "uid": "ha-weather-influx" }, "datasource": { "type": "influxdb", "uid": "ha-weather-influx" },
"fieldConfig": { "fieldConfig": {
"defaults": { "defaults": {
"custom": { "color": { "mode": "thresholds" },
"align": "left", "thresholds": { "mode": "absolute", "steps": [ { "color": "#868e96", "value": null } ] },
"cellOptions": { "mappings": [
"type": "markdown-html", { "type": "value", "options": {
"dynamicHeight": true "Sonnig & warm": { "color": "#ff922b", "index": 0 },
}, "Warm": { "color": "#fab005", "index": 1 },
"filterable": false, "Regnerisch": { "color": "#4dabf7", "index": 2 },
"inspect": false "Kalt": { "color": "#74c0fc", "index": 3 },
} "Unauffaellig": { "color": "#868e96", "index": 4 }
} }
]
}, },
"overrides": [] "overrides": []
}, },
"options": { "options": {
"showHeader": false, "reduceOptions": { "values": false, "calcs": ["lastNotNull"], "fields": "" },
"cellHeight": "lg", "orientation": "horizontal",
"footer": { "show": false, "reducer": ["sum"], "countRows": false }, "colorMode": "background",
"sortBy": [] "graphMode": "none",
"justifyMode": "center",
"textMode": "value",
"wideLayout": true
}, },
"targets": [ "targets": [
{ {
@@ -55,9 +60,298 @@
"datasource": { "type": "influxdb", "uid": "ha-weather-influx" }, "datasource": { "type": "influxdb", "uid": "ha-weather-influx" },
"rawQuery": true, "rawQuery": true,
"format": "table", "format": "table",
"rawSql": "WITH temp AS (SELECT count(value) AS samples, min(value) AS tmin, max(value) AS tmax, avg(value) AS tavg FROM \"\u00b0C\" WHERE entity_id = 'gw3000a_outdoor_temperature' AND $__timeFilter(time)), feels AS (SELECT max(value) AS fmax, avg(value) AS favg FROM \"\u00b0C\" WHERE entity_id = 'gw3000a_feels_like_temperature' AND $__timeFilter(time)), dew AS (SELECT avg(value) AS davg FROM \"\u00b0C\" WHERE entity_id = 'gw3000a_dewpoint' AND $__timeFilter(time)), hum AS (SELECT count(value) AS samples, min(value) AS hmin, max(value) AS hmax, avg(value) AS havg FROM \"%\" WHERE entity_id = 'gw3000a_humidity' AND $__timeFilter(time)), wind AS (SELECT count(value) AS samples, max(value) AS wmax, avg(value) AS wavg FROM \"km/h\" WHERE entity_id = 'gw3000a_wind_speed' AND $__timeFilter(time)), gust AS (SELECT count(value) AS samples, max(value) AS gmax FROM \"km/h\" WHERE entity_id = 'gw3000a_wind_gust' AND $__timeFilter(time)), rain AS (SELECT count(value) AS samples, max(value) AS rain_mm FROM \"mm\" WHERE entity_id = 'gw3000a_daily_rain' AND $__timeFilter(time)), solar AS (SELECT count(value) AS samples, max(value) AS smax, avg(value) AS savg FROM \"W/m\u00b2\" WHERE entity_id = 'gw3000a_solar_radiation' AND $__timeFilter(time)), uv AS (SELECT count(value) AS samples, max(value) AS uvmax FROM \"UV index\" WHERE entity_id = 'gw3000a_uv_index' AND $__timeFilter(time)), press AS (SELECT count(value) AS samples, min(value) AS pmin, max(value) AS pmax, avg(value) AS pavg FROM \"hPa\" WHERE entity_id = 'gw3000a_relative_pressure' AND $__timeFilter(time)) SELECT '# Wetterbericht KalliHome' || chr(10) || chr(10) || 'Zeitraum: gewaehlter Grafana-Zeitraum.' || chr(10) || chr(10) || CASE WHEN solar.smax >= 700 AND uv.uvmax >= 6 THEN 'Der Tag war warm, hell und ueberwiegend sonnig; die hohe Solarstrahlung und der UV-Index von ' || cast(round(uv.uvmax, 1) as varchar) || ' passen klar zu einem schoenen Sommertag.' WHEN temp.tmax >= 25 THEN 'Der Tag war warm; die Messwerte sprechen fuer sommerliches Wetter.' ELSE 'Der Tag war wettertechnisch unauffaellig; die folgenden Messwerte fassen ihn zusammen.' END || chr(10) || chr(10) || '- Temperatur aussen: ' || coalesce(cast(round(temp.tmin, 1) as varchar), 'n/a') || ' bis ' || coalesce(cast(round(temp.tmax, 1) as varchar), 'n/a') || ' \u00b0C, Mittel ' || coalesce(cast(round(temp.tavg, 1) as varchar), 'n/a') || ' \u00b0C.' || chr(10) || '- Gefuehlt: Maximum ' || coalesce(cast(round(feels.fmax, 1) as varchar), 'n/a') || ' \u00b0C, Mittel ' || coalesce(cast(round(feels.favg, 1) as varchar), 'n/a') || ' \u00b0C. Taupunkt im Mittel ' || coalesce(cast(round(dew.davg, 1) as varchar), 'n/a') || ' \u00b0C.' || chr(10) || '- Luftfeuchte aussen: ' || coalesce(cast(round(hum.hmin, 0) as varchar), 'n/a') || ' bis ' || coalesce(cast(round(hum.hmax, 0) as varchar), 'n/a') || ' %, Mittel ' || coalesce(cast(round(hum.havg, 0) as varchar), 'n/a') || ' %.' || chr(10) || '- Wind: Mittel ' || coalesce(cast(round(wind.wavg, 1) as varchar), 'n/a') || ' km/h, Maximum Wind ' || coalesce(cast(round(wind.wmax, 1) as varchar), 'n/a') || ' km/h; staerkste Boe ' || coalesce(cast(round(gust.gmax, 1) as varchar), 'n/a') || ' km/h.' || chr(10) || CASE WHEN rain.samples > 0 THEN '- Regen: ' || coalesce(cast(round(rain.rain_mm, 1) as varchar), 'n/a') || ' mm Tagesmenge laut daily_rain.' ELSE '- Regen: nicht belastbar auswertbar, weil gw3000a_daily_rain im Zeitraum keine Samples hatte.' END || chr(10) || '- Solarstrahlung: Maximum ' || coalesce(cast(round(solar.smax, 0) as varchar), 'n/a') || ' W/m\u00b2, Mittel ' || coalesce(cast(round(solar.savg, 0) as varchar), 'n/a') || ' W/m\u00b2.' || chr(10) || '- UV-Index: Maximum ' || coalesce(cast(round(uv.uvmax, 1) as varchar), 'n/a') || '.' || chr(10) || '- Luftdruck: ' || coalesce(cast(round(press.pmin, 0) as varchar), 'n/a') || ' bis ' || coalesce(cast(round(press.pmax, 0) as varchar), 'n/a') || ' hPa, Mittel ' || coalesce(cast(round(press.pavg, 0) as varchar), 'n/a') || ' hPa.' AS bericht FROM temp CROSS JOIN feels CROSS JOIN dew CROSS JOIN hum CROSS JOIN wind CROSS JOIN gust CROSS JOIN rain CROSS JOIN solar CROSS JOIN uv CROSS JOIN press" "rawSql": "WITH s AS (SELECT max(value) AS smax FROM \"W/m²\" WHERE entity_id = 'gw3000a_solar_radiation' AND $__timeFilter(time)), u AS (SELECT max(value) AS uvmax FROM \"UV index\" WHERE entity_id = 'gw3000a_uv_index' AND $__timeFilter(time)), t AS (SELECT max(value) AS tmax FROM \"°C\" WHERE entity_id = 'gw3000a_outdoor_temperature' AND $__timeFilter(time)), r AS (SELECT max(value) AS rain FROM \"mm\" WHERE entity_id = 'gw3000a_daily_rain' AND $__timeFilter(time)) SELECT CASE WHEN s.smax >= 700 AND u.uvmax >= 6 THEN 'Sonnig & warm' WHEN t.tmax >= 25 THEN 'Warm' WHEN coalesce(r.rain, 0) >= 5 THEN 'Regnerisch' WHEN t.tmax <= 5 THEN 'Kalt' ELSE 'Unauffaellig' END AS \"Bewertung\" FROM s CROSS JOIN u CROSS JOIN t CROSS JOIN r"
} }
] ]
},
{
"id": 10,
"title": "",
"type": "stat",
"gridPos": { "h": 4, "w": 6, "x": 0, "y": 7 },
"datasource": { "type": "influxdb", "uid": "ha-weather-influx" },
"fieldConfig": {
"defaults": {
"unit": "celsius",
"decimals": 1,
"displayName": "Temp min",
"color": { "mode": "fixed", "fixedColor": "#4dabf7" }
},
"overrides": []
},
"options": {
"reduceOptions": { "values": false, "calcs": ["min"], "fields": "" },
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"textMode": "value_and_name",
"wideLayout": true
},
"targets": [
{ "refId": "A", "datasource": { "type": "influxdb", "uid": "ha-weather-influx" }, "rawQuery": true, "format": "time_series", "rawSql": "SELECT time, value FROM \"°C\" WHERE entity_id = 'gw3000a_outdoor_temperature' AND $__timeFilter(time) ORDER BY time" }
]
},
{
"id": 11,
"title": "",
"type": "stat",
"gridPos": { "h": 4, "w": 6, "x": 6, "y": 7 },
"datasource": { "type": "influxdb", "uid": "ha-weather-influx" },
"fieldConfig": {
"defaults": {
"unit": "celsius",
"decimals": 1,
"displayName": "Temp max",
"color": { "mode": "thresholds" },
"thresholds": { "mode": "absolute", "steps": [
{ "color": "#4dabf7", "value": null },
{ "color": "#51cf66", "value": 15 },
{ "color": "#fcc419", "value": 24 },
{ "color": "#ff922b", "value": 29 },
{ "color": "#ff6b6b", "value": 34 }
] }
},
"overrides": []
},
"options": {
"reduceOptions": { "values": false, "calcs": ["max"], "fields": "" },
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"textMode": "value_and_name",
"wideLayout": true
},
"targets": [
{ "refId": "A", "datasource": { "type": "influxdb", "uid": "ha-weather-influx" }, "rawQuery": true, "format": "time_series", "rawSql": "SELECT time, value FROM \"°C\" WHERE entity_id = 'gw3000a_outdoor_temperature' AND $__timeFilter(time) ORDER BY time" }
]
},
{
"id": 12,
"title": "",
"type": "stat",
"gridPos": { "h": 4, "w": 6, "x": 12, "y": 7 },
"datasource": { "type": "influxdb", "uid": "ha-weather-influx" },
"fieldConfig": {
"defaults": {
"unit": "lengthmm",
"decimals": 1,
"displayName": "Regen",
"color": { "mode": "thresholds" },
"thresholds": { "mode": "absolute", "steps": [
{ "color": "#868e96", "value": null },
{ "color": "#4dabf7", "value": 0.2 },
{ "color": "#1c7ed6", "value": 5 },
{ "color": "#1864ab", "value": 15 }
] }
},
"overrides": []
},
"options": {
"reduceOptions": { "values": false, "calcs": ["max"], "fields": "" },
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"textMode": "value_and_name",
"wideLayout": true
},
"targets": [
{ "refId": "A", "datasource": { "type": "influxdb", "uid": "ha-weather-influx" }, "rawQuery": true, "format": "time_series", "rawSql": "SELECT time, value FROM \"mm\" WHERE entity_id = 'gw3000a_daily_rain' AND $__timeFilter(time) ORDER BY time" }
]
},
{
"id": 13,
"title": "",
"type": "stat",
"gridPos": { "h": 4, "w": 6, "x": 18, "y": 7 },
"datasource": { "type": "influxdb", "uid": "ha-weather-influx" },
"fieldConfig": {
"defaults": {
"unit": "short",
"decimals": 1,
"displayName": "UV max",
"color": { "mode": "thresholds" },
"thresholds": { "mode": "absolute", "steps": [
{ "color": "#51cf66", "value": null },
{ "color": "#94d82d", "value": 3 },
{ "color": "#fcc419", "value": 6 },
{ "color": "#ff922b", "value": 8 },
{ "color": "#ff6b6b", "value": 11 }
] }
},
"overrides": []
},
"options": {
"reduceOptions": { "values": false, "calcs": ["max"], "fields": "" },
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"textMode": "value_and_name",
"wideLayout": true
},
"targets": [
{ "refId": "A", "datasource": { "type": "influxdb", "uid": "ha-weather-influx" }, "rawQuery": true, "format": "time_series", "rawSql": "SELECT time, value FROM \"UV index\" WHERE entity_id = 'gw3000a_uv_index' AND $__timeFilter(time) ORDER BY time" }
]
},
{
"id": 14,
"title": "",
"type": "stat",
"gridPos": { "h": 4, "w": 6, "x": 0, "y": 11 },
"datasource": { "type": "influxdb", "uid": "ha-weather-influx" },
"fieldConfig": {
"defaults": {
"unit": "velocitykmh",
"decimals": 1,
"displayName": "Böe max",
"color": { "mode": "thresholds" },
"thresholds": { "mode": "absolute", "steps": [
{ "color": "#15aabf", "value": null },
{ "color": "#22b8cf", "value": 20 },
{ "color": "#fcc419", "value": 40 },
{ "color": "#ff922b", "value": 60 },
{ "color": "#ff6b6b", "value": 80 }
] }
},
"overrides": []
},
"options": {
"reduceOptions": { "values": false, "calcs": ["max"], "fields": "" },
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"textMode": "value_and_name",
"wideLayout": true
},
"targets": [
{ "refId": "A", "datasource": { "type": "influxdb", "uid": "ha-weather-influx" }, "rawQuery": true, "format": "time_series", "rawSql": "SELECT time, value FROM \"km/h\" WHERE entity_id = 'gw3000a_wind_gust' AND $__timeFilter(time) ORDER BY time" }
]
},
{
"id": 15,
"title": "",
"type": "stat",
"gridPos": { "h": 4, "w": 6, "x": 6, "y": 11 },
"datasource": { "type": "influxdb", "uid": "ha-weather-influx" },
"fieldConfig": {
"defaults": {
"unit": "percent",
"decimals": 0,
"displayName": "Luftfeuchte Ø",
"color": { "mode": "fixed", "fixedColor": "#22b8cf" }
},
"overrides": []
},
"options": {
"reduceOptions": { "values": false, "calcs": ["mean"], "fields": "" },
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"textMode": "value_and_name",
"wideLayout": true
},
"targets": [
{ "refId": "A", "datasource": { "type": "influxdb", "uid": "ha-weather-influx" }, "rawQuery": true, "format": "time_series", "rawSql": "SELECT time, value FROM \"%\" WHERE entity_id = 'gw3000a_humidity' AND $__timeFilter(time) ORDER BY time" }
]
},
{
"id": 16,
"title": "",
"type": "stat",
"gridPos": { "h": 4, "w": 6, "x": 12, "y": 11 },
"datasource": { "type": "influxdb", "uid": "ha-weather-influx" },
"fieldConfig": {
"defaults": {
"unit": "pressurehpa",
"decimals": 0,
"displayName": "Luftdruck Ø",
"color": { "mode": "fixed", "fixedColor": "#3bc9db" }
},
"overrides": []
},
"options": {
"reduceOptions": { "values": false, "calcs": ["mean"], "fields": "" },
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"textMode": "value_and_name",
"wideLayout": true
},
"targets": [
{ "refId": "A", "datasource": { "type": "influxdb", "uid": "ha-weather-influx" }, "rawQuery": true, "format": "time_series", "rawSql": "SELECT time, value FROM \"hPa\" WHERE entity_id = 'gw3000a_relative_pressure' AND $__timeFilter(time) ORDER BY time" }
]
},
{
"id": 17,
"title": "",
"type": "stat",
"gridPos": { "h": 4, "w": 6, "x": 18, "y": 11 },
"datasource": { "type": "influxdb", "uid": "ha-weather-influx" },
"fieldConfig": {
"defaults": {
"unit": "wattm2",
"decimals": 0,
"displayName": "Solar max",
"color": { "mode": "thresholds" },
"thresholds": { "mode": "absolute", "steps": [
{ "color": "#868e96", "value": null },
{ "color": "#fcc419", "value": 200 },
{ "color": "#ff922b", "value": 600 },
{ "color": "#ff6b6b", "value": 900 }
] }
},
"overrides": []
},
"options": {
"reduceOptions": { "values": false, "calcs": ["max"], "fields": "" },
"colorMode": "value",
"graphMode": "area",
"justifyMode": "auto",
"textMode": "value_and_name",
"wideLayout": true
},
"targets": [
{ "refId": "A", "datasource": { "type": "influxdb", "uid": "ha-weather-influx" }, "rawQuery": true, "format": "time_series", "rawSql": "SELECT time, value FROM \"W/m²\" WHERE entity_id = 'gw3000a_solar_radiation' AND $__timeFilter(time) ORDER BY time" }
]
},
{
"id": 20,
"title": "Temperatur über den Tag",
"type": "timeseries",
"gridPos": { "h": 9, "w": 12, "x": 0, "y": 15 },
"datasource": { "type": "influxdb", "uid": "ha-weather-influx" },
"fieldConfig": {
"defaults": { "unit": "celsius", "custom": { "drawStyle": "line", "fillOpacity": 12, "lineWidth": 2, "showPoints": "never" } },
"overrides": [
{ "matcher": { "id": "byFrameRefID", "options": "A" }, "properties": [ { "id": "displayName", "value": "Außen" }, { "id": "color", "value": { "mode": "fixed", "fixedColor": "#fa5252" } } ] },
{ "matcher": { "id": "byFrameRefID", "options": "B" }, "properties": [ { "id": "displayName", "value": "Gefühlt" }, { "id": "color", "value": { "mode": "fixed", "fixedColor": "#ff922b" } } ] },
{ "matcher": { "id": "byFrameRefID", "options": "C" }, "properties": [ { "id": "displayName", "value": "Taupunkt" }, { "id": "color", "value": { "mode": "fixed", "fixedColor": "#4dabf7" } } ] }
]
},
"options": { "legend": { "displayMode": "list", "placement": "bottom", "calcs": ["min", "max"] }, "tooltip": { "mode": "multi" } },
"targets": [
{ "refId": "A", "datasource": { "type": "influxdb", "uid": "ha-weather-influx" }, "rawQuery": true, "format": "time_series", "rawSql": "SELECT time, value FROM \"°C\" WHERE entity_id = 'gw3000a_outdoor_temperature' AND $__timeFilter(time) ORDER BY time" },
{ "refId": "B", "datasource": { "type": "influxdb", "uid": "ha-weather-influx" }, "rawQuery": true, "format": "time_series", "rawSql": "SELECT time, value FROM \"°C\" WHERE entity_id = 'gw3000a_feels_like_temperature' AND $__timeFilter(time) ORDER BY time" },
{ "refId": "C", "datasource": { "type": "influxdb", "uid": "ha-weather-influx" }, "rawQuery": true, "format": "time_series", "rawSql": "SELECT time, value FROM \"°C\" WHERE entity_id = 'gw3000a_dewpoint' AND $__timeFilter(time) ORDER BY time" }
]
},
{
"id": 21,
"title": "Sonne: Solarstrahlung & UV",
"type": "timeseries",
"gridPos": { "h": 9, "w": 12, "x": 12, "y": 15 },
"datasource": { "type": "influxdb", "uid": "ha-weather-influx" },
"fieldConfig": {
"defaults": { "custom": { "drawStyle": "line", "fillOpacity": 30, "lineWidth": 1, "showPoints": "never", "gradientMode": "opacity" } },
"overrides": [
{ "matcher": { "id": "byFrameRefID", "options": "A" }, "properties": [ { "id": "displayName", "value": "Solar" }, { "id": "unit", "value": "wattm2" }, { "id": "color", "value": { "mode": "fixed", "fixedColor": "#f2b705" } } ] },
{ "matcher": { "id": "byFrameRefID", "options": "B" }, "properties": [ { "id": "displayName", "value": "UV-Index" }, { "id": "unit", "value": "short" }, { "id": "color", "value": { "mode": "fixed", "fixedColor": "#ff6b6b" } }, { "id": "custom.axisPlacement", "value": "right" }, { "id": "custom.fillOpacity", "value": 0 }, { "id": "custom.lineWidth", "value": 2 } ] }
]
},
"options": { "legend": { "displayMode": "list", "placement": "bottom", "calcs": ["max"] }, "tooltip": { "mode": "multi" } },
"targets": [
{ "refId": "A", "datasource": { "type": "influxdb", "uid": "ha-weather-influx" }, "rawQuery": true, "format": "time_series", "rawSql": "SELECT time, value FROM \"W/m²\" WHERE entity_id = 'gw3000a_solar_radiation' AND $__timeFilter(time) ORDER BY time" },
{ "refId": "B", "datasource": { "type": "influxdb", "uid": "ha-weather-influx" }, "rawQuery": true, "format": "time_series", "rawSql": "SELECT time, value FROM \"UV index\" WHERE entity_id = 'gw3000a_uv_index' AND $__timeFilter(time) ORDER BY time" }
]
} }
] ]
} }