better (??) version of fancontrol script

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



thanks. checked into CVS.

Dean Takemori wrote:
> Still technically beta quality, but in my local testing it works 
> equivalently to the /bin/sh
> script provided in lm_sensors-2.7.6/prog/pwm but with the bonuses that
> a) it doesn't need to spawn outside programs (sleep, grep etc)
> b) it can daemonize itself, so it works better as a /etc/init.d script
> 
> -dean takemori
> 
> 
> 
> 
> 
> #!/usr/bin/perl -wT
> # $Id: fancontrol,v 1.14 2004/05/31 01:34:29 dean Exp $
> #
> # Perl script for temperature dependent fan speed control.
> #
> # Copyright 2004 dean takemori <deant at hawaii.rr.com>
> #
> # This is a reimplementation in perl of Marius Reiner's bash script for
> # fan speed control.  It has advantages in that it can daemonize itself
> # and needn't spawn subprocesses for grep, sleep etc.  Much of the 
> structure
> # of the bash script is preserved to make mirroring changes easier, so
> # this is seriously non-idiomatic perl but at the same time it should not
> # be considered a a direct bash to perl translation.
> #
> # Usage: fancontrol [CONFIGFILE]
> #
> # For configuration instructions and warnings please see fancontrol.txt,
> # which can be found in the doc/ directory or at the website mentioned
> # elsewhere.
> #
> # This script is derived from Marius Reiner's bash version, so it is
> # hereby placed under the GPL.
> #
> #    Copyright 2003 Marius Reiner <marius.reiner at 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.
> #
> 
> use warnings;
> use strict;
> use IO::Handle;
> use Getopt::Std;
> use POSIX;
> 
> $ENV{PATH} = "/bin:/usr/bin";
> 
> ##### Configuration #####
> use constant DEBUG => 1;
> use constant MAX   => 255;
> 
> use constant PIDFILE  => '/var/run/fancontrol.pid';
> use constant CONFFILE => '/etc/fancontrol';
> 
> use constant SDIR => '/sys/bus/i2c/devices';
> ### End Configuration ###
> 
> our $interval;
> our $pwmo;
> our @afcpwm;
> our @afctemp;
> our @afcfan;
> our @afcmaxtemp;
> our @afcmintemp;
> our @afcminstart;
> our @afcminstop;
> 
> sub loadconfig($);
> sub pwmdisable($);
> sub pwmenable($);
> sub restorefans();
> sub calc(@);
> sub UpdateFanSpeeds();
> 
> our $opt_d;
> getopts('d');
> 
> my $config = shift;
> if (defined($config))
>   { loadconfig($config); }
> else
>   { loadconfig(CONFFILE); }
> 
> ### Daemonize
> if ( defined($opt_d) && ($opt_d == 1) )
>   {
>     my $pid = fork;
>     exit if $pid;
> 
>     unless (defined($pid))
>       { die("Couldn't fork: $!"); }
> 
>     open(*STDERR, '>>', '/var/log/fancontrol/fancontrol.log');
>     IO::Handle::autoflush(*STDERR);
>     open(*STDOUT, '>>', '/var/log/fancontrol/fancontrol.log');
>     IO::Handle::autoflush(*STDOUT);
> 
>     unless (POSIX::setsid())
>       { die("Couldn't open new session: $!"); }
> 
>   }
> 
> ### Pidfile
> if (open(FILE, ">" . PIDFILE))
>   {
>     print(FILE "$$\n");
>     close(FILE);
>   }
> else
>   { print(PIDFILE . ": $!\n"); }
> 
> 
> ### What kind of interface?
> our $sysfs = 0;
> our $dir = '/proc/sys/dev/sensors';
> if (!(-d $dir))
>   {
>     if (!(-d SDIR))
>       { die("No sensors found! (are the necessary modules loaded?) : 
> $!\n"); }
>     else
>       {
>         $sysfs = 1;
>         $dir = SDIR;
>       }
>   }
> 
> ### Trap signals
> $SIG{TERM} = \&restorefans;
> $SIG{HUP}  = \&restorefans;
> $SIG{INT}  = \&restorefans;
> $SIG{QUIT} = \&restorefans;
> 
> ### Enable PWM
> print("Enabling PWM on fans...\n");
> my $fcvcount = 0;
> while ($fcvcount < $#afcpwm+1)
>   {
>     $pwmo = $afcpwm[$fcvcount];
>     unless (pwmenable($pwmo))
>       {
>         print("Error enabling PWM on $dir/$pwmo : $!\n");
>         restorefans();
>       }
>     $fcvcount++;
>   }
> 
> print("Starting automatic fan control...\n");
> 
> while(1)
>   {
>     UpdateFanSpeeds();
>     sleep($interval);
>   }
> 
> 1;
> 
> ################################################################ 
> loadconfig($)
> sub loadconfig($)
> {
>   my $file = shift;
> 
>   print("Loading configuration from $file ...\n");
> 
>   unless ( (-e $file) && (-r $file) )
>     { die("Unable to read config file $file: $!"); }
> 
>   open(F, $file);
> 
>   our ($interval, $fctemps, $fcfans, $mintemp, $maxtemp, $minstart, 
> $minstop);
>   while($_ = <F>)
>     {
>       if ($_ =~ /^\s+$/)                { next; }
>       elsif ($_ =~ /^INTERVAL=(.*)$/) { $interval = $1; next; }
>       elsif ($_ =~ /^FCTEMPS=(.*)$/)  { $fctemps = $1;  next; }
>       elsif ($_ =~ /^FCFANS=(.*)$/)   { $fcfans = $1;   next; }
>       elsif ($_ =~ /^MINTEMP=(.*)$/)  { $mintemp = $1;  next; }
>       elsif ($_ =~ /^MAXTEMP=(.*)$/)  { $maxtemp = $1;  next; }
>       elsif ($_ =~ /^MINSTART=(.*)$/) { $minstart = $1; next; }
>       elsif ($_ =~ /^MINSTOP=(.*)$/)  { $minstop = $1;  next; }
>     }
>   close(F);
> 
>   unless (defined($interval))
>     { die("Some settings missing ..."); }
> 
>   print("\nCommon settings: \n");
>   print("  INTERVAL=$interval\n");
> 
>   my $fcvcount = 0;
>   foreach my $fcv (split(/\s+/, $fctemps))
>     {
>       ($afcpwm[$fcvcount], $afctemp[$fcvcount]) = split(/=/, $fcv);
> 
>       $fcfans   =~ s/^\S*=(\S+)\s*//;  $afcfan[$fcvcount]      = $1;
>       $mintemp  =~ s/^\S*=(\S+)\s*//;  $afcmintemp[$fcvcount]  = $1;
>       $maxtemp  =~ s/^\S*=(\S+)\s*//;  $afcmaxtemp[$fcvcount]  = $1;
>       $minstart =~ s/^\S*=(\S+)\s*//;  $afcminstart[$fcvcount] = $1;
>       $minstop  =~ s/^\S*=(\S+)\s*//;  $afcminstop[$fcvcount]  = $1;
> 
>       print("\nSettings for $afcpwm[$fcvcount]:\n");
>       print("  Depends on $afctemp[$fcvcount]\n");
>       print("  Controls $afcfan[$fcvcount]\n");
>       print("  MINTEMP  = $afcmintemp[$fcvcount]\n");
>       print("  MAXTEMP  = $afcmaxtemp[$fcvcount]\n");
>       print("  MINSTART = $afcminstart[$fcvcount]\n");
>       print("  MINSTOP  = $afcminstop[$fcvcount]\n");
> 
>       $fcvcount++;
>     }
> }
> 
> 
> ################################################################ 
> pwmdisable($)
> sub pwmdisable($)
> {
>   my $p = shift;
> 
>   if ($sysfs == 1)
>     {
>       if (open(F, ">$dir/$p"))
>         {
>           print(F MAX . '\n');
>           close(F);
>         }
>       else
>         { die("$dir/$p : $!"); }
> 
>       my $enable = "$dir/$p/pwm/pwm_enable";
>       if (-f $enable)
>         {
>           if (open(F, ">$enable"))
>             {
>               print(F '0');
>               close(F);
>             }
>           else
>             { die("$dir/$p/pwm/pwm_enable : $!"); }
>         }
>     }
>   else
>     {
>       if (open(F, ">$dir/$p"))
>         {
>           print(F MAX . ' 0');
>           close(F);
>         }
>       else
>         { die("$dir/$p : $!"); }
>     }
>   return(1);
> }
> 
> 
> ################################################################# 
> pwmenable($)
> sub pwmenable($)
> {
>   my $p = shift;
> 
>   if ($sysfs == 1)
>     {
>       my $enable = "$dir/$p/pwm/pwm_enable";
>       if (-f $enable)
>         {
>           if (open(F, ">$enable"))
>             {
>               print(F "1\n");
>               close(F);
>             }
>           else
>             {
>               print("$dir/$p : $!\n");
>               restorefans();
>             }
>         }
>     }
>   else
>     {
>       if (open(F, ">$dir/$p"))
>         {
>           print(F MAX . " 1\n");
>           close(F);
>         }
>       else
>         {
>           print("$dir/$p : $!\n");
>           restorefans();
>         }
>     }
>   return(1);
> }
> 
> 
> ################################################################ 
> restorefans()
> sub restorefans()
> {
>   my $sigtype = shift;
> 
>   $SIG{TERM} = 'IGNORE';
>   $SIG{HUP}  = 'IGNORE';
>   $SIG{INT}  = 'IGNORE';
>   $SIG{QUIT} = 'IGNORE';
> 
>   print("Aborting, restoring fans...\n");
>   my $fcvcount = 0;
> 
>   while ( $fcvcount < $#afcpwm+1)
>     {
>       my $pwmo = $afcpwm[$fcvcount];
>       &pwmdisable($afcpwm[$fcvcount]);
>       $fcvcount++;
>     }
>   print("Verify fans have returned to full speed\n");
>   exit(0);
> }
> 
> 
> ############################################################ 
> UpdateFanSpeeds()
> sub UpdateFanSpeeds()
> {
>   my $fcvcount = 0;
> 
>   while ($fcvcount < $#afcpwm+1)
>     {
>       my $pwmo  = $afcpwm[$fcvcount];
>       my $tsens = $afctemp[$fcvcount];
>       my $fan   = $afcfan[$fcvcount];
>       my $mint  = $afcmintemp[$fcvcount];
>       my $maxt  = $afcmaxtemp[$fcvcount];
>       my $minsa = $afcminstart[$fcvcount];
>       my $minso = $afcminstop[$fcvcount];
> 
>       ### tval
>       my $tval = 0;
>       if (open(F, "$dir/$tsens"))
>         {
>           $tval = <F>;
>           close(F);
>         }
>       else
>         {
>           print("Error reading temperature from $dir/$tsens");
>           restorefans();
>         }
>       $tval =~ /([.\d]+)\s*$/;
>       $tval = int($1);
>       if ($sysfs == 1)
>         { $tval /= 1000; }
> 
>       ### pwmpval
>       my $pwmpval = 0;
>       if (open(F, "$dir/$pwmo"))
>         {
>           $pwmpval = <F>;
>           close(F);
>         }
>       else
>         {
>           print("Error reading PWM value from $dir/$pwmo");
>           restorefans();
>         }
>       ($pwmpval) = split(/\s/, $pwmpval);
> 
>       ### fanval
>       my $fanval = 0;
>       if (open(F, "$dir/$fan"))
>         {
>           $fanval = <F>;
>           close(F);
>         }
>       else
>         {
>           print("Error reading Fan value from $dir/$fan");
>           restorefans();
>         }
>       $fanval =~ /(\d+)\s$/;
>       $fanval = $1;
> 
>       ### DEBUG
>       if (DEBUG == 1)
>         {
>           print("pwmo=$pwmo\n");
>           print("tsens=$tsens\n");
>           print("fan=$fan\n");
>           print("mint=$mint\n");
>           print("maxt=$maxt\n");
>           print("minsa=$minsa\n");
>           print("minso=$minso\n");
>           print("tval=$tval\n");
>           print("pwmpval=$pwmpval\n");
>           print("fanval=$fanval\n");
>           print("\n");
>         }
> 
>       my $pwmval;
>       if ($tval <= $mint)
>         { $pwmval = 0; }
>       elsif ($tval >= $maxt)
>         { $pwmval = MAX; }
>       else
>         {
>           $pwmval = eval ( ($tval - $mint) / ($maxt - $mint) )**2 ;
>           $pwmval *= (255 - $minso);
>           $pwmval += $minso;
>           $pwmval = int($pwmval);
>           if ( ($pwmval == 0) || ($fanval == 0) )
>             {
>               if (open(F, ">$dir/$pwmo"))
>                 {
>                   print(F "$minsa\n");
>                   close(F);
>                 }
>               else
>                 {
>                   print("Error writing PWM value to $dir/$pwmo : $!\n");
>                   restorefans();
>                 }
>               sleep 1;
>             }
>         }
> 
>       if (open(F, ">$dir/$pwmo"))
>         {
>           print(F "$pwmval\n");
>           close(F);
>         }
>       else
>         {
>           print("Error writing PWM value to $dir/$pwmo : $!\n");
>           restorefans();
>         }
> 
>       if (DEBUG == 1)
>         { print("new pwmval = $pwmval\n"); }
> 
>       $fcvcount++;
>     }
> 
> }
> 
> 1;
> 
> 



[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux