feat(monitoring): restructure dashboards into Grabengasse7 folder and add Z2M alerting

This commit is contained in:
Moritz Graf 2026-07-15 22:04:47 +02:00
parent ead3e99876
commit 44508e865c
12 changed files with 279 additions and 194 deletions

View File

@ -108,4 +108,9 @@ For the full creation workflow, Flux query templates, and InfluxDB conventions,
- `../home-assistant/home-assistant.secret.yaml` — HA helm values (InfluxDB integration config)
- `../home-assistant/tmp_long_lived_token.secret.yml` — HA API token for discovery
- `../influxdb/influxdb2.secret.yml` — InfluxDB helm values
- `../influxdb/influxdb2.secret.yml` — InfluxDB helm values
## Alerting Policy
We prioritize a high threshold for alerts to prevent alarm fatigue in this private home lab environment:
* **Alert Duration Threshold:** Most alerts (including container downtime, offline bridges, and missing device metrics) are configured with a `for: 1h` duration. They are only treated as critical and trigger active alerts if they remain unresolved for longer than 1 hour.

View File

@ -139,7 +139,7 @@ data:
kind: ConfigMap
metadata:
annotations:
grafana_dashboard_folder: "\U0001F3E0 Home"
grafana_dashboard_folder: "Grabengasse7"
labels:
grafana_dashboard: '1'
name: grafana-dashboard-energy-monitor

View File

