Enhance SMART report information

This commit is contained in:
Yan Lin 2025-09-14 14:00:06 +02:00
parent fd8a537a18
commit 4a21632801
3 changed files with 100 additions and 11 deletions

View file

@ -9,7 +9,7 @@
# hs-specific home configuration
programs.zsh.shellAliases = {
# Disk health monitoring
smart-report = "sudo SMART_DRIVES='/dev/disk/by-id/ata-ZHITAI_SC001_XT_1000GB_ZTB401TAB244431J4R:ZFS Mirror 1;/dev/disk/by-id/ata-ZHITAI_SC001_XT_1000GB_ZTB401TAB244431KEG:ZFS Mirror 2;/dev/disk/by-id/ata-HGST_HUH721212ALE604_5PK2N4GB:Data Drive 1 (12TB);/dev/disk/by-id/ata-HGST_HUH721212ALE604_5PJ7Z3LE:Data Drive 2 (12TB);/dev/disk/by-id/ata-ST16000NM000J-2TW103_WRS0F8BE:Parity Drive (16TB)' /home/yanlin/.config/nix/scripts/daily-smart-report.sh Ac9qKFH5cA.7Yly";
smart-report = "sudo SMART_DRIVES='/dev/disk/by-id/ata-ZHITAI_SC001_XT_1000GB_ZTB401TAB244431J4R:ZFS_Mirror_1;/dev/disk/by-id/ata-ZHITAI_SC001_XT_1000GB_ZTB401TAB244431KEG:ZFS_Mirror_2;/dev/disk/by-id/ata-HGST_HUH721212ALE604_5PK2N4GB:Data_Drive_1_12TB;/dev/disk/by-id/ata-HGST_HUH721212ALE604_5PJ7Z3LE:Data_Drive_2_12TB;/dev/disk/by-id/ata-ST16000NM000J-2TW103_WRS0F8BE:Parity_Drive_16TB' /home/yanlin/.config/nix/scripts/daily-smart-report.sh Ac9qKFH5cA.7Yly";
move-inbox = "cp -rl /mnt/storage/Media/downloads/.inbox/* /mnt/storage/Media/downloads/inbox && chown -R yanlin:users /mnt/storage/Media/downloads/inbox";
};

View file

