From 00413326be1d7489a91ed26231d4290a5e6acf8b Mon Sep 17 00:00:00 2001 From: Tim Connors Date: Sat, 13 Sep 2025 04:02:33 +1000 Subject: [PATCH] hddtemp, smart-intercept-spindown: handle idle, add --numeric, --no-device Filter out temperature=255 at this stage rather than in clients who use us Allow hddtemp to output a simpler format if --no-device --numeric is requested Ignore idle disks as well in order not to bring them out of idle mode and thus reset timer --- hddtemp | 58 +++++++++++++++++++++++++++++++++------- smart-intercept-spindown | 4 +-- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/hddtemp b/hddtemp index 609c972..ad58d82 100755 --- a/hddtemp +++ b/hddtemp @@ -20,30 +20,70 @@ use warnings; $ENV{PATH}="$ENV{PATH}:/usr/sbin:/sbin"; +sub usage { + print STDERR "@_\n" if @_; + print STDERR "Usage: hddtemp [-n|--numeric] [--no-device] \n"; + exit 1; +} + +# FIXME: consider using megaclisas-status if it's available, although +# finding the mapping might be interesting... + +my $units="°C"; +my $print_device=1; +while (@ARGV and $ARGV[0] =~ /^-/) { + if ($ARGV[0] eq "--numeric" or $ARGV[0] eq "-n") { + shift @ARGV; + $units=""; + } elsif ($ARGV[0] eq "--no-device") { + shift @ARGV; + $print_device=0; + } else { + usage; + } +} + +usage "Supply device name(s)" if (!@ARGV); + my $last_exit=0; foreach my $drive (@ARGV) { my $output=`/usr/local/bin/smart-intercept-spindown -A -i $drive`; $last_exit = $?>>8; - if (!($output =~ /Standby condition/)) { - my $model=""; + if (!($output =~ /(Standby|Idle) condition/)) { + my $model = ""; + my $temp = ""; if ($output =~ /(Model Number|Device Model):\s*(.*)/) { - $model="$2: "; + $model = "$2: "; } + if ($output =~ /Current Drive Temperature:\s*(\d+)/) { - print "$drive: $model$1°C\n"; + $temp = $1; } elsif ($output =~ /^(194 Temperature_(Celsius|Internal).*)/m) { my @F = split /\s+/, $1; - print "$drive: $model$F[9]°C\n"; + $temp = $F[9]; } elsif ($output =~ /^(231 Temperature_Celsius.*)/m) { my @F = split ' ', $1; - print "$drive: $model$F[9]°C\n"; + $temp = $F[9]; } elsif ($output =~ /^(190 (Airflow_Temperature_Cel|Temperature_Case).*)/m) { my @F = split ' ', $1; - print "$drive: $model$F[9]°C\n"; + $temp = $F[9]; } elsif ($output =~ /Temperature:\s*(\d+) Celsius/) { - print "$drive: $model$1°C\n"; + $temp = $1; } else { - print "$drive: Smart not available\n"; + print "$drive: SMART not available\n"; + next; + } + + # Some devices permanently return a *temperature* of 255, so + # ignore them too + if ($temp == 255) { + print "$drive: ${model}Temperature not available through SMART\n"; + } else { + if ($print_device) { + print "$drive: $model$temp$units\n"; + } else { + print "$temp$units\n"; + } } } else { print "$drive: Sleeping. Temperature not available\n"; diff --git a/smart-intercept-spindown b/smart-intercept-spindown index 29fd1e3..0dfb6fb 100755 --- a/smart-intercept-spindown +++ b/smart-intercept-spindown @@ -98,14 +98,14 @@ if [ "1" = --version ] ; then exec smartctl "$@" fi -if sdparm --command=sense "$final_arg" 2>/dev/null | grep Standby; then +if sdparm --command=sense "$final_arg" 2>/dev/null | grep -e "Standby condition" -e "Idle condition" ; then # exit code success rather than code 2 like smartctl by default # Could do similar output with hdparm -C, but smartctl # --nocheck=standby,0 correctly detects that exit fi -smart_output=$( smartctl --nocheck=standby,0 "$@" ) +smart_output=$( smartctl --nocheck=idle,0 "$@" ) exit_code=$? case "$smart_output" in