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"):
|
if not SMART_ENABLED or not shutil.which("smartctl"):
|
||||||
return "Nicht verfügbar"
|
return "Nicht verfügbar"
|
||||||
smart_device = device.replace("/dev/", f"{HOST_DEVICE_PATH.rstrip('/')}/", 1)
|
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)
|
def extract(output):
|
||||||
if not output:
|
for line in output.splitlines():
|
||||||
output, error = _read_command(["smartctl", "-A", "-d", "sat", smart_device], timeout=6, warn_on_nonzero=False)
|
if not re.search(r"temperature|airflow", line, re.IGNORECASE):
|
||||||
patterns = (
|
continue
|
||||||
r"(?:Temperature_Celsius|Airflow_Temperature_Cel|Drive_Temperature|Current Drive Temperature)\s+.*?\s(\d{1,3})(?:\s*°?C)?\s*$",
|
explicit = re.search(r"(\d{1,3})\s*(?:°\s*C|Celsius|degrees?\s*C)\b", line, re.IGNORECASE)
|
||||||
r"^\s*Temperature:\s*(\d{1,3})\s*(?:C|°C|Celsius)?\s*$",
|
if explicit and 0 < int(explicit.group(1)) < 150:
|
||||||
)
|
return f"{int(explicit.group(1))} °C"
|
||||||
for pattern in patterns:
|
numbers = [int(value) for value in re.findall(r"\b\d{1,3}\b", line)]
|
||||||
match = re.search(pattern, output, re.IGNORECASE | re.MULTILINE)
|
plausible = [value for value in numbers if 0 < value < 150]
|
||||||
if match:
|
if plausible:
|
||||||
return f"{int(match.group(1))} °C"
|
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"
|
return "Nicht verfügbar"
|
||||||
|
|
||||||
def raid_status():
|
def raid_status():
|
||||||
|
|||||||
Reference in New Issue
Block a user