Fix temperature parsing to handle multiple SMART formats
Temperature parsing now correctly handles: - SATA Temperature_Celsius attribute (extracts last numeric value) - Simple "Temperature: XX Celsius" format - "Current Temperature: XX Celsius" format - NVMe temperature reporting Also improved device type detection for NVMe, SSD (including 0 RPM), and fixed serial number parsing to capture full serial with spaces. Fixes: #2 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -272,16 +272,84 @@ build_drive_map() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
# get_drive_smart_info
|
||||||
|
#
|
||||||
|
# Retrieves SMART data for a given device.
|
||||||
|
#
|
||||||
|
# Args:
|
||||||
|
# $1 - Device name (e.g., sda, nvme0n1)
|
||||||
|
#
|
||||||
|
# Returns: Pipe-delimited string: TYPE|TEMP|HEALTH|MODEL|SERIAL
|
||||||
|
# TYPE: SSD, HDD, or NVMe
|
||||||
|
# TEMP: Temperature in Celsius (or "-" if unavailable)
|
||||||
|
# HEALTH: ✓ for passed, ✗ for failed
|
||||||
|
# MODEL: Drive model string
|
||||||
|
# SERIAL: Drive serial number
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
get_drive_smart_info() {
|
get_drive_smart_info() {
|
||||||
local device=$1
|
local device="$1"
|
||||||
local smart_info=$(sudo smartctl -A -i -H /dev/$device 2>/dev/null)
|
local smart_info
|
||||||
local temp=$(echo "$smart_info" | grep "Temperature" | awk '{print $10}' | head -1)
|
local temp="-"
|
||||||
local type=$(echo "$smart_info" | grep "Rotation Rate" | grep -q "Solid State" && echo "SSD" || echo "HDD")
|
local type="HDD"
|
||||||
local health=$(echo "$smart_info" | grep "SMART overall-health" | grep -q "PASSED" && echo "✓" || echo "✗")
|
local health="✗"
|
||||||
local model=$(echo "$smart_info" | grep "Device Model\|Model Number" | cut -d: -f2 | xargs)
|
local model="-"
|
||||||
local serial=$(echo "$smart_info" | grep "Serial Number" | awk '{print $3}')
|
local serial="-"
|
||||||
|
|
||||||
echo "$type|$temp°C|$health|$model|$serial"
|
smart_info="$(sudo smartctl -A -i -H "/dev/$device" 2>/dev/null)"
|
||||||
|
|
||||||
|
# Temperature parsing - handles multiple formats:
|
||||||
|
# - SATA: "194 Temperature_Celsius ... 35" (value at end of line)
|
||||||
|
# - SATA: "Temperature: 42 Celsius"
|
||||||
|
# - SATA: "Current Temperature: 35 Celsius"
|
||||||
|
# - NVMe: "Temperature: 42 Celsius"
|
||||||
|
if echo "$smart_info" | grep -q "Temperature_Celsius"; then
|
||||||
|
# SMART attribute format - temperature is typically the 10th field (raw value)
|
||||||
|
# But we use the last numeric field before any parentheses for reliability
|
||||||
|
temp="$(echo "$smart_info" | grep "Temperature_Celsius" | head -1 | awk '{for(i=NF;i>0;i--) if($i ~ /^[0-9]+$/) {print $i; exit}}')"
|
||||||
|
elif echo "$smart_info" | grep -qE "^(Current )?Temperature:"; then
|
||||||
|
# Simple "Temperature: XX Celsius" format
|
||||||
|
temp="$(echo "$smart_info" | grep -E "^(Current )?Temperature:" | head -1 | awk '{print $2}')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Device type detection - handles SSD, HDD, and NVMe
|
||||||
|
if [[ "$device" == nvme* ]]; then
|
||||||
|
type="NVMe"
|
||||||
|
elif echo "$smart_info" | grep -q "Rotation Rate"; then
|
||||||
|
if echo "$smart_info" | grep "Rotation Rate" | grep -qiE "solid state|0 rpm"; then
|
||||||
|
type="SSD"
|
||||||
|
else
|
||||||
|
type="HDD"
|
||||||
|
fi
|
||||||
|
elif echo "$smart_info" | grep -qiE "SSD|Solid State"; then
|
||||||
|
type="SSD"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Health status
|
||||||
|
if echo "$smart_info" | grep -q "SMART overall-health.*PASSED"; then
|
||||||
|
health="✓"
|
||||||
|
elif echo "$smart_info" | grep -q "SMART Health Status.*OK"; then
|
||||||
|
# NVMe format
|
||||||
|
health="✓"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Model - try multiple field names
|
||||||
|
model="$(echo "$smart_info" | grep -E "^(Device Model|Model Number|Product):" | head -1 | cut -d: -f2 | xargs)"
|
||||||
|
[[ -z "$model" ]] && model="-"
|
||||||
|
|
||||||
|
# Serial number - capture everything after the colon to handle spaces
|
||||||
|
serial="$(echo "$smart_info" | grep -E "^Serial [Nn]umber:" | head -1 | cut -d: -f2 | xargs)"
|
||||||
|
[[ -z "$serial" ]] && serial="-"
|
||||||
|
|
||||||
|
# Format temperature with unit if we have a value
|
||||||
|
local temp_display
|
||||||
|
if [[ -n "$temp" && "$temp" != "-" ]]; then
|
||||||
|
temp_display="${temp}°C"
|
||||||
|
else
|
||||||
|
temp_display="-"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${type}|${temp_display}|${health}|${model}|${serial}"
|
||||||
}
|
}
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user