From 58ccbfb130beb997e2be078d249842c5041cdcb5 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Sun, 12 Apr 2026 17:28:15 -0300 Subject: [PATCH] monitoring: add humidity and dew point to climate panels --- scripts/dashboards_render_atlas.py | 60 +++++++++++++--- .../monitoring/dashboards/atlas-overview.json | 68 ++++++++++++++++-- .../monitoring/dashboards/atlas-power.json | 72 +++++++++++++++++-- .../grafana-dashboard-overview.yaml | 68 ++++++++++++++++-- .../monitoring/grafana-dashboard-power.yaml | 72 +++++++++++++++++-- 5 files changed, 305 insertions(+), 35 deletions(-) diff --git a/scripts/dashboards_render_atlas.py b/scripts/dashboards_render_atlas.py index 575b4326..a6fe0ae0 100644 --- a/scripts/dashboards_render_atlas.py +++ b/scripts/dashboards_render_atlas.py @@ -548,6 +548,20 @@ CLIMATE_PRESSURE_CURRENT = "max(typhon_vpd_kpa) or on() vector(0)" CLIMATE_HUMIDITY_MAX = "max(typhon_relative_humidity_percent) or on() vector(0)" CLIMATE_TEMP_SERIES = "typhon_temperature_celsius" CLIMATE_PRESSURE_SERIES = "typhon_vpd_kpa" +CLIMATE_HUMIDITY_SERIES = "typhon_relative_humidity_percent" +CLIMATE_DEW_POINT_CURRENT = ( + "(243.5 * (ln(clamp_min(max(typhon_relative_humidity_percent) / 100, 0.01)) " + "+ ((17.67 * max(typhon_temperature_celsius)) / (243.5 + max(typhon_temperature_celsius))))) " + "/ (17.67 - ln(clamp_min(max(typhon_relative_humidity_percent) / 100, 0.01)) " + "- ((17.67 * max(typhon_temperature_celsius)) / (243.5 + max(typhon_temperature_celsius)))) " + "or on() vector(0)" +) +CLIMATE_DEW_POINT_SERIES = ( + "(243.5 * (ln(clamp_min(typhon_relative_humidity_percent / 100, 0.01)) " + "+ ((17.67 * typhon_temperature_celsius) / (243.5 + typhon_temperature_celsius)))) " + "/ (17.67 - ln(clamp_min(typhon_relative_humidity_percent / 100, 0.01)) " + "- ((17.67 * typhon_temperature_celsius) / (243.5 + typhon_temperature_celsius)))" +) CLIMATE_FAN_OUTLET_CURRENT = ( 'max(typhon_fan_speed_level{fan_group="outlet"}) or on() vector(0)' ) @@ -1368,14 +1382,18 @@ def build_overview(): text_mode="value", targets=[ {"refId": "A", "expr": CLIMATE_TEMP_MAX, "legendFormat": "Tent Temp (°C)", "instant": True}, - {"refId": "B", "expr": CLIMATE_PRESSURE_CURRENT, "legendFormat": "Tent Pressure (kPa)", "instant": True}, + {"refId": "B", "expr": CLIMATE_PRESSURE_CURRENT, "legendFormat": "Tent VPD (kPa)", "instant": True}, + {"refId": "C", "expr": CLIMATE_HUMIDITY_MAX, "legendFormat": "Tent RH (%)", "instant": True}, + {"refId": "D", "expr": CLIMATE_DEW_POINT_CURRENT, "legendFormat": "Dew Point (°C)", "instant": True}, ], field_overrides=[ {"matcher": {"id": "byName", "options": "Tent Temp (°C)"}, "properties": [{"id": "unit", "value": "celsius"}]}, - {"matcher": {"id": "byName", "options": "Tent Pressure (kPa)"}, "properties": [{"id": "unit", "value": "suffix:kPa"}]}, + {"matcher": {"id": "byName", "options": "Tent VPD (kPa)"}, "properties": [{"id": "unit", "value": "suffix:kPa"}]}, + {"matcher": {"id": "byName", "options": "Tent RH (%)"}, "properties": [{"id": "unit", "value": "percent"}]}, + {"matcher": {"id": "byName", "options": "Dew Point (°C)"}, "properties": [{"id": "unit", "value": "celsius"}]}, ], links=link_to("atlas-power"), - description="Current tent temperature and pressure.", + description="Current tent temperature, VPD, humidity, and dew point.", orientation="vertical", wide_layout=False, ) @@ -1389,11 +1407,19 @@ def build_overview(): unit="celsius", targets=[ {"refId": "A", "expr": CLIMATE_TEMP_SERIES, "legendFormat": "Temperature (°C)"}, - {"refId": "B", "expr": CLIMATE_PRESSURE_SERIES, "legendFormat": "Pressure (kPa)"}, + {"refId": "B", "expr": CLIMATE_HUMIDITY_SERIES, "legendFormat": "Humidity (%)"}, + {"refId": "C", "expr": CLIMATE_PRESSURE_SERIES, "legendFormat": "VPD (kPa)"}, + {"refId": "D", "expr": CLIMATE_DEW_POINT_SERIES, "legendFormat": "Dew Point (°C)"}, ], field_overrides=[ { - "matcher": {"id": "byName", "options": "Pressure (kPa)"}, + "matcher": {"id": "byName", "options": "Humidity (%)"}, + "properties": [ + {"id": "unit", "value": "percent"}, + ], + }, + { + "matcher": {"id": "byName", "options": "VPD (kPa)"}, "properties": [ {"id": "unit", "value": "none"}, {"id": "custom.axisPlacement", "value": "right"}, @@ -3149,13 +3175,17 @@ def build_power_dashboard(): text_mode="name_and_value", targets=[ {"refId": "A", "expr": CLIMATE_TEMP_MAX, "legendFormat": "Tent Temp (°C)", "instant": True}, - {"refId": "B", "expr": CLIMATE_PRESSURE_CURRENT, "legendFormat": "Tent Pressure (kPa)", "instant": True}, + {"refId": "B", "expr": CLIMATE_PRESSURE_CURRENT, "legendFormat": "Tent VPD (kPa)", "instant": True}, + {"refId": "C", "expr": CLIMATE_HUMIDITY_MAX, "legendFormat": "Tent RH (%)", "instant": True}, + {"refId": "D", "expr": CLIMATE_DEW_POINT_CURRENT, "legendFormat": "Dew Point (°C)", "instant": True}, ], field_overrides=[ {"matcher": {"id": "byName", "options": "Tent Temp (°C)"}, "properties": [{"id": "unit", "value": "celsius"}]}, - {"matcher": {"id": "byName", "options": "Tent Pressure (kPa)"}, "properties": [{"id": "unit", "value": "none"}]}, + {"matcher": {"id": "byName", "options": "Tent VPD (kPa)"}, "properties": [{"id": "unit", "value": "suffix:kPa"}]}, + {"matcher": {"id": "byName", "options": "Tent RH (%)"}, "properties": [{"id": "unit", "value": "percent"}]}, + {"matcher": {"id": "byName", "options": "Dew Point (°C)"}, "properties": [{"id": "unit", "value": "celsius"}]}, ], - description="Current tent temperature and air pressure. These render once climate telemetry is online.", + description="Current tent temperature, VPD, humidity, and dew point. These render once climate telemetry is online.", ) ) panels.append( @@ -3167,11 +3197,19 @@ def build_power_dashboard(): unit="celsius", targets=[ {"refId": "A", "expr": CLIMATE_TEMP_SERIES, "legendFormat": "Temperature (°C)"}, - {"refId": "B", "expr": CLIMATE_PRESSURE_SERIES, "legendFormat": "Pressure (kPa)"}, + {"refId": "B", "expr": CLIMATE_HUMIDITY_SERIES, "legendFormat": "Humidity (%)"}, + {"refId": "C", "expr": CLIMATE_PRESSURE_SERIES, "legendFormat": "VPD (kPa)"}, + {"refId": "D", "expr": CLIMATE_DEW_POINT_SERIES, "legendFormat": "Dew Point (°C)"}, ], field_overrides=[ { - "matcher": {"id": "byName", "options": "Pressure (kPa)"}, + "matcher": {"id": "byName", "options": "Humidity (%)"}, + "properties": [ + {"id": "unit", "value": "percent"}, + ], + }, + { + "matcher": {"id": "byName", "options": "VPD (kPa)"}, "properties": [ {"id": "unit", "value": "none"}, {"id": "custom.axisPlacement", "value": "right"}, @@ -3182,7 +3220,7 @@ def build_power_dashboard(): ], legend_display="table", legend_placement="right", - description="Two-axis chart: tent temperature (left axis) and tent pressure in kPa (right axis).", + description="Two-axis chart: temperature/humidity/dew point (left axis) and VPD in kPa (right axis).", ) ) panels.append( diff --git a/services/monitoring/dashboards/atlas-overview.json b/services/monitoring/dashboards/atlas-overview.json index 5939f590..9d3d9ccb 100644 --- a/services/monitoring/dashboards/atlas-overview.json +++ b/services/monitoring/dashboards/atlas-overview.json @@ -1370,7 +1370,19 @@ { "refId": "B", "expr": "max(typhon_vpd_kpa) or on() vector(0)", - "legendFormat": "Tent Pressure (kPa)", + "legendFormat": "Tent VPD (kPa)", + "instant": true + }, + { + "refId": "C", + "expr": "max(typhon_relative_humidity_percent) or on() vector(0)", + "legendFormat": "Tent RH (%)", + "instant": true + }, + { + "refId": "D", + "expr": "(243.5 * (ln(clamp_min(max(typhon_relative_humidity_percent) / 100, 0.01)) + ((17.67 * max(typhon_temperature_celsius)) / (243.5 + max(typhon_temperature_celsius))))) / (17.67 - ln(clamp_min(max(typhon_relative_humidity_percent) / 100, 0.01)) - ((17.67 * max(typhon_temperature_celsius)) / (243.5 + max(typhon_temperature_celsius)))) or on() vector(0)", + "legendFormat": "Dew Point (\u00b0C)", "instant": true } ], @@ -1415,7 +1427,7 @@ { "matcher": { "id": "byName", - "options": "Tent Pressure (kPa)" + "options": "Tent VPD (kPa)" }, "properties": [ { @@ -1423,6 +1435,30 @@ "value": "suffix:kPa" } ] + }, + { + "matcher": { + "id": "byName", + "options": "Tent RH (%)" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Dew Point (\u00b0C)" + }, + "properties": [ + { + "id": "unit", + "value": "celsius" + } + ] } ] }, @@ -1448,7 +1484,7 @@ "targetBlank": true } ], - "description": "Current tent temperature and pressure." + "description": "Current tent temperature, VPD, humidity, and dew point." }, { "id": 43, @@ -1472,8 +1508,18 @@ }, { "refId": "B", + "expr": "typhon_relative_humidity_percent", + "legendFormat": "Humidity (%)" + }, + { + "refId": "C", "expr": "typhon_vpd_kpa", - "legendFormat": "Pressure (kPa)" + "legendFormat": "VPD (kPa)" + }, + { + "refId": "D", + "expr": "(243.5 * (ln(clamp_min(typhon_relative_humidity_percent / 100, 0.01)) + ((17.67 * typhon_temperature_celsius) / (243.5 + typhon_temperature_celsius)))) / (17.67 - ln(clamp_min(typhon_relative_humidity_percent / 100, 0.01)) - ((17.67 * typhon_temperature_celsius) / (243.5 + typhon_temperature_celsius)))", + "legendFormat": "Dew Point (\u00b0C)" } ], "fieldConfig": { @@ -1484,7 +1530,19 @@ { "matcher": { "id": "byName", - "options": "Pressure (kPa)" + "options": "Humidity (%)" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "VPD (kPa)" }, "properties": [ { diff --git a/services/monitoring/dashboards/atlas-power.json b/services/monitoring/dashboards/atlas-power.json index 01f45a23..96752ba7 100644 --- a/services/monitoring/dashboards/atlas-power.json +++ b/services/monitoring/dashboards/atlas-power.json @@ -291,7 +291,19 @@ { "refId": "B", "expr": "max(typhon_vpd_kpa) or on() vector(0)", - "legendFormat": "Tent Pressure (kPa)", + "legendFormat": "Tent VPD (kPa)", + "instant": true + }, + { + "refId": "C", + "expr": "max(typhon_relative_humidity_percent) or on() vector(0)", + "legendFormat": "Tent RH (%)", + "instant": true + }, + { + "refId": "D", + "expr": "(243.5 * (ln(clamp_min(max(typhon_relative_humidity_percent) / 100, 0.01)) + ((17.67 * max(typhon_temperature_celsius)) / (243.5 + max(typhon_temperature_celsius))))) / (17.67 - ln(clamp_min(max(typhon_relative_humidity_percent) / 100, 0.01)) - ((17.67 * max(typhon_temperature_celsius)) / (243.5 + max(typhon_temperature_celsius)))) or on() vector(0)", + "legendFormat": "Dew Point (\u00b0C)", "instant": true } ], @@ -336,12 +348,36 @@ { "matcher": { "id": "byName", - "options": "Tent Pressure (kPa)" + "options": "Tent VPD (kPa)" }, "properties": [ { "id": "unit", - "value": "none" + "value": "suffix:kPa" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Tent RH (%)" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Dew Point (\u00b0C)" + }, + "properties": [ + { + "id": "unit", + "value": "celsius" } ] } @@ -360,7 +396,7 @@ }, "textMode": "name_and_value" }, - "description": "Current tent temperature and air pressure. These render once climate telemetry is online." + "description": "Current tent temperature, VPD, humidity, and dew point. These render once climate telemetry is online." }, { "id": 4, @@ -384,8 +420,18 @@ }, { "refId": "B", + "expr": "typhon_relative_humidity_percent", + "legendFormat": "Humidity (%)" + }, + { + "refId": "C", "expr": "typhon_vpd_kpa", - "legendFormat": "Pressure (kPa)" + "legendFormat": "VPD (kPa)" + }, + { + "refId": "D", + "expr": "(243.5 * (ln(clamp_min(typhon_relative_humidity_percent / 100, 0.01)) + ((17.67 * typhon_temperature_celsius) / (243.5 + typhon_temperature_celsius)))) / (17.67 - ln(clamp_min(typhon_relative_humidity_percent / 100, 0.01)) - ((17.67 * typhon_temperature_celsius) / (243.5 + typhon_temperature_celsius)))", + "legendFormat": "Dew Point (\u00b0C)" } ], "fieldConfig": { @@ -396,7 +442,19 @@ { "matcher": { "id": "byName", - "options": "Pressure (kPa)" + "options": "Humidity (%)" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "VPD (kPa)" }, "properties": [ { @@ -428,7 +486,7 @@ "mode": "multi" } }, - "description": "Two-axis chart: tent temperature (left axis) and tent pressure in kPa (right axis)." + "description": "Two-axis chart: temperature/humidity/dew point (left axis) and VPD in kPa (right axis)." }, { "id": 5, diff --git a/services/monitoring/grafana-dashboard-overview.yaml b/services/monitoring/grafana-dashboard-overview.yaml index aced4b53..b9af6fbf 100644 --- a/services/monitoring/grafana-dashboard-overview.yaml +++ b/services/monitoring/grafana-dashboard-overview.yaml @@ -1379,7 +1379,19 @@ data: { "refId": "B", "expr": "max(typhon_vpd_kpa) or on() vector(0)", - "legendFormat": "Tent Pressure (kPa)", + "legendFormat": "Tent VPD (kPa)", + "instant": true + }, + { + "refId": "C", + "expr": "max(typhon_relative_humidity_percent) or on() vector(0)", + "legendFormat": "Tent RH (%)", + "instant": true + }, + { + "refId": "D", + "expr": "(243.5 * (ln(clamp_min(max(typhon_relative_humidity_percent) / 100, 0.01)) + ((17.67 * max(typhon_temperature_celsius)) / (243.5 + max(typhon_temperature_celsius))))) / (17.67 - ln(clamp_min(max(typhon_relative_humidity_percent) / 100, 0.01)) - ((17.67 * max(typhon_temperature_celsius)) / (243.5 + max(typhon_temperature_celsius)))) or on() vector(0)", + "legendFormat": "Dew Point (\u00b0C)", "instant": true } ], @@ -1424,7 +1436,7 @@ data: { "matcher": { "id": "byName", - "options": "Tent Pressure (kPa)" + "options": "Tent VPD (kPa)" }, "properties": [ { @@ -1432,6 +1444,30 @@ data: "value": "suffix:kPa" } ] + }, + { + "matcher": { + "id": "byName", + "options": "Tent RH (%)" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Dew Point (\u00b0C)" + }, + "properties": [ + { + "id": "unit", + "value": "celsius" + } + ] } ] }, @@ -1457,7 +1493,7 @@ data: "targetBlank": true } ], - "description": "Current tent temperature and pressure." + "description": "Current tent temperature, VPD, humidity, and dew point." }, { "id": 43, @@ -1481,8 +1517,18 @@ data: }, { "refId": "B", + "expr": "typhon_relative_humidity_percent", + "legendFormat": "Humidity (%)" + }, + { + "refId": "C", "expr": "typhon_vpd_kpa", - "legendFormat": "Pressure (kPa)" + "legendFormat": "VPD (kPa)" + }, + { + "refId": "D", + "expr": "(243.5 * (ln(clamp_min(typhon_relative_humidity_percent / 100, 0.01)) + ((17.67 * typhon_temperature_celsius) / (243.5 + typhon_temperature_celsius)))) / (17.67 - ln(clamp_min(typhon_relative_humidity_percent / 100, 0.01)) - ((17.67 * typhon_temperature_celsius) / (243.5 + typhon_temperature_celsius)))", + "legendFormat": "Dew Point (\u00b0C)" } ], "fieldConfig": { @@ -1493,7 +1539,19 @@ data: { "matcher": { "id": "byName", - "options": "Pressure (kPa)" + "options": "Humidity (%)" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "VPD (kPa)" }, "properties": [ { diff --git a/services/monitoring/grafana-dashboard-power.yaml b/services/monitoring/grafana-dashboard-power.yaml index 45bbe8f4..617e2535 100644 --- a/services/monitoring/grafana-dashboard-power.yaml +++ b/services/monitoring/grafana-dashboard-power.yaml @@ -300,7 +300,19 @@ data: { "refId": "B", "expr": "max(typhon_vpd_kpa) or on() vector(0)", - "legendFormat": "Tent Pressure (kPa)", + "legendFormat": "Tent VPD (kPa)", + "instant": true + }, + { + "refId": "C", + "expr": "max(typhon_relative_humidity_percent) or on() vector(0)", + "legendFormat": "Tent RH (%)", + "instant": true + }, + { + "refId": "D", + "expr": "(243.5 * (ln(clamp_min(max(typhon_relative_humidity_percent) / 100, 0.01)) + ((17.67 * max(typhon_temperature_celsius)) / (243.5 + max(typhon_temperature_celsius))))) / (17.67 - ln(clamp_min(max(typhon_relative_humidity_percent) / 100, 0.01)) - ((17.67 * max(typhon_temperature_celsius)) / (243.5 + max(typhon_temperature_celsius)))) or on() vector(0)", + "legendFormat": "Dew Point (\u00b0C)", "instant": true } ], @@ -345,12 +357,36 @@ data: { "matcher": { "id": "byName", - "options": "Tent Pressure (kPa)" + "options": "Tent VPD (kPa)" }, "properties": [ { "id": "unit", - "value": "none" + "value": "suffix:kPa" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Tent RH (%)" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "Dew Point (\u00b0C)" + }, + "properties": [ + { + "id": "unit", + "value": "celsius" } ] } @@ -369,7 +405,7 @@ data: }, "textMode": "name_and_value" }, - "description": "Current tent temperature and air pressure. These render once climate telemetry is online." + "description": "Current tent temperature, VPD, humidity, and dew point. These render once climate telemetry is online." }, { "id": 4, @@ -393,8 +429,18 @@ data: }, { "refId": "B", + "expr": "typhon_relative_humidity_percent", + "legendFormat": "Humidity (%)" + }, + { + "refId": "C", "expr": "typhon_vpd_kpa", - "legendFormat": "Pressure (kPa)" + "legendFormat": "VPD (kPa)" + }, + { + "refId": "D", + "expr": "(243.5 * (ln(clamp_min(typhon_relative_humidity_percent / 100, 0.01)) + ((17.67 * typhon_temperature_celsius) / (243.5 + typhon_temperature_celsius)))) / (17.67 - ln(clamp_min(typhon_relative_humidity_percent / 100, 0.01)) - ((17.67 * typhon_temperature_celsius) / (243.5 + typhon_temperature_celsius)))", + "legendFormat": "Dew Point (\u00b0C)" } ], "fieldConfig": { @@ -405,7 +451,19 @@ data: { "matcher": { "id": "byName", - "options": "Pressure (kPa)" + "options": "Humidity (%)" + }, + "properties": [ + { + "id": "unit", + "value": "percent" + } + ] + }, + { + "matcher": { + "id": "byName", + "options": "VPD (kPa)" }, "properties": [ { @@ -437,7 +495,7 @@ data: "mode": "multi" } }, - "description": "Two-axis chart: tent temperature (left axis) and tent pressure in kPa (right axis)." + "description": "Two-axis chart: temperature/humidity/dew point (left axis) and VPD in kPa (right axis)." }, { "id": 5,