feat: improve SMART temperature parsing with multi-command fallback and enhanced line-based extraction logic
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
This commit is contained in:
@@ -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():
|
||||
|
||||
Reference in New Issue
Block a user