@ -6,7 +6,7 @@ metadata:
labels:
grafana_dashboard: '1'
annotations:
grafana_dashboard_folder: "🏠 Home"
grafana_dashboard_folder: "Grabengasse7"
data:
fritzbox-hosts.json: |-
{

View File

@ -6,7 +6,7 @@ metadata:
labels:
grafana_dashboard: '1'
annotations:
grafana_dashboard_folder: "🏠 Home"
grafana_dashboard_folder: "Grabengasse7"
data:
fritzbox.json: |-
{

View File

@ -90,7 +90,7 @@ data:
kind: ConfigMap
metadata:
annotations:
grafana_dashboard_folder: "\U0001F3E0 Home"
grafana_dashboard_folder: "Grabengasse7"
labels:
grafana_dashboard: '1'
name: grafana-dashboard-heating-gas

View File

@ -217,7 +217,7 @@ data:
kind: ConfigMap
metadata:
annotations:
grafana_dashboard_folder: "\U0001F3E0 Home"
grafana_dashboard_folder: "Grabengasse7"
labels:
grafana_dashboard: '1'
name: grafana-dashboard-home-climate

View File

@ -118,7 +118,7 @@ data:
kind: ConfigMap
metadata:
annotations:
grafana_dashboard_folder: "\U0001F3E0 Home"
grafana_dashboard_folder: "Grabengasse7"
labels:
grafana_dashboard: '1'
name: grafana-dashboard-outdoor-weather

View File

@ -6,7 +6,7 @@ metadata:
labels:
grafana_dashboard: "1"
annotations:
grafana_dashboard_folder: "🏡 Home"
grafana_dashboard_folder: "Grabengasse7"
data:
shelly-ws90.json: |
{
@ -15,7 +15,7 @@ data:
"tags": ["home", "weather", "outdoor", "prometheus"],
"timezone": "browser",
"schemaVersion": 39,
"version": 1,
"version": 3,
"refresh": "30s",
"editable": false,
"graphTooltip": 2,
@ -95,7 +95,7 @@ data:
{
"id": 3,
"type": "stat",
"title": "🧭 Barometric Pressure",
"title": "🧭 Current Pressure",
"gridPos": { "x": 8, "y": 0, "w": 8, "h": 3 },
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
@ -129,153 +129,159 @@ data:
{
"id": 4,
"type": "stat",
"title": "☀️ Light Level",
"title": "🌧️ Rain Status",
"gridPos": { "x": 16, "y": 0, "w": 8, "h": 3 },
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
"expr": "homeassistant_sensor_illuminance_lx{entity=\"sensor.shelly_ws90_illuminance\"}",
"expr": "homeassistant_binary_sensor_state{entity=\"binary_sensor.shelly_ws90_rain_status\"}",
"refId": "A"
}
],
"fieldConfig": {
"defaults": {
"unit": "lux",
"decimals": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{ "color": "purple", "value": null },
{ "color": "orange", "value": 1000 },
{ "color": "yellow", "value": 5000 }
]
},
"color": { "mode": "value" }
"mappings": [
{
"type": "value",
"options": {
"0": { "text": "Dry", "color": "green" },
"1": { "text": "Wet", "color": "blue" }
}
}
]
}
},
"options": {
"graphMode": "none",
"colorMode": "value",
"textMode": "auto",
"colorMode": "background",
"textMode": "value",
"reduceOptions": { "values": false, "calcs": ["lastNotNull"] }
}
},
{
"id": 5,
"type": "stat",
"title": "🌡️ Outdoor Temperature",
"gridPos": { "x": 0, "y": 3, "w": 12, "h": 8 },
"type": "timeseries",
"title": "🌡️ Thermal Comfort & Humidity History (24h)",
"gridPos": { "x": 0, "y": 3, "w": 24, "h": 8 },
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
"expr": "homeassistant_sensor_temperature_celsius{entity=\"sensor.shelly_ws90_temperatur\"}",
"legendFormat": "Temperature",
"refId": "A"
}
],
"fieldConfig": {
"defaults": {
"unit": "celsius",
"decimals": 1,
"thresholds": {
"mode": "absolute",
"steps": [
{ "color": "#5794F2", "value": null },
{ "color": "#73BF69", "value": 15 },
{ "color": "#FFD700", "value": 22 },
{ "color": "#FF7383", "value": 26 },
{ "color": "#C4162A", "value": 30 }
]
},
"color": { "mode": "thresholds" }
}
},
"options": {
"graphMode": "area",
"colorMode": "background",
"textMode": "auto",
"reduceOptions": { "values": false, "calcs": ["lastNotNull"] }
}
},
{
"id": 6,
"type": "stat",
"title": "💧 Outdoor Humidity",
"gridPos": { "x": 12, "y": 3, "w": 12, "h": 8 },
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
},
{
"expr": "homeassistant_sensor_temperature_celsius{entity=\"sensor.shelly_ws90_apparent_temperature\"}",
"legendFormat": "Apparent Temperature",
"refId": "B"
},
{
"expr": "homeassistant_sensor_temperature_celsius{entity=\"sensor.shelly_ws90_wind_chill\"}",
"legendFormat": "Wind Chill",
"refId": "C"
},
{
"expr": "homeassistant_sensor_temperature_celsius{entity=\"sensor.shelly_ws90_dew_point\"}",
"legendFormat": "Dew Point",
"refId": "D"
},
{
"expr": "homeassistant_sensor_temperature_celsius{entity=\"sensor.shelly_ws90_humidex\"}",
"legendFormat": "Humidex",
"refId": "E"
},
{
"expr": "homeassistant_sensor_humidity_percent{entity=\"sensor.shelly_ws90_luftfeuchtigkeit\"}",
"refId": "A"
}
],
"fieldConfig": {
"defaults": {
"unit": "percent",
"decimals": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{ "color": "#FF7383", "value": null },
{ "color": "#FFD700", "value": 30 },
{ "color": "#73BF69", "value": 40 },
{ "color": "#5794F2", "value": 70 }
]
},
"color": { "mode": "thresholds" }
}
},
"options": {
"graphMode": "area",
"colorMode": "background",
"textMode": "auto",
"reduceOptions": { "values": false, "calcs": ["lastNotNull"] }
}
},
{
"id": 7,
"type": "gauge",
"title": "💨 Wind Speed",
"gridPos": { "x": 0, "y": 11, "w": 6, "h": 6 },
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
"legendFormat": "Relative Humidity",
"refId": "F"
},
{
"expr": "homeassistant_sensor_wind_speed_km_per_h{entity=\"sensor.shelly_ws90_wind_speed\"} or on() vector(0)",
"refId": "A"
"expr": "homeassistant_sensor_unit_percent{entity=\"sensor.shelly_ws90_heat_stress\"}",
"legendFormat": "Heat Stress",
"refId": "G"
}
],
"fieldConfig": {
"defaults": {
"unit": "velocitykmh",
"min": 0,
"max": 100,
"thresholds": {
"mode": "absolute",
"steps": [
{ "color": "green", "value": null },
{ "color": "yellow", "value": 15 },
{ "color": "orange", "value": 30 },
{ "color": "red", "value": 50 }
"custom": {
"lineWidth": 2,
"fillOpacity": 4,
"spanNulls": true,
"showPoints": "never"
}
},
"overrides": [
{
"matcher": { "id": "byName", "options": "Temperature" },
"properties": [
{ "id": "unit", "value": "celsius" },
{ "id": "color", "value": { "fixedColor": "orange", "mode": "fixed" } }
]
},
"color": { "mode": "thresholds" }
}
{
"matcher": { "id": "byName", "options": "Apparent Temperature" },
"properties": [
{ "id": "unit", "value": "celsius" },
{ "id": "color", "value": { "fixedColor": "red", "mode": "fixed" } }
]
},
{
"matcher": { "id": "byName", "options": "Wind Chill" },
"properties": [
{ "id": "unit", "value": "celsius" },
{ "id": "color", "value": { "fixedColor": "light-blue", "mode": "fixed" } }
]
},
{
"matcher": { "id": "byName", "options": "Dew Point" },
"properties": [
{ "id": "unit", "value": "celsius" },
{ "id": "color", "value": { "fixedColor": "cyan", "mode": "fixed" } }
]
},
{
"matcher": { "id": "byName", "options": "Humidex" },
"properties": [
{ "id": "unit", "value": "celsius" },
{ "id": "color", "value": { "fixedColor": "purple", "mode": "fixed" } }
]
},
{
"matcher": { "id": "byName", "options": "Relative Humidity" },
"properties": [
{ "id": "unit", "value": "percent" },
{ "id": "color", "value": { "fixedColor": "blue", "mode": "fixed" } },
{ "id": "custom.axisPlacement", "value": "right" }
]
},
{
"matcher": { "id": "byName", "options": "Heat Stress" },
"properties": [
{ "id": "unit", "value": "percent" },
{ "id": "color", "value": { "fixedColor": "green", "mode": "fixed" } },
{ "id": "custom.axisPlacement", "value": "right" }
]
}
]
},
"options": {
"reduceOptions": { "values": false, "calcs": ["lastNotNull"] },
"orientation": "auto",
"showThresholdLabels": true,
"showThresholdMarkers": true
"legend": {
"displayMode": "table",
"placement": "bottom",
"calcs": ["lastNotNull", "min", "max", "mean"]
},
"tooltip": { "mode": "multi", "sort": "desc" }
}
},
{
"id": 8,
"type": "gauge",
"title": "🧭 Wind Direction",
"gridPos": { "x": 6, "y": 11, "w": 6, "h": 6 },
"title": "🧭 Wind Direction (Current)",
"gridPos": { "x": 0, "y": 11, "w": 6, "h": 8 },
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
"expr": "homeassistant_sensor_wind_direction_u0xb0{entity=\"sensor.shelly_ws90_wind_direction\"} or on() vector(0)",
"expr": "homeassistant_sensor_unit_u0xb0{entity=\"sensor.shelly_ws90_wind_direction\"} or on() vector(0)",
"refId": "A"
}
],
@ -301,90 +307,72 @@ data:
}
},
{
"id": 9,
"type": "gauge",
"title": "🌧️ Precipitation Rate",
"gridPos": { "x": 12, "y": 11, "w": 6, "h": 6 },
"id": 7,
"type": "timeseries",
"title": "💨 Wind & Gust Speed History (24h)",
"gridPos": { "x": 6, "y": 11, "w": 18, "h": 8 },
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
"expr": "homeassistant_sensor_precipitation_intensity_mm_per_h{entity=\"sensor.shelly_ws90_rain_rate\"} or on() vector(0)",
"expr": "homeassistant_sensor_wind_speed_km_per_h{entity=\"sensor.shelly_ws90_wind_speed\"} or on() vector(0)",
"legendFormat": "Wind Speed",
"refId": "A"
},
{
"expr": "homeassistant_sensor_wind_speed_km_per_h{entity=\"sensor.shelly_ws90_gust_speed\"} or on() vector(0)",
"legendFormat": "Gust Speed",
"refId": "B"
}
],
"fieldConfig": {
"defaults": {
"unit": "lengthmm",
"min": 0,
"max": 50,
"thresholds": {
"mode": "absolute",
"steps": [
{ "color": "green", "value": null },
{ "color": "blue", "value": 0.1 },
{ "color": "dark-blue", "value": 5 }
"unit": "velocitykmh",
"custom": {
"lineWidth": 2,
"fillOpacity": 6,
"spanNulls": true,
"showPoints": "never"
}
},
"overrides": [
{
"matcher": { "id": "byName", "options": "Wind Speed" },
"properties": [
{ "id": "color", "value": { "fixedColor": "green", "mode": "fixed" } }
]
},
"color": { "mode": "thresholds" }
}
{
"matcher": { "id": "byName", "options": "Gust Speed" },
"properties": [
{ "id": "color", "value": { "fixedColor": "yellow", "mode": "fixed" } }
]
}
]
},
"options": {
"reduceOptions": { "values": false, "calcs": ["lastNotNull"] },
"orientation": "auto",
"showThresholdLabels": true,
"showThresholdMarkers": true
"legend": {
"displayMode": "table",
"placement": "bottom",
"calcs": ["lastNotNull", "max"]
},
"tooltip": { "mode": "multi", "sort": "desc" }
}
},
{
"id": 10,
"type": "gauge",
"title": "🔆 Solar Illuminance",
"gridPos": { "x": 18, "y": 11, "w": 6, "h": 6 },
"type": "timeseries",
"title": "🔆 Solar Illuminance & UV Index History (24h)",
"gridPos": { "x": 0, "y": 19, "w": 24, "h": 8 },
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
"expr": "homeassistant_sensor_illuminance_lx{entity=\"sensor.shelly_ws90_illuminance\"}",
"refId": "A"
}
],
"fieldConfig": {
"defaults": {
"unit": "lux",
"min": 0,
"max": 100000,
"thresholds": {
"mode": "absolute",
"steps": [
{ "color": "blue", "value": null },
{ "color": "orange", "value": 1000 },
{ "color": "yellow", "value": 10000 }
]
},
"color": { "mode": "thresholds" }
}
},
"options": {
"reduceOptions": { "values": false, "calcs": ["lastNotNull"] },
"orientation": "auto",
"showThresholdLabels": true,
"showThresholdMarkers": true
}
},
{
"id": 11,
"type": "timeseries",
"title": "📈 Temperature & Humidity History (24h)",
"gridPos": { "x": 0, "y": 17, "w": 12, "h": 8 },
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
"expr": "homeassistant_sensor_temperature_celsius{entity=\"sensor.shelly_ws90_temperatur\"}",
"legendFormat": "Temperature",
"legendFormat": "Solar Illuminance",
"refId": "A"
},
{
"expr": "homeassistant_sensor_humidity_percent{entity=\"sensor.shelly_ws90_luftfeuchtigkeit\"}",
"legendFormat": "Humidity",
"expr": "homeassistant_sensor_state{entity=\"sensor.shelly_ws90_uv_index\"} or on() vector(0)",
"legendFormat": "UV Index",
"refId": "B"
}
],
@ -392,24 +380,25 @@ data:
"defaults": {
"custom": {
"lineWidth": 2,
"fillOpacity": 10,
"fillOpacity": 5,
"spanNulls": true,
"showPoints": "never"
}
},
"overrides": [
{
"matcher": { "id": "byName", "options": "Temperature" },
"matcher": { "id": "byName", "options": "Solar Illuminance" },
"properties": [
{ "id": "unit", "value": "celsius" },
{ "id": "unit", "value": "lux" },
{ "id": "color", "value": { "fixedColor": "orange", "mode": "fixed" } }
]
},
{
"matcher": { "id": "byName", "options": "Humidity" },
"matcher": { "id": "byName", "options": "UV Index" },
"properties": [
{ "id": "unit", "value": "percent" },
{ "id": "color", "value": { "fixedColor": "blue", "mode": "fixed" } },
{ "id": "unit", "value": "none" },
{ "id": "decimals", "value": 0 },
{ "id": "color", "value": { "fixedColor": "purple", "mode": "fixed" } },
{ "id": "custom.axisPlacement", "value": "right" }
]
}
@ -419,7 +408,58 @@ data:
"legend": {
"displayMode": "table",
"placement": "bottom",
"calcs": ["lastNotNull", "min", "max", "mean"]
"calcs": ["lastNotNull", "max"]
},
"tooltip": { "mode": "multi", "sort": "desc" }
}
},
{
"id": 9,
"type": "timeseries",
"title": "🌧️ Precipitation History (Hourly Bars)",
"gridPos": { "x": 0, "y": 27, "w": 12, "h": 8 },
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
"expr": "homeassistant_sensor_precipitation_intensity_mm_per_h{entity=\"sensor.shelly_ws90_rain_rate\"} or on() vector(0)",
"legendFormat": "Rain Intensity",
"refId": "A"
},
{
"expr": "homeassistant_sensor_precipitation_mm{entity=\"sensor.shelly_ws90_precipitation\"} or on() vector(0)",
"legendFormat": "Daily Rain",
"refId": "B"
}
],
"fieldConfig": {
"defaults": {
"unit": "lengthmm",
"custom": {
"drawStyle": "bars",
"fillOpacity": 60,
"spanNulls": true
}
},
"overrides": [
{
"matcher": { "id": "byName", "options": "Rain Intensity" },
"properties": [
{ "id": "color", "value": { "fixedColor": "blue", "mode": "fixed" } }
]
},
{
"matcher": { "id": "byName", "options": "Daily Rain" },
"properties": [
{ "id": "color", "value": { "fixedColor": "dark-blue", "mode": "fixed" } }
]
}
]
},
"options": {
"legend": {
"displayMode": "table",
"placement": "bottom",
"calcs": ["lastNotNull", "max"]
},
"tooltip": { "mode": "multi", "sort": "desc" }
}
@ -427,8 +467,8 @@ data:
{
"id": 12,
"type": "timeseries",
"title": "📉 Pressure & Precipitation History (24h)",
"gridPos": { "x": 12, "y": 17, "w": 12, "h": 8 },
"title": "🧭 Barometric Pressure History (24h)",
"gridPos": { "x": 12, "y": 27, "w": 12, "h": 8 },
"datasource": { "type": "prometheus", "uid": "prometheus" },
"targets": [
{
@ -437,8 +477,8 @@ data:
"refId": "A"
},
{
"expr": "homeassistant_sensor_precipitation_intensity_mm_per_h{entity=\"sensor.shelly_ws90_rain_rate\"} or on() vector(0)",
"legendFormat": "Rain Intensity",
"expr": "homeassistant_sensor_unit_hpa_per_h{entity=\"sensor.shelly_ws90_pressure_trend\"} or on() vector(0)",
"legendFormat": "Pressure Trend",
"refId": "B"
}
],
@ -446,7 +486,7 @@ data:
"defaults": {
"custom": {
"lineWidth": 2,
"fillOpacity": 10,
"fillOpacity": 5,
"spanNulls": true,
"showPoints": "never"
}
@ -460,10 +500,10 @@ data:
]
},
{
"matcher": { "id": "byName", "options": "Rain Intensity" },
"matcher": { "id": "byName", "options": "Pressure Trend" },
"properties": [
{ "id": "unit", "value": "lengthmm" },
{ "id": "color", "value": { "fixedColor": "dark-blue", "mode": "fixed" } },
{ "id": "unit", "value": "none" },
{ "id": "color", "value": { "fixedColor": "cyan", "mode": "fixed" } },
{ "id": "custom.axisPlacement", "value": "right" }
]
}
@ -473,7 +513,7 @@ data:
"legend": {
"displayMode": "table",
"placement": "bottom",
"calcs": ["lastNotNull", "min", "max", "mean"]
"calcs": ["lastNotNull", "min", "max"]
},
"tooltip": { "mode": "multi", "sort": "desc" }
}

