SantaRosaFanControl

Differences between revisions 11 and 12
Revision 11 as of 2007-10-16 06:45:25
Size: 7580
Editor: mx
Comment:
Revision 12 as of 2007-10-16 07:01:27
Size: 7865
Editor: mx
Comment:
Deletions are marked like this. Additions are marked like this.
Line 28: Line 28:
# version 0.3 - 20071016
Line 31: Line 32:
### WARNING ###                    ### W A R N I N G ###
Line 46: Line 47:
  MIN=465 # temp in degree celsius x 10
  MAX=520
  MIN=475 # temp in degree celsius x 10
  MAX=540
Line 53: Line 54:
  let "RATIO = 4500 / ($MAX - $MIN)"   let "RATIO = 6000 / ($MAX - $MIN)"
Line 56: Line 57:
 let "HIGH = ( ($MAX - $MIN)/3 ) + $TARGET"
}

debug=0
do_init
count=1


while [ true ]; do
# let "HIGH = ( ($MAX - $MIN)/3 ) + $TARGET"
}

get_temp()
{
Line 70: Line 67:

 [ $debug -eq 1 ] && echo "average temp: $TEMP (target: $TARGET, high: $HIGH)"
}

debug=0
do_init
count=1
maxtempcount=0

while [ true ]; do

 get_temp

 [ $debug -eq 1 ] && echo "average temp: $TEMP (target: $TARGET, max: $MAX)"
Line 85: Line 92:
 [ $debug -eq 1 ] && echo "set fan speed to: $SPEED (ratio: $RATIO)"  [ $debug -eq 1 ] && echo "set fan speed to: $SPEED (step: $RATIO)"
Line 88: Line 95:
   if [ $SPEED -lt 2 ]; then
  # Sleep longer when autoregulatings

 if [ $TEMP -gt $MAX ]; then
  [ $debug -eq 1 ] && echo "temp: $TEMP > max: $MAX"
  let "maxtempcount = $maxtempcount + 1"
  if [ $maxtempcount -gt 3 ]; then
   while [ $TEMP -gt $TARGET ]; do
    [ $debug -eq 1 ] && echo "Force fan speed to: 6000 until temp ($TEMP) = $TARGET"
    echo 6000 > /sys/devices/platform/applesmc.768/fan2_min
    echo 6000 > /sys/devices/platform/applesmc.768/fan1_min
    sleep 10
    get_temp
    let "count = $count + 2"
   done
   maxtempcount=0
  else
   sleep 5
   let "count = $count+1"
  fi
 elif [ $SPEED -lt 2 ]; then
  # Sleep longer when autoregulating
Line 101: Line 125:
  # if above HIGH temp level, force the fan speed a bit
  if [ $TEMP -gt $HIGH ]; then
   [ $debug -eq 1 ] && echo "temp: $TEMP > target: $TARGET"
   [ $debug -eq 1 ] && echo "Force fan speed to: 6000 for 20 sec"
   echo 6000 > /sys/devices/platform/applesmc.768/fan2_min
   echo 6000 > /sys/devices/platform/applesmc.768/fan1_min
   sleep 20
  fi

Finding that my MacBookPro 3.1 (MacBookPro/SantaRosa) was getting incredibly hot, even with applesmc installed.

Trivia (how I came to write this and other boring details)

I first tried to set the fans to 3000rpm, but even then, at the end of the day it would remain hot. At least, the writer of the comment I have followed gave me the base knowledge on how to deal with applesmc.

From then I have written a stupid little script, that grew a bit along a couple week of testing, which controls the minimum fan speed so that it stays at a reasonable temperature. The model is quite weird because it's a linear one (the rpm grows linearly as the temperature grows, trying to find the best possible equilibrium between the value range you give it). Maybe a log or a sinus one should have been more efficient, but I am still trying to figure how to do a log in bash, when you have to remain in the great world of integer.

Other quirk: we have 2 fans and 8 sensors. Which one are left, or right, no one tells, so for now I do an average on the main 4 ones (the one I have seen growing the hotest first). I average them and base my cooling on it.

Also, I came to realize a bit late, that when setting the minimum fan speed to one, applesmc seems to take over regulation. This is why when it tops cleanly, it leave the value to 1. If you leave it this way you core temperature is stabilzed around 56, which is a bit too hot but it works well to have a low fan speed. One of these days I'll have time to dig into applesmc to understand how it works...

Thermodynamic model

The what ? Beleive me, I am even surprised I know how to spell this Wink ;)

the scripts

Warning

There is no guaranty that the model I am using works. Nobody but you take the responsability to install this on your laptop. If your laptop starts burning, start by turning it off then blame yourself. You've been warned !

tempmon (the main part)

The following scripts create a daemon that will regulate temperature for us. They (the 2 scripts) just require that the applesmc module be loaded (sudo modeprobe applesmc to make sure). Create it as /usr/local/sbin/tempmon.

# version 0.3 - 20071016
# A temperature daemon to help for a cooler MacBookPro 3.1
# Author nick barcet nickNOSPAM AT barcet DOT com

                   ### W A R N I N G ###

# No garanty whatsoever that it will do good to your computer.
# You can blame yourself for installing this if your processor
# decides to die tomorrow

