All pastes #747335 Raw Edit

Something

public text v1 · immutable
·published 2007-10-23 22: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 ( qq{rrdtool graph $graph_file_2hr \\
                 --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 ( qq{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 ( qq{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);
}
#-----------------------------------------------------------------