From f1bb65cb73683cc39a14b6c49baf1d27354766e9 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Mon, 13 Apr 2026 01:08:58 -0300 Subject: [PATCH] monitoring(overview): center climate/ups cards and add UPS discharge risk coloring --- scripts/dashboards_render_atlas.py | 95 ++++++++--- .../monitoring/dashboards/atlas-overview.json | 148 ++++++++++-------- .../grafana-dashboard-overview.yaml | 148 ++++++++++-------- 3 files changed, 242 insertions(+), 149 deletions(-) diff --git a/scripts/dashboards_render_atlas.py b/scripts/dashboards_render_atlas.py index a1065078..7a15e271 100644 --- a/scripts/dashboards_render_atlas.py +++ b/scripts/dashboards_render_atlas.py @@ -609,6 +609,12 @@ ANANKE_UPS_ON_BATTERY_DB = ( ANANKE_UPS_ON_BATTERY_TETHYS = ( f'max(ananke_ups_on_battery{{{ANANKE_UPS_TETHYS_SELECTOR}}}) or on() vector(0)' ) +ANANKE_UPS_THRESHOLD_DB = ( + f'clamp_min(max(ananke_ups_threshold_seconds{{{ANANKE_UPS_DB_SELECTOR}}}), 1)' +) +ANANKE_UPS_THRESHOLD_TETHYS = ( + f'clamp_min(max(ananke_ups_threshold_seconds{{{ANANKE_UPS_TETHYS_SELECTOR}}}), 1)' +) ANANKE_UPS_BATTERY_CHARGE_DB = ( f'max(ananke_ups_battery_charge_percent{{{ANANKE_UPS_DB_SELECTOR}}}) or on() vector(0)' ) @@ -648,6 +654,27 @@ ANANKE_UPS_RUNTIME_BY_SOURCE = f"ananke_ups_runtime_seconds{{{ANANKE_SELECTOR}}} ANANKE_UPS_LOAD_BY_SOURCE = f"ananke_ups_load_percent{{{ANANKE_SELECTOR}}}" ANANKE_UPS_CHARGE_BY_SOURCE = f"ananke_ups_battery_charge_percent{{{ANANKE_SELECTOR}}}" ANANKE_UPS_TRIGGER_BY_SOURCE = f"ananke_ups_trigger_active{{{ANANKE_SELECTOR}}}" + + +def ups_discharge_risk_expr(on_battery_expr, runtime_expr, shutdown_threshold_expr): + return ( + f"((({on_battery_expr}) > bool 0) * (" + f"1 + (({runtime_expr}) < bool (3 * ({shutdown_threshold_expr}))) + " + f"(({runtime_expr}) < bool (2 * ({shutdown_threshold_expr})))" + f")) or on() vector(0)" + ) + + +ANANKE_UPS_DISCHARGE_RISK_DB = ups_discharge_risk_expr( + ANANKE_UPS_ON_BATTERY_DB, + ANANKE_UPS_RUNTIME_DB, + ANANKE_UPS_THRESHOLD_DB, +) +ANANKE_UPS_DISCHARGE_RISK_TETHYS = ups_discharge_risk_expr( + ANANKE_UPS_ON_BATTERY_TETHYS, + ANANKE_UPS_RUNTIME_TETHYS, + ANANKE_UPS_THRESHOLD_TETHYS, +) CLIMATE_SENSOR_COUNT = "count(typhon_temperature_celsius) or on() vector(0)" CLIMATE_DEDUP_LABELS = "job,instance,pod,service,endpoint,namespace" CLIMATE_TEMP_SERIES = ( @@ -664,19 +691,19 @@ CLIMATE_TEMP_MAX = f"max({CLIMATE_TEMP_SERIES}) or on() vector(0)" CLIMATE_TEMP_FAHRENHEIT_MAX = f"max({CLIMATE_TEMP_FAHRENHEIT_SERIES}) or on() vector(0)" CLIMATE_PRESSURE_CURRENT = f"max({CLIMATE_PRESSURE_SERIES}) or on() vector(0)" CLIMATE_HUMIDITY_MAX = f"max({CLIMATE_HUMIDITY_SERIES}) or on() vector(0)" -CLIMATE_TEMP_MIN_BOUND_SERIES = f"(min_over_time({CLIMATE_TEMP_SERIES}[$__range]) - 0.4)" -CLIMATE_TEMP_MAX_BOUND_SERIES = f"(max_over_time({CLIMATE_TEMP_SERIES}[$__range]) + 0.4)" +CLIMATE_TEMP_MIN_BOUND_SERIES = f"(min_over_time({CLIMATE_TEMP_SERIES}[$__range]) - 0.08)" +CLIMATE_TEMP_MAX_BOUND_SERIES = f"(max_over_time({CLIMATE_TEMP_SERIES}[$__range]) + 0.08)" CLIMATE_HUMIDITY_MIN_BOUND_SERIES = ( - f"clamp_min((min_over_time({CLIMATE_HUMIDITY_SERIES}[$__range]) - 2), 0)" + f"clamp_min((min_over_time({CLIMATE_HUMIDITY_SERIES}[$__range]) - 0.35), 0)" ) CLIMATE_HUMIDITY_MAX_BOUND_SERIES = ( - f"clamp_max((max_over_time({CLIMATE_HUMIDITY_SERIES}[$__range]) + 2), 100)" + f"clamp_max((max_over_time({CLIMATE_HUMIDITY_SERIES}[$__range]) + 0.35), 100)" ) CLIMATE_PRESSURE_MIN_BOUND_SERIES = ( - f"clamp_min((min_over_time({CLIMATE_PRESSURE_SERIES}[$__range]) - 0.15), 0)" + f"clamp_min((min_over_time({CLIMATE_PRESSURE_SERIES}[$__range]) - 0.03), 0)" ) CLIMATE_PRESSURE_MAX_BOUND_SERIES = ( - f"(max_over_time({CLIMATE_PRESSURE_SERIES}[$__range]) + 0.15)" + f"(max_over_time({CLIMATE_PRESSURE_SERIES}[$__range]) + 0.03)" ) CLIMATE_FAN_OUTLET_CURRENT = ( f'max(max without ({CLIMATE_DEDUP_LABELS}) (typhon_fan_speed_level{{fan_group="outlet"}})) or on() vector(0)' @@ -1014,9 +1041,14 @@ def canvas_metric_grid_panel( description=None, metric_size=26, label_size=12, + color_fields=None, + thresholds=None, ): """Return a canvas panel with a deterministic 2x2 metric layout.""" + if color_fields is None: + color_fields = [targets[0]["legendFormat"], targets[1]["legendFormat"], targets[2]["legendFormat"], targets[3]["legendFormat"]] + def text_element(name, text, left, top): return { "type": "text", @@ -1031,7 +1063,7 @@ def canvas_metric_grid_panel( "background": {"color": {"fixed": "transparent"}}, "border": {"color": {"fixed": "transparent"}}, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": label_size, "color": {"fixed": "text"}, @@ -1056,10 +1088,10 @@ def canvas_metric_grid_panel( "background": {"color": {"fixed": "transparent"}}, "border": {"color": {"fixed": "transparent"}}, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": metric_size, - "color": {"field": field, "fixed": "text"}, + "color": {"field": color_fields[int(name.split()[-1]) - 1], "fixed": "text"}, "text": { "mode": "field", "field": field, @@ -1079,7 +1111,8 @@ def canvas_metric_grid_panel( "fieldConfig": { "defaults": { "mappings": [], - "thresholds": { + "thresholds": thresholds + or { "mode": "absolute", "steps": [ {"color": "rgba(115, 115, 115, 1)", "value": None}, @@ -1099,14 +1132,14 @@ def canvas_metric_grid_panel( "type": "frame", "name": f"{title} frame", "elements": [ - text_element("Cell 1 label", targets[0]["legendFormat"], 10, 6), - metric_element("Cell 1", targets[0]["legendFormat"], 10, 20), - text_element("Cell 2 label", targets[1]["legendFormat"], 166, 6), - metric_element("Cell 2", targets[1]["legendFormat"], 166, 20), - text_element("Cell 3 label", targets[2]["legendFormat"], 10, 64), - metric_element("Cell 3", targets[2]["legendFormat"], 10, 78), - text_element("Cell 4 label", targets[3]["legendFormat"], 166, 64), - metric_element("Cell 4", targets[3]["legendFormat"], 166, 78), + text_element("Cell 1 label", targets[0]["legendFormat"], 12, 18), + metric_element("Cell 1", targets[0]["legendFormat"], 12, 32), + text_element("Cell 2 label", targets[1]["legendFormat"], 168, 18), + metric_element("Cell 2", targets[1]["legendFormat"], 168, 32), + text_element("Cell 3 label", targets[2]["legendFormat"], 12, 76), + metric_element("Cell 3", targets[2]["legendFormat"], 12, 90), + text_element("Cell 4 label", targets[3]["legendFormat"], 168, 76), + metric_element("Cell 4", targets[3]["legendFormat"], 168, 90), ], "background": {"color": {"fixed": "transparent"}}, "border": {"color": {"fixed": "transparent"}}, @@ -1716,13 +1749,33 @@ def build_overview(): {"refId": "B", "expr": ANANKE_UPS_RUNTIME_DB, "legendFormat": f"{ANANKE_UPS_DB_NAME} Runtime", "instant": True}, {"refId": "C", "expr": ANANKE_UPS_DRAW_WATTS_TETHYS, "legendFormat": f"{ANANKE_UPS_TETHYS_NAME} Draw", "instant": True}, {"refId": "D", "expr": ANANKE_UPS_RUNTIME_TETHYS, "legendFormat": f"{ANANKE_UPS_TETHYS_NAME} Runtime", "instant": True}, + {"refId": "E", "expr": ANANKE_UPS_DISCHARGE_RISK_DB, "legendFormat": f"{ANANKE_UPS_DB_NAME} Risk", "instant": True}, + {"refId": "F", "expr": ANANKE_UPS_DISCHARGE_RISK_TETHYS, "legendFormat": f"{ANANKE_UPS_TETHYS_NAME} Risk", "instant": True}, ], field_overrides=[ {"matcher": {"id": "byRegexp", "options": ".*Draw$"}, "properties": [{"id": "unit", "value": "watt"}]}, {"matcher": {"id": "byRegexp", "options": ".*Runtime$"}, "properties": [{"id": "unit", "value": "s"}]}, ], + color_fields=[ + f"{ANANKE_UPS_DB_NAME} Risk", + f"{ANANKE_UPS_DB_NAME} Risk", + f"{ANANKE_UPS_TETHYS_NAME} Risk", + f"{ANANKE_UPS_TETHYS_NAME} Risk", + ], + thresholds={ + "mode": "absolute", + "steps": [ + {"color": "green", "value": None}, + {"color": "yellow", "value": 1}, + {"color": "orange", "value": 2}, + {"color": "red", "value": 3}, + ], + }, links=link_to("atlas-power"), - description="Per-UPS live snapshot in a fixed 2x2 layout: Pyrphoros draw/runtime, Statera draw/runtime.", + description=( + "Per-UPS live snapshot in a centered 2x2 layout. " + "Color turns yellow when discharging, orange below 3x graceful shutdown runtime, red below 2x." + ), metric_size=26, ) ) @@ -1746,7 +1799,7 @@ def build_overview(): panels.append( canvas_metric_grid_panel( 42, - "Current Climate", + "Current Enclosure Climate", {"h": 6, "w": 6, "x": 0, "y": 12}, targets=[ {"refId": "A", "expr": CLIMATE_TEMP_MAX, "legendFormat": "Temp °C", "instant": True}, @@ -1768,7 +1821,7 @@ def build_overview(): panels.append( timeseries_panel( 43, - "Climate History", + "Enclosure Climate History", None, {"h": 6, "w": 6, "x": 6, "y": 12}, unit="none", diff --git a/services/monitoring/dashboards/atlas-overview.json b/services/monitoring/dashboards/atlas-overview.json index 1de28e57..b91ec265 100644 --- a/services/monitoring/dashboards/atlas-overview.json +++ b/services/monitoring/dashboards/atlas-overview.json @@ -1108,6 +1108,18 @@ "expr": "max(ananke_ups_runtime_seconds{job=\"ananke-power\",source=\"Statera\"}) or on() vector(0)", "legendFormat": "Statera Runtime", "instant": true + }, + { + "refId": "E", + "expr": "(((max(ananke_ups_on_battery{job=\"ananke-power\",source=\"Pyrphoros\"}) or on() vector(0)) > bool 0) * (1 + ((max(ananke_ups_runtime_seconds{job=\"ananke-power\",source=\"Pyrphoros\"}) or on() vector(0)) < bool (3 * (clamp_min(max(ananke_ups_threshold_seconds{job=\"ananke-power\",source=\"Pyrphoros\"}), 1)))) + ((max(ananke_ups_runtime_seconds{job=\"ananke-power\",source=\"Pyrphoros\"}) or on() vector(0)) < bool (2 * (clamp_min(max(ananke_ups_threshold_seconds{job=\"ananke-power\",source=\"Pyrphoros\"}), 1)))))) or on() vector(0)", + "legendFormat": "Pyrphoros Risk", + "instant": true + }, + { + "refId": "F", + "expr": "(((max(ananke_ups_on_battery{job=\"ananke-power\",source=\"Statera\"}) or on() vector(0)) > bool 0) * (1 + ((max(ananke_ups_runtime_seconds{job=\"ananke-power\",source=\"Statera\"}) or on() vector(0)) < bool (3 * (clamp_min(max(ananke_ups_threshold_seconds{job=\"ananke-power\",source=\"Statera\"}), 1)))) + ((max(ananke_ups_runtime_seconds{job=\"ananke-power\",source=\"Statera\"}) or on() vector(0)) < bool (2 * (clamp_min(max(ananke_ups_threshold_seconds{job=\"ananke-power\",source=\"Statera\"}), 1)))))) or on() vector(0)", + "legendFormat": "Statera Risk", + "instant": true } ], "fieldConfig": { @@ -1117,12 +1129,20 @@ "mode": "absolute", "steps": [ { - "color": "rgba(115, 115, 115, 1)", + "color": "green", "value": null }, { - "color": "green", + "color": "yellow", "value": 1 + }, + { + "color": "orange", + "value": 2 + }, + { + "color": "red", + "value": 3 } ] }, @@ -1174,8 +1194,8 @@ "vertical": "top" }, "placement": { - "left": 10, - "top": 6, + "left": 12, + "top": 18, "width": 146, "height": 14 }, @@ -1190,7 +1210,7 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1210,8 +1230,8 @@ "vertical": "top" }, "placement": { - "left": 10, - "top": 20, + "left": 12, + "top": 32, "width": 146, "height": 42 }, @@ -1226,11 +1246,11 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 26, "color": { - "field": "Pyrphoros Draw", + "field": "Pyrphoros Risk", "fixed": "text" }, "text": { @@ -1249,8 +1269,8 @@ "vertical": "top" }, "placement": { - "left": 166, - "top": 6, + "left": 168, + "top": 18, "width": 146, "height": 14 }, @@ -1265,7 +1285,7 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1285,8 +1305,8 @@ "vertical": "top" }, "placement": { - "left": 166, - "top": 20, + "left": 168, + "top": 32, "width": 146, "height": 42 }, @@ -1301,11 +1321,11 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 26, "color": { - "field": "Pyrphoros Runtime", + "field": "Pyrphoros Risk", "fixed": "text" }, "text": { @@ -1324,8 +1344,8 @@ "vertical": "top" }, "placement": { - "left": 10, - "top": 64, + "left": 12, + "top": 76, "width": 146, "height": 14 }, @@ -1340,7 +1360,7 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1360,8 +1380,8 @@ "vertical": "top" }, "placement": { - "left": 10, - "top": 78, + "left": 12, + "top": 90, "width": 146, "height": 42 }, @@ -1376,11 +1396,11 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 26, "color": { - "field": "Statera Draw", + "field": "Statera Risk", "fixed": "text" }, "text": { @@ -1399,8 +1419,8 @@ "vertical": "top" }, "placement": { - "left": 166, - "top": 64, + "left": 168, + "top": 76, "width": 146, "height": 14 }, @@ -1415,7 +1435,7 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1435,8 +1455,8 @@ "vertical": "top" }, "placement": { - "left": 166, - "top": 78, + "left": 168, + "top": 90, "width": 146, "height": 42 }, @@ -1451,11 +1471,11 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 26, "color": { - "field": "Statera Runtime", + "field": "Statera Risk", "fixed": "text" }, "text": { @@ -1486,7 +1506,7 @@ "targetBlank": true } ], - "description": "Per-UPS live snapshot in a fixed 2x2 layout: Pyrphoros draw/runtime, Statera draw/runtime." + "description": "Per-UPS live snapshot in a centered 2x2 layout. Color turns yellow when discharging, orange below 3x graceful shutdown runtime, red below 2x." }, { "id": 41, @@ -1545,7 +1565,7 @@ { "id": 42, "type": "canvas", - "title": "Current Climate", + "title": "Current Enclosure Climate", "datasource": { "type": "prometheus", "uid": "atlas-vm" @@ -1660,7 +1680,7 @@ "infinitePan": false, "root": { "type": "frame", - "name": "Current Climate frame", + "name": "Current Enclosure Climate frame", "elements": [ { "type": "text", @@ -1670,8 +1690,8 @@ "vertical": "top" }, "placement": { - "left": 10, - "top": 6, + "left": 12, + "top": 18, "width": 146, "height": 14 }, @@ -1686,7 +1706,7 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1706,8 +1726,8 @@ "vertical": "top" }, "placement": { - "left": 10, - "top": 20, + "left": 12, + "top": 32, "width": 146, "height": 42 }, @@ -1722,7 +1742,7 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 30, "color": { @@ -1745,8 +1765,8 @@ "vertical": "top" }, "placement": { - "left": 166, - "top": 6, + "left": 168, + "top": 18, "width": 146, "height": 14 }, @@ -1761,7 +1781,7 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1781,8 +1801,8 @@ "vertical": "top" }, "placement": { - "left": 166, - "top": 20, + "left": 168, + "top": 32, "width": 146, "height": 42 }, @@ -1797,7 +1817,7 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 30, "color": { @@ -1820,8 +1840,8 @@ "vertical": "top" }, "placement": { - "left": 10, - "top": 64, + "left": 12, + "top": 76, "width": 146, "height": 14 }, @@ -1836,7 +1856,7 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1856,8 +1876,8 @@ "vertical": "top" }, "placement": { - "left": 10, - "top": 78, + "left": 12, + "top": 90, "width": 146, "height": 42 }, @@ -1872,7 +1892,7 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 30, "color": { @@ -1895,8 +1915,8 @@ "vertical": "top" }, "placement": { - "left": 166, - "top": 64, + "left": 168, + "top": 76, "width": 146, "height": 14 }, @@ -1911,7 +1931,7 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1931,8 +1951,8 @@ "vertical": "top" }, "placement": { - "left": 166, - "top": 78, + "left": 168, + "top": 90, "width": 146, "height": 42 }, @@ -1947,7 +1967,7 @@ } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 30, "color": { @@ -1987,7 +2007,7 @@ { "id": 43, "type": "timeseries", - "title": "Climate History", + "title": "Enclosure Climate History", "datasource": { "type": "prometheus", "uid": "atlas-vm" @@ -2016,32 +2036,32 @@ }, { "refId": "D", - "expr": "(min_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_temperature_celsius != 0)[$__range]) - 0.4)", + "expr": "(min_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_temperature_celsius != 0)[$__range]) - 0.08)", "legendFormat": "C bound min" }, { "refId": "E", - "expr": "(max_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_temperature_celsius != 0)[$__range]) + 0.4)", + "expr": "(max_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_temperature_celsius != 0)[$__range]) + 0.08)", "legendFormat": "C bound max" }, { "refId": "F", - "expr": "clamp_min((min_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_relative_humidity_percent != 0)[$__range]) - 2), 0)", + "expr": "clamp_min((min_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_relative_humidity_percent != 0)[$__range]) - 0.35), 0)", "legendFormat": "RH bound min" }, { "refId": "G", - "expr": "clamp_max((max_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_relative_humidity_percent != 0)[$__range]) + 2), 100)", + "expr": "clamp_max((max_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_relative_humidity_percent != 0)[$__range]) + 0.35), 100)", "legendFormat": "RH bound max" }, { "refId": "H", - "expr": "clamp_min((min_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_vpd_kpa != 0)[$__range]) - 0.15), 0)", + "expr": "clamp_min((min_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_vpd_kpa != 0)[$__range]) - 0.03), 0)", "legendFormat": "P bound min" }, { "refId": "I", - "expr": "(max_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_vpd_kpa != 0)[$__range]) + 0.15)", + "expr": "(max_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_vpd_kpa != 0)[$__range]) + 0.03)", "legendFormat": "P bound max" } ], diff --git a/services/monitoring/grafana-dashboard-overview.yaml b/services/monitoring/grafana-dashboard-overview.yaml index 319e8206..b6e59c80 100644 --- a/services/monitoring/grafana-dashboard-overview.yaml +++ b/services/monitoring/grafana-dashboard-overview.yaml @@ -1117,6 +1117,18 @@ data: "expr": "max(ananke_ups_runtime_seconds{job=\"ananke-power\",source=\"Statera\"}) or on() vector(0)", "legendFormat": "Statera Runtime", "instant": true + }, + { + "refId": "E", + "expr": "(((max(ananke_ups_on_battery{job=\"ananke-power\",source=\"Pyrphoros\"}) or on() vector(0)) > bool 0) * (1 + ((max(ananke_ups_runtime_seconds{job=\"ananke-power\",source=\"Pyrphoros\"}) or on() vector(0)) < bool (3 * (clamp_min(max(ananke_ups_threshold_seconds{job=\"ananke-power\",source=\"Pyrphoros\"}), 1)))) + ((max(ananke_ups_runtime_seconds{job=\"ananke-power\",source=\"Pyrphoros\"}) or on() vector(0)) < bool (2 * (clamp_min(max(ananke_ups_threshold_seconds{job=\"ananke-power\",source=\"Pyrphoros\"}), 1)))))) or on() vector(0)", + "legendFormat": "Pyrphoros Risk", + "instant": true + }, + { + "refId": "F", + "expr": "(((max(ananke_ups_on_battery{job=\"ananke-power\",source=\"Statera\"}) or on() vector(0)) > bool 0) * (1 + ((max(ananke_ups_runtime_seconds{job=\"ananke-power\",source=\"Statera\"}) or on() vector(0)) < bool (3 * (clamp_min(max(ananke_ups_threshold_seconds{job=\"ananke-power\",source=\"Statera\"}), 1)))) + ((max(ananke_ups_runtime_seconds{job=\"ananke-power\",source=\"Statera\"}) or on() vector(0)) < bool (2 * (clamp_min(max(ananke_ups_threshold_seconds{job=\"ananke-power\",source=\"Statera\"}), 1)))))) or on() vector(0)", + "legendFormat": "Statera Risk", + "instant": true } ], "fieldConfig": { @@ -1126,12 +1138,20 @@ data: "mode": "absolute", "steps": [ { - "color": "rgba(115, 115, 115, 1)", + "color": "green", "value": null }, { - "color": "green", + "color": "yellow", "value": 1 + }, + { + "color": "orange", + "value": 2 + }, + { + "color": "red", + "value": 3 } ] }, @@ -1183,8 +1203,8 @@ data: "vertical": "top" }, "placement": { - "left": 10, - "top": 6, + "left": 12, + "top": 18, "width": 146, "height": 14 }, @@ -1199,7 +1219,7 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1219,8 +1239,8 @@ data: "vertical": "top" }, "placement": { - "left": 10, - "top": 20, + "left": 12, + "top": 32, "width": 146, "height": 42 }, @@ -1235,11 +1255,11 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 26, "color": { - "field": "Pyrphoros Draw", + "field": "Pyrphoros Risk", "fixed": "text" }, "text": { @@ -1258,8 +1278,8 @@ data: "vertical": "top" }, "placement": { - "left": 166, - "top": 6, + "left": 168, + "top": 18, "width": 146, "height": 14 }, @@ -1274,7 +1294,7 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1294,8 +1314,8 @@ data: "vertical": "top" }, "placement": { - "left": 166, - "top": 20, + "left": 168, + "top": 32, "width": 146, "height": 42 }, @@ -1310,11 +1330,11 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 26, "color": { - "field": "Pyrphoros Runtime", + "field": "Pyrphoros Risk", "fixed": "text" }, "text": { @@ -1333,8 +1353,8 @@ data: "vertical": "top" }, "placement": { - "left": 10, - "top": 64, + "left": 12, + "top": 76, "width": 146, "height": 14 }, @@ -1349,7 +1369,7 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1369,8 +1389,8 @@ data: "vertical": "top" }, "placement": { - "left": 10, - "top": 78, + "left": 12, + "top": 90, "width": 146, "height": 42 }, @@ -1385,11 +1405,11 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 26, "color": { - "field": "Statera Draw", + "field": "Statera Risk", "fixed": "text" }, "text": { @@ -1408,8 +1428,8 @@ data: "vertical": "top" }, "placement": { - "left": 166, - "top": 64, + "left": 168, + "top": 76, "width": 146, "height": 14 }, @@ -1424,7 +1444,7 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1444,8 +1464,8 @@ data: "vertical": "top" }, "placement": { - "left": 166, - "top": 78, + "left": 168, + "top": 90, "width": 146, "height": 42 }, @@ -1460,11 +1480,11 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 26, "color": { - "field": "Statera Runtime", + "field": "Statera Risk", "fixed": "text" }, "text": { @@ -1495,7 +1515,7 @@ data: "targetBlank": true } ], - "description": "Per-UPS live snapshot in a fixed 2x2 layout: Pyrphoros draw/runtime, Statera draw/runtime." + "description": "Per-UPS live snapshot in a centered 2x2 layout. Color turns yellow when discharging, orange below 3x graceful shutdown runtime, red below 2x." }, { "id": 41, @@ -1554,7 +1574,7 @@ data: { "id": 42, "type": "canvas", - "title": "Current Climate", + "title": "Current Enclosure Climate", "datasource": { "type": "prometheus", "uid": "atlas-vm" @@ -1669,7 +1689,7 @@ data: "infinitePan": false, "root": { "type": "frame", - "name": "Current Climate frame", + "name": "Current Enclosure Climate frame", "elements": [ { "type": "text", @@ -1679,8 +1699,8 @@ data: "vertical": "top" }, "placement": { - "left": 10, - "top": 6, + "left": 12, + "top": 18, "width": 146, "height": 14 }, @@ -1695,7 +1715,7 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1715,8 +1735,8 @@ data: "vertical": "top" }, "placement": { - "left": 10, - "top": 20, + "left": 12, + "top": 32, "width": 146, "height": 42 }, @@ -1731,7 +1751,7 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 30, "color": { @@ -1754,8 +1774,8 @@ data: "vertical": "top" }, "placement": { - "left": 166, - "top": 6, + "left": 168, + "top": 18, "width": 146, "height": 14 }, @@ -1770,7 +1790,7 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1790,8 +1810,8 @@ data: "vertical": "top" }, "placement": { - "left": 166, - "top": 20, + "left": 168, + "top": 32, "width": 146, "height": 42 }, @@ -1806,7 +1826,7 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 30, "color": { @@ -1829,8 +1849,8 @@ data: "vertical": "top" }, "placement": { - "left": 10, - "top": 64, + "left": 12, + "top": 76, "width": 146, "height": 14 }, @@ -1845,7 +1865,7 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1865,8 +1885,8 @@ data: "vertical": "top" }, "placement": { - "left": 10, - "top": 78, + "left": 12, + "top": 90, "width": 146, "height": 42 }, @@ -1881,7 +1901,7 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 30, "color": { @@ -1904,8 +1924,8 @@ data: "vertical": "top" }, "placement": { - "left": 166, - "top": 64, + "left": 168, + "top": 76, "width": 146, "height": 14 }, @@ -1920,7 +1940,7 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 12, "color": { @@ -1940,8 +1960,8 @@ data: "vertical": "top" }, "placement": { - "left": 166, - "top": 78, + "left": 168, + "top": 90, "width": 146, "height": 42 }, @@ -1956,7 +1976,7 @@ data: } }, "config": { - "align": "left", + "align": "center", "valign": "middle", "size": 30, "color": { @@ -1996,7 +2016,7 @@ data: { "id": 43, "type": "timeseries", - "title": "Climate History", + "title": "Enclosure Climate History", "datasource": { "type": "prometheus", "uid": "atlas-vm" @@ -2025,32 +2045,32 @@ data: }, { "refId": "D", - "expr": "(min_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_temperature_celsius != 0)[$__range]) - 0.4)", + "expr": "(min_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_temperature_celsius != 0)[$__range]) - 0.08)", "legendFormat": "C bound min" }, { "refId": "E", - "expr": "(max_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_temperature_celsius != 0)[$__range]) + 0.4)", + "expr": "(max_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_temperature_celsius != 0)[$__range]) + 0.08)", "legendFormat": "C bound max" }, { "refId": "F", - "expr": "clamp_min((min_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_relative_humidity_percent != 0)[$__range]) - 2), 0)", + "expr": "clamp_min((min_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_relative_humidity_percent != 0)[$__range]) - 0.35), 0)", "legendFormat": "RH bound min" }, { "refId": "G", - "expr": "clamp_max((max_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_relative_humidity_percent != 0)[$__range]) + 2), 100)", + "expr": "clamp_max((max_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_relative_humidity_percent != 0)[$__range]) + 0.35), 100)", "legendFormat": "RH bound max" }, { "refId": "H", - "expr": "clamp_min((min_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_vpd_kpa != 0)[$__range]) - 0.15), 0)", + "expr": "clamp_min((min_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_vpd_kpa != 0)[$__range]) - 0.03), 0)", "legendFormat": "P bound min" }, { "refId": "I", - "expr": "(max_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_vpd_kpa != 0)[$__range]) + 0.15)", + "expr": "(max_over_time(max without (job,instance,pod,service,endpoint,namespace) (typhon_vpd_kpa != 0)[$__range]) + 0.03)", "legendFormat": "P bound max" } ],