do_init()
{
        # I'm pretty happy with the following  values but feel free to
        # play with them.  Just keep an eye on the values return by the sensors
        # package.
        # We set different value for on and off line, as we don't care
        # about saving power when on-line.
        if (cat /proc/acpi/ac_adapter/ADP1/state | grep on-line > /dev/null); then
                # We are online, be pretty cool
                MIN=475 # temp in degree celsius x 10
                MAX=540
                let "RATIO = 6000 / ($MAX - $MIN)"
        else
                [ $debug -eq 1 ] && echo "state:                   off-line"
                MIN=510 # temp in degree celsius x 10
                MAX=590
                let "RATIO = 6000 / ($MAX - $MIN)"
        fi
        let "TARGET = ( ($MAX - $MIN)/3 ) + $MIN"
#       let "HIGH = ( ($MAX - $MIN)/3 ) + $TARGET"
}

get_temp()
{
        TEMP1=`cat /sys/devices/platform/applesmc.768/temp5_input`
        TEMP2=`cat /sys/devices/platform/applesmc.768/temp8_input`
        TEMP3=`cat /sys/devices/platform/applesmc.768/temp3_input`
        TEMP4=`cat /sys/devices/platform/applesmc.768/temp3_input`
        let "TEMP = ($TEMP1 + $TEMP2 + $TEMP3 + $TEMP4)/ 400"
}

debug=0
do_init
count=1
maxtempcount=0

while [ true ]; do 

        get_temp

        [ $debug -eq 1 ] && echo "average temp: $TEMP (target: $TARGET, max: $MAX)" 
        
        let "SPEED = ($TEMP - $MIN) * $RATIO"    

        # Just to make sur we do not set fan >6000 or <0
        if [ $SPEED -gt 6000 ]; then
                SPEED=6000
        elif [ $SPEED -lt 1 ]; then
                SPEED=1
        elif [ $TEMP -lt $TARGET ]; then
                #let autoregulation work (if it does)
                SPEED=1  
        fi

        [ $debug -eq 1 ] && echo "set fan speed to: $SPEED (step: $RATIO)"
        echo $SPEED > /sys/devices/platform/applesmc.768/fan2_min
        echo $SPEED > /sys/devices/platform/applesmc.768/fan1_min

        if [ $TEMP -gt $MAX ]; then
                [ $debug -eq 1 ] && echo "temp: $TEMP > max: $MAX"
                let "maxtempcount = $maxtempcount + 1"
                if [ $maxtempcount -gt 3 ]; then
                        while [ $TEMP -gt $TARGET ]; do
                                [ $debug -eq 1 ] && echo "Force fan speed to: 6000 until temp ($TEMP) = $TARGET"
                                echo 6000 > /sys/devices/platform/applesmc.768/fan2_min
                                echo 6000 > /sys/devices/platform/applesmc.768/fan1_min
                                sleep 10
                                get_temp
                                let "count = $count + 2"
                        done
                        maxtempcount=0
                else
                        sleep 5
                        let "count = $count+1"
                fi
        elif [ $SPEED -lt 2 ]; then
                # Sleep longer when autoregulating
                sleep 20
                let "count = $count+4"
        else
                sleep 5
                let "count = $count+1"
        fi

        if [ $count -gt 10 ]; then
                count=0
                do_init
        fi
done

allow access rights to it by doing a :

sudo chmod +x /usr/local/sbin

tempmon.sh (the init.d script)

then add the following script as /etc/init.d/tempmon.sh :

### BEGIN INIT INFO
# Provides:          tempmon.sh
# Required-Start:    $local_fs $remote_fs
# Required-Stop:     $local_fs $remote_fs
# Default-Start:     2 3 4 5
# Default-Stop:      S 0 1 6
# Short-Description: Sets the MacBook minimum fan speed
# Description:       Uses the applesmc kernel module to set the minimum
#                    fan speed that the Mac will leave the fan at.
### END INIT INFO

# Author: Jason Parekh <jasonparekh@gmail.com> 
# modified by nick barcet nickNOSPAM AT barcet DOT com

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/usr/sbin:/usr/bin:/sbin:/bin
DESC="MacBook minimum fan speed setter"
NAME=tempmon
SCRIPTNAME=/etc/init.d/$NAME
MIN_FAN_SPEED=3000
DEFAULT_MIN_FAN_SPEED=2000

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
[ -f /etc/default/rcS ] && . /etc/default/rcS

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
        killall tempmon &> /dev/null
        /usr/local/sbin/tempmon > /dev/null &
}

#
# Function that stops the daemon/service
#
do_stop()
{
        killall tempmon&> /dev/null
        sleep 1
        # Put the fan back to auto regulation
        echo 1 > /sys/devices/platform/applesmc.768/fan2_min
        echo 1 > /sys/devices/platform/applesmc.768/fan1_min
}

case "$1" in
  start)
        [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
        do_start
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
  reload|force-reload|restart)

        log_daemon_msg "Reloading $DESC" "$NAME"
        do_start
        log_end_msg 0
        ;;
  *)
        echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
        #echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
        exit 3
        ;;
esac

:

allow access rights to it by doing a :

sudo chmod +x /etc/init.d/tempmon.sh

make sure that it starts and stops automatically :

sudo update-rc.d tempmon.sh defaults 90

Starting the daemon automatically

you can then start and stop the daemon by using the following call

sudo /etc/init.d/tempmon.sh {start|stop|reload} 

MacBookPro/SantaRosaFanControl (last edited 2011-04-21 11:08:42 by mx)