View File

@ -6,7 +6,7 @@ metadata:
labels:
grafana_dashboard: '1'
annotations:
grafana_dashboard_folder: 🏠 Home
grafana_dashboard_folder: "Grabengasse7"
data:
taupi-fan.json: |
{

View File

@ -6,7 +6,7 @@ metadata:
labels:
grafana_dashboard: '1'
annotations:
grafana_dashboard_folder: 🏠 Home
grafana_dashboard_folder: "Grabengasse7"
data:
wireguard.json: |
{

View File

@ -181,6 +181,7 @@ grafana:
searchNamespace: monitoring
folder: /tmp/dashboards
defaultFolderName: null
folderAnnotation: grafana_dashboard_folder
provider:
name: sidecarProvider
orgId: 1
@ -189,6 +190,7 @@ grafana:
disableDeletion: false
editable: false
allowUiUpdates: false
foldersFromFilesStructure: true
options:
path: /tmp/dashboards

View File

@ -166,3 +166,41 @@ spec:
- hosts:
- "zigbee2mqtt.moritzgraf.de"
secretName: zigbee2mqtt-tls
---
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: zigbee2mqtt-alerts
namespace: monitoring
labels:
release: prometheus-operator
spec:
groups:
- name: zigbee2mqtt.rules
rules:
- alert: Zigbee2MQTTDown
expr: kube_pod_container_status_ready{container="zigbee2mqtt", namespace="monitoring"} == 0
for: 1h
labels:
severity: critical
annotations:
summary: "Zigbee2MQTT is down"
description: "The Zigbee2MQTT pod is not ready. This typically indicates a connection failure to the SLZB-MR1U coordinator host at 192.168.10.10:7638, or a crash within the Z2M application."
- alert: Zigbee2MQTTBridgeOffline
expr: homeassistant_binary_sensor_state{entity="binary_sensor.zigbee2mqtt_bridge_connection_state"} == 0
for: 1h
labels:
severity: critical
annotations:
summary: "Zigbee2MQTT Bridge Connection Offline"
description: "The Zigbee2MQTT bridge connection is reported as offline. The bridge has lost communication with the MQTT broker or the Zigbee coordinator."
- alert: ShellyWS90MetricsStale
expr: absent(homeassistant_sensor_temperature_celsius{entity="sensor.shelly_ws90_temperatur"}) or (time() - homeassistant_last_updated_time_seconds{entity="sensor.shelly_ws90_temperatur"} > 0)
for: 1h
labels:
severity: warning
annotations:
summary: "Shelly WS90 Weather Station metrics are stale"
description: "No new metrics have been received from the Shelly WS90 weather station (sensor.shelly_ws90_temperatur) for over 1 hour. The device may be offline, out of range, or batteries might be depleted."