ibm-fancontrol.pl
Per olof Ljungmark
peo at intersonic.se
Mon Jul 23 19:26:12 UTC 2012
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 ----------------
More information about the freebsd-mobile
mailing list