# [solved] fan control

## ocin

Hi.

I'm looking for a way to automaticly control my CPU fan. It should be like this:

 *Quote:*   

> 
> 
> under 50°C -> fan 60% speed
> 
> over 50°C -> fan 70% speed
> ...

 

I have an Abit IC7-G mainboard and there is a FanEQ setting in the bios where I can say if under ?°C then ??% fan speed, but with that enabled acpi gets confused and tries to turn on the fan and it prints me every six seconds shit in my messages files see dmesg with faneq on.

So I'm looking for a way (deamon) which can do the rules above. I'm really pissed off, this acpi is a whole crap.Last edited by ocin on Sun Dec 02, 2007 7:08 pm; edited 1 time in total

----------

## SnEptUne

Assuming you have I2C and lm_sensors set up correctly, you can use this script (from gentoo wiki?):

/usr/sbin/fancontrol

```

#!/bin/bash

#

# Simple script implementing a temperature dependent fan speed control

#

# Version 0.63

#

# 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 SVN 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 <marius.reiner@hdev.de>

#

#    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.

#

#

#DEBUG=1

MAX=255

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'`

   # optional settings:

   FCFANS=`egrep '^FCFANS=.*$' $1 | sed -e 's/FCFANS=//g'`

   

   # Check whether all mandatory settings are set

   if [[ -z ${INTERVAL} || -z ${FCTEMPS} || -z ${MINTEMP} || -z ${MAXTEMP} || -z ${MINSTART} || -z ${MINSTOP} ]]

   then

      echo "Some mandatory settings missing, please check your config file!"

      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`

      AFCFAN[$fcvcount]=`echo $FCFANS |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`

      AFCMINTEMP[$fcvcount]=`echo $MINTEMP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`

      AFCMAXTEMP[$fcvcount]=`echo $MAXTEMP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`

      AFCMINSTART[$fcvcount]=`echo $MINSTART |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`

      AFCMINSTOP[$fcvcount]=`echo $MINSTOP |sed -e 's/ /\n/g' |egrep "${AFCPWM[$fcvcount]}" |cut -d'=' -f2`

      echo

      echo "Settings for ${AFCPWM[$fcvcount]}:"

      echo "  Depends on ${AFCTEMP[$fcvcount]}"

      echo "  Controls ${AFCFAN[$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

DIR=/proc/sys/dev/sensors

SDIR=/sys/bus/platform/devices

if [ ! -d $DIR ]

then

   if [ ! -d $SDIR ]

   then

      echo $0: 'No sensors found! (did you load the necessary modules?)'

      exit 1

   else

      SYSFS=1

      DIR=$SDIR

   fi   

fi

cd $DIR

# $1 = pwm file name

function pwmdisable()

{

   if [ "$SYSFS" = "1" ]

   then

      echo $MAX > $1

      ENABLE=${1}_enable

      if [ -f $ENABLE ]

      then

         echo 0 > $ENABLE

      fi

   else

      echo $MAX 0 > $1

   fi

}

# $1 = pwm file name

function pwmenable()

{

   if [ "$SYSFS" = "1" ]

   then

      ENABLE=${1}_enable

      if [ -f $ENABLE ]

      then

         echo 1 > $ENABLE

      fi

   else

      echo $MAX 1 > $1

   fi

}

function restorefans()

{

   echo 'Aborting, restoring fans...'

   let fcvcount=0

   while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs

   do

      pwmo=${AFCPWM[$fcvcount]}

      pwmdisable $pwmo

      fcvcount=$fcvcount+1

   done

   echo 'Verify fans have returned to full speed'

   exit 1

}

trap restorefans SIGHUP SIGINT SIGQUIT SIGTERM SIGKILL

# 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]}

      fan=${AFCFAN[$fcvcount]}

      mint=${AFCMINTEMP[$fcvcount]}

      maxt=${AFCMAXTEMP[$fcvcount]}

      minsa=${AFCMINSTART[$fcvcount]}

      minso=${AFCMINSTOP[$fcvcount]}

      

      tval=`cat ${tsens}`

      if [ $? -ne 0 ]

      then

         echo "Error reading temperature from $DIR/$tsens"

         restorefans

      fi

      tval=`echo ${tval} |cut -d' ' -f3 |cut -d'.' -f1`

      if [ "$SYSFS" = "1" ]

      then

         let tval="$tval / 1000"

      fi

      pwmpval=`cat ${pwmo}`

      if [ $? -ne 0 ]

      then

         echo "Error reading PWM value from $DIR/$pwmo"

         restorefans

      fi

      pwmpval=`echo ${pwmpval} | cut -d' ' -f1`

      

      # If fanspeed-sensor output shall be used, do it

      if [[ -n ${fan} ]]

      then

         fanval=`cat ${fan}`

         if [ $? -ne 0 ]

         then

            echo "Error reading Fan value from $DIR/$fan"

            restorefans

         fi

         fanval=`echo ${fanval} | cut -d' ' -f2`

      else

         fanval=1  # set it to a non zero value, so the rest of the script still works

      fi

      

      # debug info

      if [ "$DEBUG" != "" ]

      then

         echo "pwmo=$pwmo"

         echo "tsens=$tsens"

         echo "fan=$fan"

         echo "mint=$mint"

         echo "maxt=$maxt"

         echo "minsa=$minsa"

         echo "minso=$minso"

         echo "tval=$tval"

         echo "pwmpval=$pwmpval"

         echo "fanval=$fanval"

      fi

      

      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 "(((${tval}-${mint})/(${maxt}-${mint}))^2*(255-${minso})+${minso})" |cut -d'.' -f1`

        if [ $pwmpval -eq 0 -o $fanval -eq 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

      if [ $? -ne 0 ]

      then

         echo "Error writing PWM value to $DIR/$pwmo"

         restorefans

      fi

      if [ "$DEBUG" != "" ]

      then

         echo "new pwmval=$pwmval"

      fi

      fcvcount=$fcvcount+1

   done

}

