metrics: suppress stale climate when controller offline

This commit is contained in:
Brad Stein 2026-04-13 03:33:52 -03:00
parent c3a92a88e1
commit 990045f157
2 changed files with 51 additions and 1 deletions

View File

@ -231,6 +231,11 @@ export class TyphonMetrics {
new_framework_device:
controller.newFrameworkDevice === null ? "unknown" : String(controller.newFrameworkDevice)
}).set(1);
// AC Infinity returns stale snapshots while controllers are offline.
// Keep online/info visibility, but suppress climate/fan gauges until controller is online again.
if (!controller.online) {
continue;
}
this.temperatureCelsius.labels(controllerLabels).set(controller.temperatureCelsius);
this.relativeHumidityRatio.labels(controllerLabels).set(controller.relativeHumidityRatio);
this.relativeHumidityPercent.labels(controllerLabels).set(controller.relativeHumidityRatio * 100);

View File

@ -76,7 +76,7 @@ describe("TyphonMetrics", () => {
const metrics = new TyphonMetrics("0.1.0", false, registry);
const snapshot = new ClimateSnapshot(1_700_000_050, [
new ControllerClimate("c2", "Tent B", false, 22.2, 0.40, 0.8, null, null, [
new ControllerClimate("c2", "Tent B", true, 22.2, 0.40, 0.8, null, null, [
new PortClimate(2, "Fan B", "outlet", false, false, 0, 3, 0, true, null, AcInfinityMode.Unknown)
])
]);
@ -110,6 +110,51 @@ describe("TyphonMetrics", () => {
})).toBe(1);
});
it("suppresses stale climate and fan gauges when controller is offline", async () => {
const registry = new Registry();
const metrics = new TyphonMetrics("0.1.0", false, registry);
const snapshot = new ClimateSnapshot(1_700_000_060, [
new ControllerClimate("c3", "Tent C", false, 23.1, 0.42, 1.1, 11, false, [
new PortClimate(3, "Fan C", "interior", true, true, 7, 8, 2, true, 1500, AcInfinityMode.Auto)
])
]);
metrics.updateFromSnapshot(snapshot);
const json = await registry.getMetricsAsJSON();
expect(valueForMetric(json, "typhon_controller_online", {
controller_id: "c3",
controller_name: "Tent C"
})).toBe(0);
expect(valueForMetric(json, "typhon_controller_info", {
controller_id: "c3",
controller_name: "Tent C",
device_type: "11",
new_framework_device: "false"
})).toBe(1);
expect(valueForMetric(json, "typhon_temperature_celsius", {
controller_id: "c3",
controller_name: "Tent C"
})).toBeNull();
expect(valueForMetric(json, "typhon_relative_humidity_percent", {
controller_id: "c3",
controller_name: "Tent C"
})).toBeNull();
expect(valueForMetric(json, "typhon_vpd_kpa", {
controller_id: "c3",
controller_name: "Tent C"
})).toBeNull();
expect(valueForMetric(json, "typhon_fan_speed_level", {
controller_id: "c3",
controller_name: "Tent C",
port: "3",
port_name: "Fan C",
fan_group: "interior"
})).toBeNull();
});
it("tracks polling failures", async () => {
const registry = new Registry();
const metrics = new TyphonMetrics("0.1.0", false, registry);