Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
control your fan rpm speed by your hdd temperature
#!/bin/bash
emergency=0
if data=$(hddtemp --numeric --unit=C /dev/sdb) \
&& [ "$data" -eq "$data" -a "$data" -gt 1 -a "$data" -le 70 ] 2>/dev/null
then if [ "$data" -gt 40 ] ; then
echo -e "$(date '+%Y-%m-%d %H:%M:%S')\tNOTICE\temergency temp hdd:$data" | tee -a "/var/log/moli/fancontrol.log" 1>&2
emergency=1
fi
else echo -e "$(date '+%Y-%m-%d %H:%M:%S')\tERROR\temergency value:$data @hddtemp/sdb" | tee -a "/var/log/moli/fancontrol.log" 1>&2 ; fi
path=/sys/devices/platform/coretemp.0/hwmon/hwmon0/temp3_input
if input=$(cat $path) \
&& [ "$input" -eq "$input" ] 2>/dev/null \
&& data=$(echo "$input / 1000" | bc) \
&& [ "$data" -gt 1 -a "$data" -le 92 ]
then if [ "$data" -ge 82 ] ; then
echo -e "$(date '+%Y-%m-%d %H:%M:%S')\tNOTICE\temergency temp cpu:$data" | tee -a "/var/log/moli/fancontrol.log" 1>&2
emergency=1
fi
else echo -e "$(date '+%Y-%m-%d %H:%M:%S')\tERROR\temergency value:$input @$path" | tee -a "/var/log/moli/fancontrol.log" 1>&2 ; fi
path=/sys/devices/platform/coretemp.0/hwmon/hwmon0/temp2_input
if input=$(cat $path) \
&& [ "$input" -eq "$input" ] 2>/dev/null \
&& data=$(echo "$input / 1000 + 7" | bc) \
&& [ "$data" -gt 1 -a "$data" -le 99 ]
then if [ "$data" -ge 82 ] ; then
echo -e "$(date '+%Y-%m-%d %H:%M:%S')\tNOTICE\temergency temp cpu2:$data" | tee -a "/var/log/moli/fancontrol.log" 1>&2
emergency=1
fi
else echo -e "$(date '+%Y-%m-%d %H:%M:%S')\tERROR\temergency value:$input @$path" | tee -a "/var/log/moli/fancontrol.log" 1>&2 ; fi
path=/sys/class/hwmon/hwmon2/device/temp2_input
if input=$(cat $path) \
&& [ "$input" -eq "$input" ] 2>/dev/null \
&& data=$(echo "$input / 1000 + 13" | bc) \
&& [ "$data" -gt 1 -a "$data" -le 95 ]
then if [ "$data" -ge 82 ] ; then
echo -e "$(date '+%Y-%m-%d %H:%M:%S')\tNOTICE\temergency temp mobo-cpu:$data" | tee -a "/var/log/moli/fancontrol.log" 1>&2
emergency=1
fi
else echo -e "$(date '+%Y-%m-%d %H:%M:%S')\tERROR\temergency value:$input @$path" | tee -a "/var/log/moli/fancontrol.log" 1>&2 ; fi
if [ $emergency -gt 0 ] ; then
echo 255 > /sys/devices/platform/smsc47m1.1664/pwm1
fi
exit $emergency
#!/bin/bash
# uncomment this to log every intervals even if no changes made in pwm value
#debug=true
# set this to the desired temperature you want to keep your hdd at
targettemp=39 # http://static.googleusercontent.com/media/research.google.com/en//archive/disk_failures.pdf
# or set these for a temperature interval: min temp=min pwm, max temp=max pwm
# not used when targettemp is set
#mintemp=30
#maxtemp=55
# set the array containing the list of valid pwm values of your fan. the reason of using an array instead of a min-max value is: please note that in the first example the value 144 is missing as that fan was chirping at that rpm.
#pwms=( 128 160 176 192 208 224 240 ) #w83627hf.656
#pwms=( 0 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120 124 128 132 136 140 144 148 152 156 160 164 168 172 176 180 184 188 192 196 200 204 208 212 216 220 224 228 232 236 240 244 248 252 ) #smsc47m1.1664 & Konig CMP-FAN22
#pwms=( 0 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120 124 128 132 136 140 144 148 152 156 160 164 168 172 176 180 184 188 192 196 200 204 208 212 216 220 224 228 232 236 240 244 248 252 ) #smsc47m1.1664 & JF0625H1HM-R
pwms=( 0 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80 84 88 92 96 100 104 108 112 116 120 124 128 132 136 140 144 148 152 156 160 164 168 172 176 180 184 188 192 196 200 204 208 212 216 220 224 228 232 236 240 244 248 252 ) #smsc47m1.1664 & Coolink X8-1900
# the running (measuring & calculating & modifing pwm) interval in seconds
interval=5
# this is the number of intervals between changing the pwm to a lower value (so not a higher value). the reason is: a fan rpm set in every minute with it's changing noise is disturbing. 15 means 15 times $interval seconds.
# not used when targettemp is set
delay=15
# path of pwm device
#pwmdev=/sys/devices/platform/w83627hf.656/pwm1
pwmdev=/sys/devices/platform/smsc47m1.1664/pwm1
# string of command to get current temperature. again, it's a string of what to run, not running the command itself.
tempcmd='hddtemp --numeric --unit=C /dev/sdb'
# path to logfile
logfile=/var/log/moli/fancontrol.log
# timeout in seconds to wait between terminating previous running copies of this script
killtimeout=15
# path to pidfile, only used as fallback as this method is unreliable
pidfile=/var/run/fancontrol.pid
if [ $EUID -ne 0 ] ; then echo 'ERROR you are not root' >&2 ; exit 2 ; fi
pwmslen=${#pwms[*]}
if [ $pwmslen -lt 3 ] ; then echo 'ERROR there should be at least 3 values in the pwms array' >&2 ; exit 2 ; fi
if [ $mintemp ] && [ $maxtemp ] && [ $((maxtemp-mintemp)) -lt 3 ] ; then echo 'ERROR maxtemp and mintemp difference must be at least 3' >&2 ; exit 2 ; fi
func_term () {
rm -f "$pidfile"
echo -e "$(date +"%Y-%m-%d %H:%M:%S")\\tFATAL\\t$$ got killed" >> "$logfile"
exit $1
}
trap 'func_term 0' SIGQUIT SIGTERM
trap 'func_term 1' SIGHUP SIGINT
func_kill () {
local i=0
kill -sigterm $pid 2>/dev/null
while [ -e /proc/$pid -a $i -lt $killtimeout ] ; do
sleep 1
i=$((i+1))
done
if [ $i -eq $killtimeout ] ; then
echo -e "$(date +"%Y-%m-%d %H:%M:%S")\\tFATAL\\t$$ could not kill pid $pid" >> "$logfile"
echo "ERROR could not kill pid $pid" >&2
exit 2
fi
echo -e "$(date +"%Y-%m-%d %H:%M:%S")\\tNOTICE\\t$$ killed pid $pid" >> "$logfile"
sleep $killtimeout
}
for pid in $(pgrep fancontrol.sh | grep -v $$) ; do
func_kill
done
if [ -f "$pidfile" ] ; then pid=$(cat "$pidfile") ; if [ "$pid" -eq "$pid" -a -e "/proc/$pid" ] ; then if [ "$(cat /proc/$pid/comm)" = 'fancontrol.sh' ] ; then func_kill ; fi ; fi ; fi ; echo $$ > "$pidfile"
echo -e "$(date +"%Y-%m-%d %H:%M:%S")\\tNOTICE\\t$$ started" >> "$logfile"
echo 1 > "${pwmdev}_enable"
echo ${pwms[0]} > "$pwmdev"
read realpwm < "$pwmdev"
if ! [ "$realpwm" -eq ${pwms[0]} ] 2>/dev/null ; then
echo "ERROR cannot set pwm ${pwms[0]} value: $realpwm" >&2
exit 2
fi
iteration=0
prevtemp=0
while true ; do
emergency=0
if [ -f fancontrol-emergency.sh ] ; then
if ! bash fancontrol-emergency.sh ; then emergency=1 ; fi
fi
if [ $emergency -eq 0 ] ; then
log=''
temp=$($tempcmd 2>/dev/null)
if ! [ "$temp" -eq "$temp" ] 2>/dev/null ; then
echo -e "$(date +"%Y-%m-%d %H:%M:%S")\\tWARNING\\ttemp value: $temp" | tee -a "$logfile" 1>&2
if [ $maxtemp ] ; then temp=$maxtemp ; fi
if [ $targettemp ] ; then temp=$((targettemp+1)) ; fi
fi
log=$(echo -en "$(date +"%Y-%m-%d %H:%M:%S")\\ttemp:$prevtemp,$temp")
if ! [ $targettemp ] ; then log="$log$(echo -en "\\titeration:$iteration")" ; fi
if [ $temp -ne $prevtemp ] || [ $((iteration/delay)) -gt 0 ] || [ "$targettemp" -a $temp -ne "$targettemp" ] 2>/dev/null ; then
unset found
read rawcurrpwm < "$pwmdev"
if ! [ "$rawcurrpwm" -eq "$rawcurrpwm" ] 2>/dev/null ; then
echo -e "$(date +"%Y-%m-%d %H:%M:%S")\\tWARNING\\tpwm value: $rawcurrpwm" | tee -a "$logfile" 1>&2
rawcurrpwm=0
fi
for key in "${!pwms[@]}" ; do
if [ $rawcurrpwm -eq ${pwms[$key]} ] ; then
found=true
currpwm=$key
fi
done
if [ -z $found ] ; then
echo -e "$(date +"%Y-%m-%d %H:%M:%S")\\tWARNING\\tunknown pwm: $rawcurrpwm" | tee -a "$logfile" 1>&2
currpwm=0
fi
unset newpwm
if [ $targettemp ] ; then
if [ $temp -lt $targettemp ] ; then if [ $currpwm -gt 0 ] ; then newpwm=$((currpwm-1)) ; fi
elif [ $temp -gt $targettemp ] ; then if [ $currpwm -lt $((pwmslen-1)) ] ; then newpwm=$((currpwm+1)) ; fi
elif [ $temp -ne $prevtemp ] ; then
if [ $prevpwm ] ; then
newpwm=$(((currpwm+prevpwm)/2))
prevpwm=$newpwm
else
prevpwm=$currpwm
fi
fi
elif [ $mintemp ] && [ $maxtemp ] ; then
if [ $temp -le $mintemp ] ; then newpwm=0
elif [ $temp -ge $maxtemp ] ; then newpwm=$((pwmslen-1))
else newpwm=$(((temp-mintemp-1)*(pwmslen-3)/(maxtemp-mintemp-2)+1)) ; fi
fi
log="$log$(echo -en "\\tpwm:$prevpwm,$currpwm,$newpwm")"
if [ "$newpwm" -gt $currpwm ] 2>/dev/null || [ "$newpwm" -lt $((currpwm-1)) ] 2>/dev/null || [ "$newpwm" -lt $currpwm -a $temp -le "$mintemp" ] 2>/dev/null || [ "$targettemp" -a "$newpwm" -ne $currpwm ] 2>/dev/null ; then
if [ "$newpwm" -gt $currpwm ] || [ $((iteration/delay)) -gt 0 ] || [ $temp -le "$mintemp" ] 2>/dev/null || [ "$targettemp" ] ; then
rawnewpwm=${pwms[$newpwm]}
echo $rawnewpwm > "$pwmdev"
iteration=0
log="$log$(echo -en "\\tset")"
read realpwm < "$pwmdev"
if ! [ "$realpwm" -eq $rawnewpwm ] 2>/dev/null ; then
echo -e "$(date +"%Y-%m-%d %H:%M:%S")\\tWARNING\\tcannot set pwm $rawnewpwm value: $realpwm" | tee -a "$logfile" 1>&2
echo ${pwms[$((pwmslen-1))]} > "$pwmdev"
log="$log$(echo -en "\\tfailed")"
fi
if [ -z "$debug" ] ; then echo "$log" >> "$logfile" ; fi
fi
fi
fi
if [ -n "$debug" ] ; then echo "$log" >> "$logfile" ; fi
if ! [ $targettemp ] ; then iteration=$((iteration+1)) ; fi
prevtemp=$temp
fi
sleep $interval &
wait $!
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment