Re: ibm-fancontrol.pl

Per olof Ljungmark <[email protected]>
Newsgroups gmane.os.freebsd.devel.mobile
Organization Intersonic AB
Message-ID <[email protected]>
On 07/23/12 20:47, Ian Smith wrote:
> On Mon, 23 Jul 2012 18:03:53 +0200, Per olof Ljungmark wrote:
>   >  On 2012-07-23 13:57, Per olof Ljungmark wrote:
>   >  >  Hi,
>   >  >
>   >  >  Does anyone happen to have this perl script at hand? I seem to have lost
>   >  >  it and it was doing a good job holding temperature at bay for my X61.
>   >  >
>   >  >  For some reason Google refuses to tell me where it hides...
>   >
>   >  Never mind, found a backup. Sorry for the noise.
>
> Not at all .. care to share? :)
>
> I've been running a bespoke sh script for fan control on my T23 since
> November to good effect, but that was easy with only a two speed fan.
> I'd like to generalise it for N speeds .. yours might include clues :)
>

Well, it's not mine and the file has no references to the author, 
perhaps he/she is on this list?

It only requires p5-Proc-Daemon.

I've been using it for older T's and X's with good results, never 
overheats and seems to do a good balance between performance and 
temperature.

Cheeers,

--------------- cut here -----------------

#!/usr/bin/perl

############### WARNING ###############
# This script takes control of the fan
# in your laptop. It works perfectly on
# my laptop, but could ruin your laptop!
############### WARNING ###############

use strict;
use warnings;
use diagnostics;
use Proc::Daemon;

my %curr_temps;
my $lowest_cpu_temp = 52;
my $highest_cpu_temp = 83;
my $cpu_freq_down_time;
#
my $daemon_pidfile = "/tmp/ibm_fancontrol_fbsd.pid";
my $daemonize = "1";
my $daemondebug = "1";
#
# Set powerd_level to 0 if you do not want to run powerd
my $powerd_level = 69;
my $powerd_pidfile = "/var/run/powerd.pid";

my %sensors = ( "1", "CPU",
                 "2", "Mini PCI Module",
                 "3", "HDD",
                 "4", "GPU",
                 "5", "Built-in battery",
                 "6", "UltraBay battery",
                 "7", "Built-in battery",
                 "8", "UltraBay battery");

my %cpu_temp_fan_levels = ( "52", "1", "53", "1", "54", "1", "55", "2", 
"56", "2", "57", "2", "58", "3", "59", "3", "60", "3", "61", "4", "62", 
"4", "63", "4", "64", "5", "65", "5", "66", "5", "67", "6", "68", "6", 
"69", "6", "70", "7", "71", "7", "72", "7");

sub gettemps {
         my @temps = split(" ", qx(/sbin/sysctl dev.acpi_ibm.0.thermal));
         my $counter = 0;

         foreach my $temp (@temps) {
                 if ($sensors{$counter}) {
                         $curr_temps{$counter} = $temp;
#                       print "T: $sensors{$counter} - $temp\n";
                 }

                 $counter++;
         }
}

sub powerd_check {
         if ( -f $powerd_pidfile ) {
                 open(FILE,"$powerd_pidfile") or die "can not open file 
$powerd_pidfile";
                 my $powerd_pid=<FILE>;
                 close(FILE);

                 my $pid_check = system("/bin/ps -p $powerd_pid 
 >/dev/null");

                 if ( $pid_check == 0 ) {
                         return($powerd_pid);
                 } else {
                         return(0);
                 }
         } else {
                 return(0);
         }
}

sub cpufreq {
         my $action = shift;
         my %freqlevels;
         my $freqlevel;

         my @cpu_freq = split(" ", qx(/sbin/sysctl dev.cpu.0.freq));
         my @cpu_freq_levels = split(" ", qx(/sbin/sysctl 
dev.cpu.0.freq_levels));

         my $freq_nr = 0;

         foreach my $freq_level (@cpu_freq_levels) {
                 my @freq = split("/", $freq_level);
                 next if ($freq[0] !~ m/^\d+/);

                 if ($freq[0] eq $cpu_freq[1]) {
                         $freqlevel = $freq_nr;
                 }

                 $freqlevels{$freq_nr} = $freq[0];
                 $freq_nr++;
         }

         if ($action eq "higher") {
                 if ($freqlevel ne 0) {
                         $freqlevel--;
                 }

                 return($freqlevels{$freqlevel});
         } else {
                 $freqlevel++;
                 return($freqlevels{$freqlevel});
         }
}

### MAIN PROGRAM ###

if ( $daemonize == "1" ) {
         print "$0: Switching to daemon mode\n";
         Proc::Daemon::Init;

         if ( $daemondebug == 1 ) {
                 my $logfile = "/tmp/debug.log";
                 open(STDOUT, ">>$logfile") or die "Failed to re-open 
STDOUT to $logfile";
                 open(STDERR, ">&STDOUT") or die "Failed to re-open 
STDERR to STDOUT";
         }

         my $pid = $$;

         if($pid) {
                 open PIDFILE, ">$daemon_pidfile" or die "$0: can't 
write to $daemon_pidfile: $!\n";
                 print PIDFILE "$pid\n";
                 close(PIDFILE);
         }

         while(1) {
                 BeDaemon();
         }
} else {
         print "$0: Running in foreground (debug) mode\n";
         BeDaemon();
}

sub BeDaemon {
         while(1) {
                 gettemps();

                 for my $nr (sort keys %curr_temps) {
                         if ( $nr == 1 ) {
                                 print "CPU: $nr: $curr_temps{$nr} - 
$sensors{$nr}\n";

                                 if ( $curr_temps{$nr} <= $powerd_level ) {
                                         if ( $powerd_level != 0 ) {
                                                 # powerd is allowed at 
this temp
                                                 # Check if it is 
allready running else start it
                                                 my $powerd_pid = 
powerd_check();

                                                 if ( $powerd_pid == 0 ) {
                                                         print "Starting 
powerd\n";
 
system("/usr/sbin/powerd -a adaptive -b adaptive -n adaptive");
                                                 }
                                         }
                                 }

                                 if ( $curr_temps{$nr} < 
$lowest_cpu_temp ) {
                                         # Stop the fan
                                         system("/sbin/sysctl 
dev.acpi_ibm.0.fan=0");
                                         system("/sbin/sysctl 
dev.acpi_ibm.0.fan_level=0");
                                 } elsif ( $curr_temps{$nr} > 
$highest_cpu_temp ) {
                                         # Hot
                                         # Run fan at the highest level 
and slow down the cpu!!
                                         system("/sbin/sysctl 
dev.acpi_ibm.0.fan=0");
                                         system("/sbin/sysctl 
dev.acpi_ibm.0.fan_level=7");

                                         # We have to stop powerd at 
this level
                                         my $powerd_pid = powerd_check();

                                         if ( $powerd_pid > 0 ) {
                                                 print "Killing powerd\n";
                                                 system("kill $powerd_pid");
                                         }

                                         my $new_cpu_freq = 
cpufreq("lower");
                                         system("/sbin/sysctl 
dev.cpu.0.freq=$new_cpu_freq");
                                         sleep(10);
                                         $cpu_freq_down_time = time();
                                 } else {
                                         # We need to change the speed 
of the fan.

                                         # If it's higher than the 
current value, than
                                         # we will not change it to a 
lower value the next
                                         # 30 seconds
                                         my @dummy_one = split(" ", 
qx(/sbin/sysctl dev.acpi_ibm.0.fan_level));
                                         my $fan_level = $dummy_one[1];

                                         if ( $fan_level < 
$cpu_temp_fan_levels{$curr_temps{$nr}} ) {
                                                 system("/sbin/sysctl 
dev.acpi_ibm.0.fan=0");
                                                 system("/sbin/sysctl 
dev.acpi_ibm.0.fan_level=$cpu_temp_fan_levels{$curr_temps{$nr}}");
###                                             sleep(30);
                                         } elsif ( $fan_level > 
$cpu_temp_fan_levels{$curr_temps{$nr}} ) {
                                                 system("/sbin/sysctl 
dev.acpi_ibm.0.fan=0");
                                                 system("/sbin/sysctl 
dev.acpi_ibm.0.fan_level=$cpu_temp_fan_levels{$curr_temps{$nr}}");

                                                 my $curr_time = time();
                                                 $cpu_freq_down_time = 0 
if (! $cpu_freq_down_time);

                                                 my $time_diff = 
($curr_time - $cpu_freq_down_time);

                                                 if ($time_diff > 60 ) {
                                                         my 
$new_cpu_freq = cpufreq("higher");
 
system("/sbin/sysctl dev.cpu.0.freq=$new_cpu_freq");
                                                         sleep(10);
                                                 }
                                         }
                                 }
                         }
                 }

                 print 
"===================================================================================\n";
                 sleep(1);
         }
}

---------- cut here ----------------
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-mobile
To unsubscribe, send any mail to "[email protected]"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.