#!/bin/bash # # Simple script implementing a temperature dependent fan speed control # # Version 0.61 # # Usage: fancontrol [CONFIGFILE] # # Dependencies: # bash, awk, egrep, sed, lm_sensors :) # # Please send any questions, comments or success stories to # marius.reiner@hdev.de # Thanks! # # The latest version of this script is available at: # http://www.hdev.de/fancontrol/fancontrol.html # or in the CVS version of lm_sensors # # For configuration instructions and warnings please see fancontrol.txt, which # can be found in the doc/ directory or at the website mentioned above. # # # Copyright 2003 Marius Reiner # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # echo $$ > /var/run/fancontrol.pid function LoadConfig { echo "Loading configuration from $1 ..." # grep configuration from file INTERVAL=`egrep '^INTERVAL=.*$' $1 | sed -e 's/INTERVAL=//g'` FCTEMPS=`egrep '^FCTEMPS=.*$' $1 | sed -e 's/FCTEMPS=//g'` MINTEMP=`egrep '^MINTEMP=.*$' $1 | sed -e 's/MINTEMP=//g'` MAXTEMP=`egrep '^MAXTEMP=.*$' $1 | sed -e 's/MAXTEMP=//g'` MINSTART=`egrep '^MINSTART=.*$' $1 | sed -e 's/MINSTART=//g'` MINSTOP=`egrep '^MINSTOP=.*$' $1 | sed -e 's/MINSTOP=//g'` if [ "$INTERVAL" = "" ] then echo "Some settings missing..." exit 1 fi # here the other settings should be verified # write settings to arrays for easier use and print them echo echo "Common settings:" echo " INTERVAL=$INTERVAL" let fcvcount=0 for fcv in $FCTEMPS do AFCPWM[$fcvcount]=`echo $fcv |cut -d'=' -f1` AFCTEMP[$fcvcount]=`echo $fcv |cut -d'=' -f2` AFCMINTEMP[$fcvcount]=`echo $MINTEMP |sed -s 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` AFCMAXTEMP[$fcvcount]=`echo $MAXTEMP |sed -s 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` AFCMINSTART[$fcvcount]=`echo $MINSTART |sed -s 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` AFCMINSTOP[$fcvcount]=`echo $MINSTOP |sed -s 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2` echo echo "Settings for ${AFCPWM[$fcvcount]}:" echo " Depends on ${AFCTEMP[$fcvcount]}" echo " MINTEMP=${AFCMINTEMP[$fcvcount]}" echo " MAXTEMP=${AFCMAXTEMP[$fcvcount]}" echo " MINSTART=${AFCMINSTART[$fcvcount]}" echo " MINSTOP=${AFCMINSTOP[$fcvcount]}" let fcvcount=fcvcount+1 done echo } if [ -f "$1" ] then LoadConfig $1 else LoadConfig /etc/fancontrol fi cd /proc/sys/dev/sensors/ if (( $? != 0 )) ; then echo "Directory /proc/sys/dev/sensors/ does not exist, did you load the necessary kernel modules?" exit 1 fi # function doing all the math function calc () { awk "BEGIN { print $@ }" } # main function function UpdateFanSpeeds { let fcvcount=0 while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs do #hopefully shorter vars will improve readability: pwmo=${AFCPWM[$fcvcount]} tsens=${AFCTEMP[$fcvcount]} mint=${AFCMINTEMP[$fcvcount]} maxt=${AFCMAXTEMP[$fcvcount]} minsa=${AFCMINSTART[$fcvcount]} minso=${AFCMINSTOP[$fcvcount]} tval=`cat ${tsens} |cut -d' ' -f3 |cut -d'.' -f1` pwmpval=`cat ${pwmo}` # debug info #echo "pwmo=$pwmo" #echo "tsens=$tsens" #echo "mint=$mint" #echo "maxt=$maxt" #echo "minsa=$minsa" #echo "minso=$minso" #echo "tval=$tval" #echo "pwmpval=$pwmpval" if (( $tval <= $mint )) then pwmval=0 # at specified mintemp shut fan off elif (( $tval >= $maxt )) then pwmval=255 # at specified maxtemp switch to 100% else # calculate the new value from temperature and settings pwmval=`calc "((10/(${maxt}-${mint})*(${tval}-${mint}))^2/1000*(${maxt}-${mint})*(255-${minso})+${minso})" |cut -d'.' -f1` if (( $pwmpval == 0 )) then # if fan was stopped start it using a safe value echo $minsa > $pwmo sleep 1 fi fi echo $pwmval > $pwmo # write new value to pwm output fcvcount=$fcvcount+1 done } # main loop calling the main function at specified intervals while true do UpdateFanSpeeds sleep $INTERVAL done # some old stuff/missing features, will clean this up soon #if ( test "$regulationtype" = "quad" ) ; then # while true ; do # temp=`cat ${temp1} | cut -b 12-13` # if (( ${temp} < ${mintemp} )) ; # then pwm=0 # elif (( ${temp} > ${maxtemp} )) ; # then pwm=255 # else # pwm=`calc "((10/(${maxtemp}-${mintemp})*(${temp}-${mintemp}))^2/1000*(${maxtemp}-${mintemp})*(255-${minspeed})+${minspeed})"` # #no optimization here for readability (or sloth :)) # fi ; # echo $pwm > ${pwm1} ; # # sleep 10 ; # done ; #elif ( test "$regulationtype" = "exp" ) ; then #add support for exponential calculation here #else # pwmconst=$[(255-${minspeed})/(${maxtemp}-${mintemp})] # while true ; do # let temp=`cat temp1 | cut -b 12-13` ; # if (( ${temp} < ${mintemp} )) ; # then pwm=0 # elif (( ${temp} > ${maxtemp} )) ; # then pwm=255 # else # pwm=$[(${temp}-${mintemp})*${pwmconst}+${minspeed}] # fi ; # echo $pwm > pwm2 ; # # sleep 10 ; # done ; #fi