diff --git a/services/grafana/dashboards/temperature.json b/services/grafana/dashboards/temperature.json new file mode 100644 index 0000000..7c80e6a --- /dev/null +++ b/services/grafana/dashboards/temperature.json @@ -0,0 +1,399 @@ +{ + "uid": "temperature-homelab", + "title": "Temperature - Homelab", + "tags": ["home-assistant", "temperature", "homelab"], + "timezone": "browser", + "schemaVersion": 39, + "version": 1, + "refresh": "1m", + "time": { + "from": "now-30d", + "to": "now" + }, + "templating": { + "list": [] + }, + "panels": [ + { + "id": 1, + "title": "Current Temperatures", + "type": "stat", + "gridPos": {"h": 6, "w": 12, "x": 0, "y": 0}, + "datasource": {"type": "prometheus", "uid": "prometheus"}, + "targets": [ + { + "expr": "hass_sensor_temperature_celsius{entity!~\".*device_temperature\"}", + "legendFormat": "{{friendly_name}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "unit": "celsius", + "thresholds": { + "mode": "absolute", + "steps": [ + {"color": "blue", "value": null}, + {"color": "green", "value": 18}, + {"color": "yellow", "value": 24}, + {"color": "orange", "value": 27}, + {"color": "red", "value": 30} + ] + }, + "mappings": [] + }, + "overrides": [] + }, + "options": { + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, + "orientation": "auto", + "textMode": "auto", + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto" + }, + "transformations": [ + { + "id": "renameByRegex", + "options": { + "regex": "Temp (.*) Temperature", + "renamePattern": "$1" + } + } + ] + }, + { + "id": 2, + "title": "Average Home Temperature", + "type": "gauge", + "gridPos": {"h": 6, "w": 6, "x": 12, "y": 0}, + "datasource": {"type": "prometheus", "uid": "prometheus"}, + "targets": [ + { + "expr": "avg(hass_sensor_temperature_celsius{entity!~\".*device_temperature|.*server.*\"})", + "legendFormat": "Average", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "unit": "celsius", + "min": 15, + "max": 30, + "thresholds": { + "mode": "absolute", + "steps": [ + {"color": "blue", "value": null}, + {"color": "green", "value": 18}, + {"color": "yellow", "value": 24}, + {"color": "red", "value": 28} + ] + } + } + }, + "options": { + "reduceOptions": { + "calcs": ["lastNotNull"] + }, + "showThresholdLabels": false, + "showThresholdMarkers": true + } + }, + { + "id": 3, + "title": "Current Humidity", + "type": "stat", + "gridPos": {"h": 6, "w": 6, "x": 18, "y": 0}, + "datasource": {"type": "prometheus", "uid": "prometheus"}, + "targets": [ + { + "expr": "hass_sensor_humidity_percent{entity!~\".*server.*\"}", + "legendFormat": "{{friendly_name}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "unit": "percent", + "thresholds": { + "mode": "absolute", + "steps": [ + {"color": "red", "value": null}, + {"color": "yellow", "value": 30}, + {"color": "green", "value": 40}, + {"color": "yellow", "value": 60}, + {"color": "red", "value": 70} + ] + } + } + }, + "options": { + "reduceOptions": { + "calcs": ["lastNotNull"] + }, + "orientation": "horizontal", + "colorMode": "value", + "graphMode": "none" + }, + "transformations": [ + { + "id": "renameByRegex", + "options": { + "regex": "Temp (.*) Humidity", + "renamePattern": "$1" + } + } + ] + }, + { + "id": 4, + "title": "Temperature History (30 Days)", + "type": "timeseries", + "gridPos": {"h": 10, "w": 24, "x": 0, "y": 6}, + "datasource": {"type": "prometheus", "uid": "prometheus"}, + "targets": [ + { + "expr": "hass_sensor_temperature_celsius{entity!~\".*device_temperature\"}", + "legendFormat": "{{friendly_name}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "unit": "celsius", + "custom": { + "lineWidth": 1, + "fillOpacity": 10, + "pointSize": 5, + "showPoints": "never", + "spanNulls": 3600000 + } + } + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "calcs": ["mean", "min", "max"] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "transformations": [ + { + "id": "renameByRegex", + "options": { + "regex": "Temp (.*) Temperature", + "renamePattern": "$1" + } + }, + { + "id": "renameByRegex", + "options": { + "regex": "temp_server Temperature", + "renamePattern": "Server" + } + } + ] + }, + { + "id": 5, + "title": "Temperature Trend (1h rate of change)", + "type": "timeseries", + "gridPos": {"h": 8, "w": 12, "x": 0, "y": 16}, + "datasource": {"type": "prometheus", "uid": "prometheus"}, + "targets": [ + { + "expr": "deriv(hass_sensor_temperature_celsius{entity!~\".*device_temperature\"}[1h]) * 3600", + "legendFormat": "{{friendly_name}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "unit": "celsius", + "custom": { + "lineWidth": 1, + "fillOpacity": 20, + "showPoints": "never", + "spanNulls": 3600000 + }, + "thresholds": { + "mode": "absolute", + "steps": [ + {"color": "blue", "value": null}, + {"color": "green", "value": -0.5}, + {"color": "green", "value": 0.5}, + {"color": "red", "value": 1} + ] + }, + "displayName": "${__field.labels.friendly_name}" + } + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "transformations": [ + { + "id": "renameByRegex", + "options": { + "regex": "Temp (.*) Temperature", + "renamePattern": "$1" + } + }, + { + "id": "renameByRegex", + "options": { + "regex": "temp_server Temperature", + "renamePattern": "Server" + } + } + ], + "description": "Rate of temperature change per hour. Positive = warming, Negative = cooling." + }, + { + "id": 6, + "title": "24h Min / Max / Avg", + "type": "table", + "gridPos": {"h": 8, "w": 12, "x": 12, "y": 16}, + "datasource": {"type": "prometheus", "uid": "prometheus"}, + "targets": [ + { + "expr": "min_over_time(hass_sensor_temperature_celsius{entity!~\".*device_temperature\"}[24h])", + "legendFormat": "{{friendly_name}}", + "refId": "min", + "instant": true + }, + { + "expr": "max_over_time(hass_sensor_temperature_celsius{entity!~\".*device_temperature\"}[24h])", + "legendFormat": "{{friendly_name}}", + "refId": "max", + "instant": true + }, + { + "expr": "avg_over_time(hass_sensor_temperature_celsius{entity!~\".*device_temperature\"}[24h])", + "legendFormat": "{{friendly_name}}", + "refId": "avg", + "instant": true + } + ], + "fieldConfig": { + "defaults": { + "unit": "celsius", + "decimals": 1 + }, + "overrides": [ + { + "matcher": {"id": "byName", "options": "Room"}, + "properties": [{"id": "custom.width", "value": 150}] + } + ] + }, + "options": { + "showHeader": true, + "sortBy": [{"displayName": "Room", "desc": false}] + }, + "transformations": [ + { + "id": "joinByField", + "options": { + "byField": "friendly_name", + "mode": "outer" + } + }, + { + "id": "organize", + "options": { + "excludeByName": { + "Time": true, + "domain": true, + "entity": true, + "hostname": true, + "instance": true, + "job": true + }, + "renameByName": { + "friendly_name": "Room", + "Value #min": "Min (24h)", + "Value #max": "Max (24h)", + "Value #avg": "Avg (24h)" + } + } + }, + { + "id": "renameByRegex", + "options": { + "regex": "Temp (.*) Temperature", + "renamePattern": "$1" + } + } + ] + }, + { + "id": 7, + "title": "Humidity History (30 Days)", + "type": "timeseries", + "gridPos": {"h": 8, "w": 24, "x": 0, "y": 24}, + "datasource": {"type": "prometheus", "uid": "prometheus"}, + "targets": [ + { + "expr": "hass_sensor_humidity_percent", + "legendFormat": "{{friendly_name}}", + "refId": "A" + } + ], + "fieldConfig": { + "defaults": { + "unit": "percent", + "min": 0, + "max": 100, + "custom": { + "lineWidth": 1, + "fillOpacity": 10, + "showPoints": "never", + "spanNulls": 3600000 + } + } + }, + "options": { + "legend": { + "displayMode": "list", + "placement": "bottom", + "calcs": ["mean", "min", "max"] + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "transformations": [ + { + "id": "renameByRegex", + "options": { + "regex": "Temp (.*) Humidity", + "renamePattern": "$1" + } + }, + { + "id": "renameByRegex", + "options": { + "regex": "temp_server Humidity", + "renamePattern": "Server" + } + } + ] + } + ] +}