All pastes #747372 Raw Edit

Unnamed

public text v1 · immutable
·published 2007-10-23 23:36 UTC
rendered paste body
#!/usr/bin/perl 
#-----------------------------------------------------------------
# By: johns@msli.com
#
# Purpouse: 
#     Keep fan as slow as possible for a given Target CPU Temp.
#
# Some Testing:
#     speed    temp
#     100      40-42
#     255-100  37-39
#   
# REFERENCE:   http://www.intel.com/support/processors/pentiumiii/sb/cs-007589.htm
# CPU MODEL:   Intel(R) Pentium(R) III CPU - S         1266MHz
# Min temp:    45
#-----------------------------------------------------------------
my $debug=          "1";                # debug 1=on, 0=off
my $graph=          "1";                # graph 1=on, 0=off
my $pause=          "5";                # Time between tests
my $sensors=        "/usr/bin/sensors"; # Binary for sensors
my $Sensor_string=  "pc87366-isa-1410"; # Header in sensors output
my $time=time(  );
my $Speed=          "100" ;             # Setting default fan speed.
my $TargetTmp_upper="44";               # Target temp for CPU
my $TargetTmp_lower="42";               # Target temp for CPU
my $ProcFile=       "/sys/devices/platform/i2c-9191/9191-1410/pwm2";
my $rrd_file=       "/root/rrd/fan_temp.rrd";
my $graph_file_2hr= "/root/rrd/fan_temp_2hr.png";
my $graph_file_12hr="/root/rrd/fan_temp_12hr.png";
my $graph_file_1wk="/root/rrd/fan_temp_1wk.png";
#-----------------------------------------------------------------
# flush the buffer
$| = 1;
#-----------------------------------------------------------------
# daemonize the program
if ( $debug eq "0" ){  &daemonize; }
#-----------------------------------------------------------------
# Set initial fan speed to our base
&update_fanspeed($Speed);
#-----------------------------------------------------------------
# Main Loop, 
# Runs forever
while ( 1 ){
    #
    # Get temp
    #
    chomp ( my $Temp=&get_temp );
    if ( $debug eq "1" ){  print "Temp: $Temp\n"; }
    #
    # Get speed
    #
    chomp ( $Speed=&get_fanspeed );
    if ( $debug eq "1" ){  print "Speed:  $Speed\n"; }
    #
    # Calculate new speed
    #
    my $NewSpeed=&new_fanspeed($Temp,$Speed);
    if ( $debug eq "1" ){  print "NewSpeed:  $NewSpeed\n"; }
    #
    # If Speed and NewSpeed are not equal, update fan speed file.
    #
    if ( $NewSpeed ne $Speed ){ 
        &update_fanspeed($NewSpeed); 
	if ( $debug eq "1" ){  print "Loading new speed\n"; }
    }
    #
    # Create RRD file, if it does not exist
    #
    if ( ! -e "$rrd_file" ){
    	    &create_graph($rrd_file);  
    };
    #
    # Record Fan speed
    #
    my $NewSpeed=&record_fanspeed($Temp,$Speed,$rrd_file);
    #
    # Graph from rrd
    #
    &graph_fanspeed($rrd_file,$graph_file_2hr,$graph_file_12hr,$graph_file_1wk);
    #
    #
    # Sleep
    #
    system ( sleep $pause );
}
#-----------------------------------------------------------------
sub daemonize {
    chdir '/'                 or die "Can't chdir to /: $!";
    open STDIN, '/dev/null'   or die "Can't read /dev/null: $!";
    open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!";
    open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!";
    defined(my $pid = fork)   or die "Can't fork: $!";
    exit if $pid;
    setsid                    or die "Can't start a new session: $!";
    umask 0;
}
#-----------------------------------------------------------------
sub create_graph {
    chomp ( my $rrd_file=shift );
    # rrdtool create $rrd_directory/fan_temp.rrd \
    # --step 1 \		 # 1 sec steps for RRA's blow
    # DS:Temp:GAUGE:10:0:U \	 # DataSource: over max of 10sec, "0" minimum and unknown max value as valid data
    # DS:Speed:GAUGE:10:0:U \	 # DataSource: over max of 10sec, "0" minimum and unknown max value as valid data
    # RRA:AVERAGE:0.5:1:10 \	 # Archive: Average over 1   measurement  (10 sec),  10 values should be stroed
    # RRA:AVERAGE:0.5:6:60 \	 # Archive: Average over 6   measurements (1 min),   60 values should be stroed
    # RRA:AVERAGE:0.5:24:240 \   # Archive: Average over 24  measurements (4 min),  240 values should be stroed
    # RRA:AVERAGE:0.5:288:2880 \ # Archive: Average over 288 measurements (42 min),2880 values should be stroed
    # RRA:MAX:0.5:1:10 \	 # Archive: MAX     over 1   measurements (10 sec),  10 values should be stroed
    # RRA:MAX:0.5:6:60 \	 # Archive: MAX     over 6   measurements (1 min),   60 values should be stroed
    # RRA:MAX:0.5:24:240 \	 # Archive: MAX     over 24  measurements (4 min),  240 values should be stroed
    # RRA:MAX:0.5:288:2880 \	 # Archive: MAX     over 288 measurements (42 min),2880 values should be stroed
    # RRA:LAST:0.5:1:10 \	 # Archive: Last    over 1   measurement  (10 sec),  10 values should be stored
    # RRA:LAST:0.5:6:60 \	 # Archive: MAX     over 6   measurements (1 min),   60 values should be stroed
    # RRA:LAST:0.5:24:240 \	 # Archive: MAX     over 24  measurements (4 min),  240 values should be stroed
    # RRA:LAST:0.5:288:2880 \	 # Archive: MAX     over 288 measurements (42 min),2880 values should be stroed
    system( qq{rrdtool create $rrd_file \\
    	    --step 1  \\
    	    DS:Temp:GAUGE:10:0:U  \\
    	    DS:Speed:GAUGE:10:0:U  \\
    	    RRA:AVERAGE:0.5:1:10 \\
    	    RRA:AVERAGE:0.5:6:60 \\
    	    RRA:AVERAGE:0.5:24:240 \\
    	    RRA:AVERAGE:0.5:288:2880 \\
    	    RRA:MAX:0.5:1:10 \\
    	    RRA:MAX:0.5:6:60 \\
    	    RRA:MAX:0.5:24:240  \\
    	    RRA:MAX:0.5:288:2880 \\
    	    RRA:LAST:0.5:1:10	\\
    	    RRA:LAST:0.5:6:60	\\
    	    RRA:LAST:0.5:24:240   \\
    	    RRA:LAST:0.5:288:2880} );
}
#-----------------------------------------------------------------
sub record_fanspeed{
	my $temp=shift;
	my $speed=shift;
	my $rrd_file=shift ;
	system ( "rrdtool update $rrd_file --template Temp:Speed N:$temp:$speed" );	
}
#-----------------------------------------------------------------
sub graph_fanspeed {
        my $rrd_file=shift;
	my $graph_file_2hr=shift;
	my $graph_file_12hr=shift;
        my $graph_file_1wk=shift;
   #####################################
   # For the graph:
   #  Temp    a=ave   b=max    c=last  
   #  Speed   d=ave   e=max    f=last
   #####################################
   #
   # Draw 2 Hour png
   #
	system("rrdtool", "graph", "/root/rrd/fan_temp_2hr.png",
	         "--imgformat=PNG",
		 "--start=-2880",
		 "-c", "BACK#343435", "-c", "FONT#ffffff", "-c", "CANVAS#605f60",
		 "--title=2 Hour Fanspeed Tmp",
		 "--height=150", "--width=400", 
		 "--vertical-label=Red=degreeC, Yellow=speed",
		 "--step", "10",
		 "DEF:a=$rrd_file:Temp:AVERAGE", 
		 "DEF:b=$rrd_file:Temp:MAX",
		 "DEF:c=$rrd_file:Temp:LAST",
		 "DEF:d=$rrd_file:Speed:AVERAGE",
		 "DEF:e=$rrd_file:Speed:MAX",
		 "DEF:f=$rrd_file:Speed:LAST", 
		 "LINE1:c#ea0e2b:Temp:", 
		   "GPRINT:a:LAST:%6.0lf%s\\r", 
		   "GPRINT:b:LAST:%6.0lf%s\\r",
		   "GPRINT:c:LAST:%6.0lf%s\\r",
		   "COMMENT:\\n",  
		 "LINE1:f#EACC00:Speed:", 
		   "GPRINT:d:LAST:%6.0lf%s\\r",
		   "GPRINT:e:LAST:%6.0lf%s\\r",
		   "GPRINT:f:LAST:%6.0lf%s\\r",
		   "COMMENT:\\n"
	 ); 

   #
   # Draw 12 Hour png
   #
	system ( qw{rrdtool graph $graph_file_12hr \\
	         --imgformat=PNG  \\
		 --start=\'-86400\' \\
		 -c BACK#343435 -c FONT#ffffff -c CANVAS#605f60 \\
		 --title='12 Hour Fanspeed Tmp'  \\
		 --height=150 --width=400 \\
		 --vertical-label='Red=degreeC, Yellow=speed' \\
		 --step 10  \\
		 DEF:a='$rrd_file':Temp:AVERAGE \\
		 DEF:b='$rrd_file':Temp:MAX \\
		 DEF:c='$rrd_file':Temp:LAST \\
		 DEF:d='$rrd_file':Speed:AVERAGE \\
		 DEF:e='$rrd_file':Speed:MAX  \\
		 DEF:f='$rrd_file':Speed:LAST  \\
		 LINE1:c#ea0e2b:'Temp\\:'   \\
		   GPRINT:a:LAST:%6.0lf%s\r \\
		   GPRINT:b:LAST:%6.0lf%s\r  \\
		   GPRINT:c:LAST:%6.0lf%s\r  \\
		   COMMENT:'\\\n'  \\
		 LINE1:f#EACC00:'Speed\\:' \\
		   GPRINT:d:LAST:%6.0lf%s\r  \\
		   GPRINT:e:LAST:%6.0lf%s\r  \\
		   GPRINT:f:LAST:%6.0lf%s\r  \\
		   COMMENT:'\\n'} 
	); 

   #
   # Draw 12 Hour png
   #
	system ( qw{rrdtool graph $graph_file_1wk \\
	            --imgformat=PNG  \\
		    --start='-604800' \\
		    -c BACK#343435 -c FONT#ffffff -c CANVAS#605f60 \\
		    --title='1 Week Fanspeed Tmp'  \\
		    --height=150 --width=400 \\
		    --vertical-label='Red=degreeC, Yellow=speed' \\
		    --step 10  \\
		    DEF:a='$rrd_file':Temp:AVERAGE \\
		    DEF:b='$rrd_file':Temp:MAX \\
		    DEF:c='$rrd_file':Temp:LAST \\
		    DEF:d='$rrd_file':Speed:AVERAGE \\
		    DEF:e='$rrd_file':Speed:MAX    \\
		    DEF:f='$rrd_file':Speed:LAST  \\
		    LINE1:c#ea0e2b:'Temp\\:'   \\
		      GPRINT:a:LAST:%6.0lf%s\r \\
		      GPRINT:b:LAST:%6.0lf%s\r  \\
		      GPRINT:c:LAST:%6.0lf%s\r  \\
		      COMMENT:'\\\n'  \\
		    LINE1:f#EACC00:'Speed\\:' \\
		      GPRINT:d:LAST:%6.0lf%s\r  \\
		      GPRINT:e:LAST:%6.0lf%s\r  \\
		      GPRINT:f:LAST:%6.0lf%s\r  \\
		      COMMENT:'\\n'} 
	); 
}
#-----------------------------------------------------------------
sub update_fanspeed {
    my $NewSpeed=shift;
    open ( FANSPEED, ">>$ProcFile") || die "Cannot read fanspeed file: $?\n";
    print FANSPEED "$NewSpeed";
    close ( FANSPEED ) || die "Cannot close fanspeed file: $?\n";
    return;
}    
#-----------------------------------------------------------------
sub new_fanspeed {
    my $Temp=shift;
    my $Speed=shift;    
    #
    # If temp is over 42, increment fan speed.
    #
    if (  "$Temp" > $TargetTmp_upper ){ unless( $Speed eq 255){ ++$Speed ; } }    
    #
    # If temp is under 42, decrement fan speed.
    #
    if (  $Temp < $TargetTmp_lower ){ unless( $Speed eq 0 ){ --$Speed ; } }
    #
    # Return the new speed
    #
    return ( $Speed );
}
#-----------------------------------------------------------------
sub get_fanspeed {
    open ( FANSPEED, "<$ProcFile") || die "Cannot read fanspeed file: $?\n";
    chomp ( my $Speed=<FANSPEED> );
    close ( FANSPEED ) || die "Cannot close fanspeed file: $?\n";
    return ( $Speed );
}
#-----------------------------------------------------------------
sub get_temp {
    # Process output of `sensors` one line at a time.
    open ( SENSORS, "$sensors |") || die "Cannot run sensors\n";
    while (<SENSORS>){

      ########################################
      #  Screen for relevent sensor data
      #   - If lm_sensors modules are loade incorrectly,
      #     double output of incorrect values result.
      #   - This allows one to specify which to collect
      ########################################
 
      # Start collecting data when this line is reached
      if ( $_ =~ m/$Sensor_string/ ){
    	  $Start="1";
      # Stop Collecting data when this line is reached
      } elsif ( $_ =~ m/^$/ ) {
    	  $Start="0";
    	  done;
      }
      # If Start is 1, we are working with good data
      if ( $Start eq "1" ){
    	#
	# Example string: CPU0 Temp:   +42 C  (low  =    +0 C, high =   +70 C)
    	#
    	$bla=$_;
	# print "$bla";
    	if ( $bla =~ m{
    			  ^CPU0
			  \W*
			  Temp: 	# Starts with temp:
			  \W*           # NonWord characters
    			  \+
    			  (\d+)		# digits are the temp
			  .*            # Anything up to
    			  \n		# new line
    		      }xig		# allow comments, case insensetive, global
           ) { 
	       #
	       # Debug: Print the captured value
	       #
	       if ( $debug eq "0" ){  print "CPU Tmep:\t$1\n"; }
	       # END of SENSORS data
               close ( SENSORS );
	       return ($1);
	   }
      } 
    }
    # Should never get here.
    close ( SENSORS );
    return (0);
}
#-----------------------------------------------------------------