@ -33,7 +33,7 @@
programs.zsh.shellAliases = {
# Disk health monitoring
smart-report = "sudo SMART_DRIVES='/dev/nvme0n1:System SSD (ThinkPad)' /home/yanlin/.config/nix/scripts/daily-smart-report.sh AieM4SJHFcyl7TC";
smart-report = "sudo SMART_DRIVES='/dev/nvme0n1:System_SSD_ThinkPad' /home/yanlin/.config/nix/scripts/daily-smart-report.sh AieM4SJHFcyl7TC";
};
home.packages = with pkgs; [

View file

@ -64,6 +64,14 @@ main() {
continue
fi
# Detect drive type
local drive_type="UNKNOWN"
if [[ "$device" == *"nvme"* ]]; then
drive_type="NVMe"
elif smartctl -i "$device" 2>/dev/null | grep -q "SATA\|ATA"; then
drive_type="SATA"
fi
# Get SMART health
local health="UNKNOWN"
if health=$(smartctl -H "$device" 2>/dev/null | grep -o "PASSED\|FAILED" | head -1); then
@ -73,29 +81,110 @@ main() {
echo " Health: $health"
fi
# Get temperature
# Get enhanced SMART data
local temp="N/A"
local power_hours="N/A"
local wear_info="N/A"
local data_info=""
local error_info=""
if [[ "$health" == "PASSED" ]]; then
if temp=$(smartctl -A "$device" 2>/dev/null | awk '/Temperature_Celsius/ {print $10}' | head -1); then
if [[ "$temp" -gt 0 ]] 2>/dev/null; then
local smart_data
smart_data=$(smartctl -A "$device" 2>/dev/null)
if [[ "$drive_type" == "NVMe" ]]; then
# NVMe specific attributes
temp=$(echo "$smart_data" | awk '/^Temperature:/ {print $2}' | head -1)
if [[ -n "$temp" && "$temp" =~ ^[0-9]+$ ]]; then
temp="${temp}C"
echo " Temperature: $temp"
else
temp="N/A"
echo " Temperature: $temp"
fi
power_hours=$(echo "$smart_data" | awk '/^Power On Hours:/ {print $4}' | sed 's/,//g')
local percentage_used
percentage_used=$(echo "$smart_data" | awk '/^Percentage Used:/ {print $3}' | tr -d '%')
if [[ -n "$percentage_used" ]]; then
wear_info="Wear: ${percentage_used}%"
fi
local data_read data_written
data_read=$(echo "$smart_data" | awk '/^Data Units Read:/ {match($0, /\[([^\]]+)\]/, arr); print arr[1]}')
data_written=$(echo "$smart_data" | awk '/^Data Units Written:/ {match($0, /\[([^\]]+)\]/, arr); print arr[1]}')
if [[ -n "$data_read" && -n "$data_written" ]]; then
data_info="Data: R:${data_read} W:${data_written}"
fi
local unsafe_shutdowns media_errors
unsafe_shutdowns=$(echo "$smart_data" | awk '/^Unsafe Shutdowns:/ {print $3}')
media_errors=$(echo "$smart_data" | awk '/^Media and Data Integrity Errors:/ {print $6}')
local error_parts=()
if [[ -n "$unsafe_shutdowns" && "$unsafe_shutdowns" -gt 0 ]]; then
error_parts+=("UnsafeShutdowns:$unsafe_shutdowns")
fi
if [[ -n "$media_errors" && "$media_errors" -gt 0 ]]; then
error_parts+=("MediaErrors:$media_errors")
fi
if [[ ${#error_parts[@]} -gt 0 ]]; then
error_info=$(IFS=' '; echo "${error_parts[*]}")
fi
else
# SATA/SAS specific attributes
temp=$(echo "$smart_data" | awk '/Temperature_Celsius/ {print $10}' | head -1)
if [[ -n "$temp" && "$temp" =~ ^[0-9]+$ ]]; then
temp="${temp}C"
else
temp="N/A"
echo " Temperature: $temp"
fi
power_hours=$(echo "$smart_data" | awk '/Power_On_Hours/ {print $10}' | head -1)
local reallocated
reallocated=$(echo "$smart_data" | awk '/Reallocated_Sector_Ct/ {print $10}' | head -1)
if [[ -n "$reallocated" ]]; then
wear_info="Reallocated:$reallocated"
fi
local power_cycles
power_cycles=$(echo "$smart_data" | awk '/Power_Cycle_Count/ {print $10}' | head -1)
if [[ -n "$power_cycles" ]]; then
data_info="PowerCycles:$power_cycles"
fi
fi
echo " Temperature: $temp"
echo " Power Hours: $power_hours"
[[ -n "$wear_info" ]] && echo " $wear_info"
[[ -n "$data_info" ]] && echo " $data_info"
[[ -n "$error_info" ]] && echo " $error_info"
fi
# Format output
if [[ "$health" == "PASSED" ]]; then
report+="[OK] $device_name: $health (Temp: $temp)\n"
report+="[OK] $device_name ($drive_type): $health\\n"
report+=" Temp: $temp"
if [[ "$power_hours" != "N/A" ]]; then
report+=", PowerOn: ${power_hours}h"
fi
if [[ -n "$wear_info" ]]; then
report+=", $wear_info"
fi
report+="\\n"
if [[ -n "$data_info" ]]; then
report+=" $data_info\\n"
fi
if [[ -n "$error_info" ]]; then
report+=" ⚠️ $error_info\\n"
fi
healthy_drives=$((healthy_drives + 1))
else
report+="[FAIL] $device_name: $health (Temp: $temp)\n"
report+="[FAIL] $device_name ($drive_type): $health\\n"
if [[ "$temp" != "N/A" ]]; then
report+=" Temp: $temp\\n"
fi
fi
done