echo 'Enabling PWM on fans...'

let fcvcount=0

while (( $fcvcount < ${#AFCPWM[@]} )) # go through all pwm outputs

do

   pwmo=${AFCPWM[$fcvcount]}

   pwmenable $pwmo

   if [ $? -ne 0 ]

   then

      echo "Error enabling PWM on $DIR/$pwmo"

      restorefans

   fi

   fcvcount=$fcvcount+1

done

echo 'Starting automatic fan control...'

# main loop calling the main function at specified intervals

while true

do

   UpdateFanSpeeds

   sleep $INTERVAL

done

```

/etc/init.d/fancontrol

```

!/sbin/runscript

# Copyright 1999-2006 Gentoo Foundation

# Distributed under the terms of the GNU General Public License v2

# $Header: /var/cvsroot/gentoo-x86/sys-apps/lm_sensors/files/fancontrol-init.d,v 1.1 2007/05/17 07:31:41 phreak Exp $

CONFIG=/etc/fancontrol

PID=/var/run/fancontrol.pid

depend() {

        after lm_sensors

}

checkconfig() {

        if [ ! -f ${CONFIG} ]; then

                eerror "Configuration file ${CONFIG} not found"

                return 1

        fi

}

start() {

        checkconfig || return 1

        ebegin "Starting fancontrol"

        start-stop-daemon --start --quiet --background --pidfile ${PID} \

                --exec /usr/sbin/fancontrol -- ${CONFIG}

        eend ${?}

}

stop() {

        ebegin "Stopping fancontrol"

        start-stop-daemon --stop --pidfile ${PID}

        eend ${?}

}

```

/etc/fancontrol

```

INTERVAL=15 #update interval in seconds

FCTEMPS=it87.2576/pwm1=it87.2576/temp1_input #i2c device temperature

FCFANS=it87.2576/pwm1=it87.2576/fan1_input  #i2c device fan speed

MINTEMP=it87.2576/pwm1=35

MAXTEMP=it87.2576/pwm1=55

MINSTART=it87.2576/pwm1=100

MINSTOP=it87.2576/pwm1=50

```

----------

## ocin

Well thats not exactly what I want but it works like a charm.

Thank you.

----------

## bunder

strange... i use asus qfan on all my machines, and i don't get such errors...  what's your kernel version?

edit: tried checking your DSDT?

----------

## ocin

 *bunder wrote:*   

> strange... i use asus qfan on all my machines, and i don't get such errors...  what's your kernel version?
> 
> edit: tried checking your DSDT?

 

abit faneq != asus qfan

well I'm using the latest rc kernel but the problem is there since jan 07 or so and it hasn't got fixed yet. google for "unable to turn cooling device" and you'll see I'm not the only one with this kind of problem.

I also opened a bug at the kernel bugzilla. And what is this dsdt?

----------

## bunder

 *most.idiot wrote:*   

> And what is this dsdt?

 

HOWTO Fix Common ACPI Problems  :Wink: 

cheers

----------

## ocin

 *bunder wrote:*   

>  *most.idiot wrote:*   And what is this dsdt? 
> 
> HOWTO Fix Common ACPI Problems  :wink: 
> 
> cheers

 

huh thats too much for me, thank you though.

----------

