From 514502e045071e080da95ebf205dac641b246352 Mon Sep 17 00:00:00 2001 From: adam Date: Tue, 16 Jun 2026 19:05:10 +0000 Subject: [PATCH] host_sensors: filter IPMI margin sensors; coretemp per-core CPU fallback - skip IPMI '*Margin' sensors (thermal margin / distance-to-throttle reads in degrees C but is not an absolute temperature, e.g. robin's P1 Therm Margin) - coretemp: when a CPU has no 'Package id' sensor (older Xeons like robin's X3430), fall back to the hottest Core as the CPU temp --- services/host_sensors.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/services/host_sensors.py b/services/host_sensors.py index 9bdc191..4736f57 100644 --- a/services/host_sensors.py +++ b/services/host_sensors.py @@ -45,6 +45,10 @@ def _parse_ipmi(text: str) -> list[dict]: if len(parts) < 5: continue name, _sid, status, entity, reading = parts[:5] + # Skip relative/derived sensors (e.g. "P1 Therm Margin") — they read in + # "degrees C" but are a distance-to-throttle, not an absolute temp. + if "margin" in name.lower(): + continue m = re.search(r"(-?\d+(?:\.\d+)?)\s*degrees?\s*C", reading, re.IGNORECASE) if not m: # "no reading", "disabled", "ns", etc. continue @@ -74,22 +78,28 @@ def read_coretemp() -> list[dict]: continue except OSError: continue + packages: list[dict] = [] + cores: list[int] = [] for label_f in sorted(hw.glob("temp*_label")): try: label = label_f.read_text().strip() except OSError: continue - if not label.lower().startswith("package id"): - continue input_f = label_f.with_name(label_f.name.replace("_label", "_input")) try: - milli = int(input_f.read_text().strip()) + temp = round(int(input_f.read_text().strip()) / 1000) except (OSError, ValueError): continue - pkg = label.split("id")[-1].strip() - cpus.append({ - "name": f"CPU {pkg}", - "temperature_c": round(milli / 1000), - "kind": "cpu", - }) + low = label.lower() + if low.startswith("package id"): + pkg = label.split("id")[-1].strip() + packages.append({"name": f"CPU {pkg}", "temperature_c": temp, "kind": "cpu"}) + elif low.startswith("core"): + cores.append(temp) + # Prefer the per-package sensor; older CPUs (no package sensor) fall back + # to the hottest core as the CPU temp. + if packages: + cpus.extend(packages) + elif cores: + cpus.append({"name": "CPU", "temperature_c": max(cores), "kind": "cpu"}) return cpus