feat(monitoring): add prometheus metrics, alerts, and dashboard for taupi fan
This commit is contained in:
@@ -0,0 +1,266 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: grafana-dashboard-taupi-fan
|
||||
namespace: monitoring
|
||||
labels:
|
||||
grafana_dashboard: '1'
|
||||
annotations:
|
||||
grafana_dashboard_folder: 🏠 Home
|
||||
data:
|
||||
taupi-fan.json: |
|
||||
{
|
||||
"uid": "taupi-fan",
|
||||
"title": "💨 Cellar Fan (TAUPI)",
|
||||
"tags": ["climate", "fan", "cellar", "prometheus"],
|
||||
"timezone": "browser",
|
||||
"schemaVersion": 39,
|
||||
"version": 1,
|
||||
"refresh": "30s",
|
||||
"editable": false,
|
||||
"graphTooltip": 1,
|
||||
"time": {
|
||||
"from": "now-24h",
|
||||
"to": "now"
|
||||
},
|
||||
"panels": [
|
||||
{
|
||||
"title": "⚡ Status & Controls",
|
||||
"type": "row",
|
||||
"gridPos": {"h": 1, "w": 24, "x": 0, "y": 0},
|
||||
"collapsed": false
|
||||
},
|
||||
{
|
||||
"title": "Fan Power Relay",
|
||||
"type": "stat",
|
||||
"datasource": {"type": "prometheus", "uid": "prometheus"},
|
||||
"gridPos": {"h": 4, "w": 6, "x": 0, "y": 1},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"mappings": [
|
||||
{"type": "value", "options": {"0": {"text": "OFF", "color": "blue"}, "1": {"text": "ON", "color": "orange"}}}
|
||||
],
|
||||
"color": {"mode": "thresholds"}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"graphMode": "none",
|
||||
"colorMode": "background",
|
||||
"textMode": "auto",
|
||||
"reduceOptions": {"values": false, "calcs": ["lastNotNull"]}
|
||||
},
|
||||
"targets": [
|
||||
{"expr": "taupi_relay_status", "legendFormat": "Fan Status"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Mold Danger Status",
|
||||
"type": "stat",
|
||||
"datasource": {"type": "prometheus", "uid": "prometheus"},
|
||||
"gridPos": {"h": 4, "w": 6, "x": 6, "y": 1},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"mappings": [
|
||||
{"type": "value", "options": {"0": {"text": "SAFE", "color": "green"}, "1": {"text": "CRITICAL", "color": "red"}}}
|
||||
]
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"graphMode": "none",
|
||||
"colorMode": "background",
|
||||
"textMode": "auto",
|
||||
"reduceOptions": {"values": false, "calcs": ["lastNotNull"]}
|
||||
},
|
||||
"targets": [
|
||||
{"expr": "taupi_is_critical", "legendFormat": "Mold Danger"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Activation Criteria Met",
|
||||
"type": "stat",
|
||||
"datasource": {"type": "prometheus", "uid": "prometheus"},
|
||||
"gridPos": {"h": 4, "w": 6, "x": 12, "y": 1},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"mappings": [
|
||||
{"type": "value", "options": {"0": {"text": "NO", "color": "gray"}, "1": {"text": "YES", "color": "green"}}}
|
||||
]
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"graphMode": "none",
|
||||
"colorMode": "background",
|
||||
"textMode": "auto",
|
||||
"reduceOptions": {"values": false, "calcs": ["lastNotNull"]}
|
||||
},
|
||||
"targets": [
|
||||
{"expr": "taupi_would_fan_activate", "legendFormat": "Dewpoint Condition"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Shelly Plug Reachability",
|
||||
"type": "stat",
|
||||
"datasource": {"type": "prometheus", "uid": "prometheus"},
|
||||
"gridPos": {"h": 4, "w": 6, "x": 18, "y": 1},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"mappings": [
|
||||
{"type": "value", "options": {"0": {"text": "OFFLINE", "color": "red"}, "1": {"text": "ONLINE", "color": "green"}}}
|
||||
]
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"graphMode": "none",
|
||||
"colorMode": "background",
|
||||
"textMode": "auto",
|
||||
"reduceOptions": {"values": false, "calcs": ["lastNotNull"]}
|
||||
},
|
||||
"targets": [
|
||||
{"expr": "up{job=\"taupi-fan\"}", "legendFormat": "Connectivity"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "🌡️ Climate Details",
|
||||
"type": "row",
|
||||
"gridPos": {"h": 1, "w": 24, "x": 0, "y": 5},
|
||||
"collapsed": false
|
||||
},
|
||||
{
|
||||
"title": "Temperatures",
|
||||
"type": "timeseries",
|
||||
"datasource": {"type": "prometheus", "uid": "prometheus"},
|
||||
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 6},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"unit": "celsius",
|
||||
"custom": {
|
||||
"lineWidth": 2,
|
||||
"fillOpacity": 5,
|
||||
"spanNulls": true,
|
||||
"showPoints": "never"
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"legend": {"displayMode": "table", "placement": "bottom", "calcs": ["min", "max", "mean"]},
|
||||
"tooltip": {"mode": "multi", "sort": "desc"}
|
||||
},
|
||||
"targets": [
|
||||
{"expr": "taupi_temperature_celsius_innen", "legendFormat": "Indoor Temperature"},
|
||||
{"expr": "taupi_temperature_celsius_aussen", "legendFormat": "Outdoor Temperature"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Dew Points",
|
||||
"type": "timeseries",
|
||||
"datasource": {"type": "prometheus", "uid": "prometheus"},
|
||||
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 6},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"unit": "celsius",
|
||||
"custom": {
|
||||
"lineWidth": 2,
|
||||
"fillOpacity": 5,
|
||||
"spanNulls": true,
|
||||
"showPoints": "never"
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"legend": {"displayMode": "table", "placement": "bottom", "calcs": ["min", "max", "mean"]},
|
||||
"tooltip": {"mode": "multi", "sort": "desc"}
|
||||
},
|
||||
"targets": [
|
||||
{"expr": "taupi_dewpoint_celsius_innen", "legendFormat": "Indoor Dewpoint"},
|
||||
{"expr": "taupi_dewpoint_celsius_aussen", "legendFormat": "Outdoor Dewpoint"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Relative Humidity vs. Mold Threshold",
|
||||
"type": "timeseries",
|
||||
"datasource": {"type": "prometheus", "uid": "prometheus"},
|
||||
"gridPos": {"h": 8, "w": 24, "x": 0, "y": 14},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"unit": "percent",
|
||||
"custom": {
|
||||
"lineWidth": 2,
|
||||
"fillOpacity": 5,
|
||||
"spanNulls": true,
|
||||
"showPoints": "never"
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"legend": {"displayMode": "table", "placement": "bottom", "calcs": ["min", "max", "mean"]},
|
||||
"tooltip": {"mode": "multi", "sort": "desc"}
|
||||
},
|
||||
"targets": [
|
||||
{"expr": "taupi_humidity_percent_innen", "legendFormat": "Indoor Humidity"},
|
||||
{"expr": "taupi_humidity_percent_aussen", "legendFormat": "Outdoor Humidity"},
|
||||
{"expr": "taupi_critical_humidity_threshold_percent", "legendFormat": "Mold Danger Threshold"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "🔋 BLE Sensors Diagnostic",
|
||||
"type": "row",
|
||||
"gridPos": {"h": 1, "w": 24, "x": 0, "y": 22},
|
||||
"collapsed": false
|
||||
},
|
||||
{
|
||||
"title": "Sensor Batteries",
|
||||
"type": "gauge",
|
||||
"datasource": {"type": "prometheus", "uid": "prometheus"},
|
||||
"gridPos": {"h": 6, "w": 12, "x": 0, "y": 23},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"unit": "percent",
|
||||
"min": 0,
|
||||
"max": 100,
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{"color": "red", "value": null},
|
||||
{"color": "orange", "value": 20},
|
||||
{"color": "green", "value": 50}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"reduceOptions": {"values": false, "calcs": ["lastNotNull"]},
|
||||
"showThresholdLabels": false,
|
||||
"showThresholdMarkers": true
|
||||
},
|
||||
"targets": [
|
||||
{"expr": "taupi_battery_percent_innen", "legendFormat": "Indoor Sensor Battery"},
|
||||
{"expr": "taupi_battery_percent_aussen", "legendFormat": "Outdoor Sensor Battery"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Sensor Connection Age (Staleness)",
|
||||
"type": "timeseries",
|
||||
"datasource": {"type": "prometheus", "uid": "prometheus"},
|
||||
"gridPos": {"h": 6, "w": 12, "x": 12, "y": 23},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"unit": "s",
|
||||
"custom": {
|
||||
"lineWidth": 2,
|
||||
"fillOpacity": 5,
|
||||
"spanNulls": true,
|
||||
"showPoints": "never"
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"legend": {"displayMode": "table", "placement": "bottom", "calcs": ["lastNotNull"]},
|
||||
"tooltip": {"mode": "multi", "sort": "desc"}
|
||||
},
|
||||
"targets": [
|
||||
{"expr": "taupi_lost_connection_seconds_innen", "legendFormat": "Indoor Connection Stale Time"},
|
||||
{"expr": "taupi_lost_connection_seconds_aussen", "legendFormat": "Outdoor Connection Stale Time"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: taupi-fan
|
||||
namespace: monitoring
|
||||
labels:
|
||||
app: taupi-fan
|
||||
spec:
|
||||
ports:
|
||||
- name: http-metrics
|
||||
port: 80
|
||||
targetPort: 80
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Endpoints
|
||||
metadata:
|
||||
name: taupi-fan
|
||||
namespace: monitoring
|
||||
labels:
|
||||
app: taupi-fan
|
||||
subsets:
|
||||
- addresses:
|
||||
- ip: 192.168.10.168
|
||||
ports:
|
||||
- name: http-metrics
|
||||
port: 80
|
||||
---
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
name: taupi-fan
|
||||
namespace: monitoring
|
||||
labels:
|
||||
app: taupi-fan
|
||||
release: prometheus-operator
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: taupi-fan
|
||||
namespaceSelector:
|
||||
matchNames:
|
||||
- monitoring
|
||||
endpoints:
|
||||
- port: http-metrics
|
||||
path: /script/1/prometheus
|
||||
interval: 30s
|
||||
scrapeTimeout: 10s
|
||||
---
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: PrometheusRule
|
||||
metadata:
|
||||
name: taupi-fan-alerts
|
||||
namespace: monitoring
|
||||
labels:
|
||||
release: prometheus-operator
|
||||
spec:
|
||||
groups:
|
||||
- name: taupi-fan.rules
|
||||
rules:
|
||||
- alert: TaupiFanOffline
|
||||
expr: up{job="taupi-fan"} == 0
|
||||
for: 5m
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "Id: {{ $labels.instance }} - TAUPI Fan Plug is unreachable"
|
||||
description: "The Shelly plug at 192.168.10.168 is unreachable by Prometheus. Check Wi-Fi connection or power status."
|
||||
- alert: TaupiFanSensorsStale
|
||||
expr: taupi_lost_connection_seconds_innen > 600 or taupi_lost_connection_seconds_aussen > 600
|
||||
for: 5m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "TAUPI Fan BLE sensors stale"
|
||||
description: "The BLE sensors for temperature and humidity inside or outside have not sent new data for over 10 minutes."
|
||||
- alert: TaupiFanMoldDanger
|
||||
expr: taupi_is_critical == 1
|
||||
for: 30m
|
||||
labels:
|
||||
severity: warning
|
||||
annotations:
|
||||
summary: "Cellar mold risk detected"
|
||||
description: "The cellar relative humidity has exceeded the critical mold threshold (inside humidity is high enough that mold can grow on cold wall surfaces)."
|
||||
Reference in New Issue
Block a user