From 9373e93e7f6341cb4c795f2233c80b71a347bea6 Mon Sep 17 00:00:00 2001 From: nessi Date: Sun, 16 Aug 2026 20:08:29 +0200 Subject: [PATCH] feat: improve SMART temperature parsing with multi-command fallback and enhanced line-based extraction logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace regex pattern matching with extract() helper that iterates through output lines, filters for temperature/airflow keywords, and extracts values using explicit unit patterns (°C/Celsius/degrees C) with 0-150 range validation or fallback to last plausible number in line. Add smartctl -x/-x -d sat commands to fallback chain after -A/-A -d sat attempts with early return on first successful --- app.py | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/app.py b/app.py index d42b759..06fc876 100644 --- a/app.py +++ b/app.py @@ -357,17 +357,29 @@ def smart_temperature(device): if not SMART_ENABLED or not shutil.which("smartctl"): return "Nicht verfügbar" smart_device = device.replace("/dev/", f"{HOST_DEVICE_PATH.rstrip('/')}/", 1) - output, error = _read_command(["smartctl", "-A", smart_device], timeout=6, warn_on_nonzero=False) - if not output: - output, error = _read_command(["smartctl", "-A", "-d", "sat", smart_device], timeout=6, warn_on_nonzero=False) - patterns = ( - r"(?:Temperature_Celsius|Airflow_Temperature_Cel|Drive_Temperature|Current Drive Temperature)\s+.*?\s(\d{1,3})(?:\s*°?C)?\s*$", - r"^\s*Temperature:\s*(\d{1,3})\s*(?:C|°C|Celsius)?\s*$", - ) - for pattern in patterns: - match = re.search(pattern, output, re.IGNORECASE | re.MULTILINE) - if match: - return f"{int(match.group(1))} °C" + def extract(output): + for line in output.splitlines(): + if not re.search(r"temperature|airflow", line, re.IGNORECASE): + continue + explicit = re.search(r"(\d{1,3})\s*(?:°\s*C|Celsius|degrees?\s*C)\b", line, re.IGNORECASE) + if explicit and 0 < int(explicit.group(1)) < 150: + return f"{int(explicit.group(1))} °C" + numbers = [int(value) for value in re.findall(r"\b\d{1,3}\b", line)] + plausible = [value for value in numbers if 0 < value < 150] + if plausible: + return f"{plausible[-1]} °C" + return None + + for command in ( + ["smartctl", "-A", smart_device], + ["smartctl", "-A", "-d", "sat", smart_device], + ["smartctl", "-x", smart_device], + ["smartctl", "-x", "-d", "sat", smart_device], + ): + output, _ = _read_command(command, timeout=6, warn_on_nonzero=False) + temperature = extract(output) + if temperature: + return temperature return "Nicht verfügbar" def raid_status():