All pastes #966497 Raw Edit

Miscellany

public text v1 · immutable
·published 2008-04-01 19:49 UTC
rendered paste body
#!/usr/bin/perl 
#-----------------------------------------------------------------
#
# Title:
#     sensors.rrd.pl
#
# Purpouse: 
#     Chart temp and fan stats
#     Keep fan as slow as possible given safe Target CPU Temp.
#
# To find the correct  settings, run:  pwmconfig
#     9191-0290/fan1_input     current speed: 17307 RPM
#     9191-0290/fan2_input     current speed: 17307 RPM
#     9191-0290/fan3_input     current speed: 15000 RPM
#
# Fan's controlled by: 
#   /sys/devices/platform/i2c-9191/9191-0290/pwm1
#   /sys/devices/platform/i2c-9191/9191-0290/pwm2
#
#-----------------------------------------------------------------
my $debug=          "1";                # debug 1=on, 0=off
my $graph=          "1";                # graph 1=on, 0=off
my $quiet=          "0";                # change fan speed 1=on, 0=off 
my $do_rrd=         "0";                # rrd create/update 1=on, 0=off
my $pause=          "5";                # Time between tests
my $sensors=        "/usr/bin/sensors"; # Binary for sensors
my $Sensor_string=  "w83627hf-isa-0290"; # Header in sensors output
my $time=time(  );
my $Speed1=          "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";
my %stats=(  temp1 => "0",
             temp2 => "0",
	     temp3 => "0",
	     rpm1  => "0",
	     rpm2  => "0",
	     rpm3  => "0"
	   );
#-----------------------------------------------------------------
# flush the buffer
$| = 1;
#-----------------------------------------------------------------
# daemonize the program
if ( $debug eq "0" ){  &daemonize; }
#-----------------------------------------------------------------
# Set initial fan speed to our base
#&update_fanspeed($Speed1);
#-----------------------------------------------------------------
# Main Loop, 
# Runs forever
while ( 1 ){
    if ( $debug eq "1" ){  
        print "Contents of hash before.\n";
        for my $key ( sort ( keys ( %stats ) ) ){
	  print "\t$key:\t$stats{$key}\n";
	}
    }
    #
    # Get temp
    #
    &get_i2c( \%stats ) || die "can't check sensors:\t $!\n";
    if ( $debug eq "1" ){  
        print "Contents of hash after\n";
        for my $key ( sort ( keys ( %stats ) ) ){
	  print "\t$key:\t$stats{$key}\n";
	}
    }

    if ( $quiet eq "1" ){
        #
        # Get speed
        #
        chomp ( $Speed1 = &get_file_fanspeed );
        if ( $debug eq "1" ){  print "Speed:  $Speed1\n"; }
        #
        # Calculate new speed
        #
        my $NewSpeed=&new_fanspeed($Temp,$Speed1);
        if ( $debug eq "1" ){  print "NewSpeed:  $NewSpeed\n"; }
        #
        # If Speed and NewSpeed are not equal, update fan speed file.
        #
            if ( $NewSpeed ne $Speed1 ){ 
                &update_fanspeed($NewSpeed); 
	        if ( $debug eq "1" ){  print "Loading new speed\n"; }
            }
    }
    if ( $do_rrdeq eq "1" ){      
        #
        # Create RRD file, if it does not exist
        #
        if ( ! -e "$rrd_file" ){
    	    &create_graph($rrd_file);  
        };
        #
        # Record Fan speed
        #
        $Rpm=($Rpm/100);
        if ( $debug eq "1" ){  print "$Temp,$Speed1,$Rpm,$rrd_file\n"; }
        my $NewSpeed=&record_fanspeed($Temp,$Speed1,$Rpm,$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
    # DS:Rpm: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 \\
	    DS:Rpm: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 $Speed1=shift;
	my $rpm=shift;
	my $rrd_file=shift ;
	system ( "rrdtool update $rrd_file --template Temp:Speed:Rpm N:$temp:$Speed1:$rpm" );	
}
#-----------------------------------------------------------------
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
   #  Rpm     g=ave   h=max    i=last
   #####################################
   #
   # Draw 2 Hour png
   #
   system(  "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, Blue=rpm",
   	    "--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", 
   	    "DEF:g=$rrd_file:Rpm:AVERAGE",
   	    "DEF:h=$rrd_file:Rpm:MAX",
   	    "DEF:i=$rrd_file:Rpm:LAST", 
   	    "LINE1:c#ea0e2b:Temp\\r:", 
   	      "GPRINT:a:AVERAGE:Average\\t%6.0lf%s\\r", 
   	      "GPRINT:b:MAX:Max\\t%6.0lf%s\\r",
   	      "GPRINT:c:LAST:Last\\t%6.0lf%s\\r",
   	      "COMMENT:\\n",  
   	    "LINE1:f#EACC00:Speed\\r:", 
   	      "GPRINT:d:AVERAGE:Average\\t%6.0lf%s\\r",
   	      "GPRINT:e:MAX:Max\\t%6.0lf%s\\r",
   	      "GPRINT:f:LAST:Last\\t%6.0lf%s\\r",
   	      "COMMENT:\\n",
   	    "LINE1:g#d4dcf8:Rpm\\r:",
   	      "GPRINT:g:AVERAGE:Average\\t%6.0lf%s\\r",
   	      "GPRINT:h:MAX:Max\\t%6.0lf%s\\r",
   	      "GPRINT:i:LAST:Last\\t%6.0lf%s\\r",
   	      "COMMENT:\\n"	      
   );
   #
   # Draw 12 Hour png
   #
   system(  "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, Blue=rpm",
   	    "--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", 
   	    "DEF:g=$rrd_file:Rpm:AVERAGE",
   	    "DEF:h=$rrd_file:Rpm:MAX",
   	    "DEF:i=$rrd_file:Rpm:LAST", 
   	    "LINE1:c#ea0e2b:Temp\\r:", 
   	      "GPRINT:a:AVERAGE:Average\\t%6.0lf%s\\r", 
   	      "GPRINT:b:MAX:Max\\t%6.0lf%s\\r",
   	      "GPRINT:c:LAST:Last\\t%6.0lf%s\\r",
   	      "COMMENT:\\n",  
   	    "LINE1:f#EACC00:Speed\\r:", 
   	      "GPRINT:d:AVERAGE:Average\\t%6.0lf%s\\r",
   	      "GPRINT:e:MAX:Max\\t%6.0lf%s\\r",
   	      "GPRINT:f:LAST:Last\\t%6.0lf%s\\r",
   	      "COMMENT:\\n",
   	    "LINE1:g#d4dcf8:Rpm\\r:",
   	      "GPRINT:g:AVERAGE:Average\\t%6.0lf%s\\r",
   	      "GPRINT:h:MAX:Max\\t%6.0lf%s\\r",
   	      "GPRINT:i:LAST:Last\\t%6.0lf%s\\r",
   	      "COMMENT:\\n"	      
   );

   #
   # Draw 1week png
   #
   system(  "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, Blue=rpm",
   	    "--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", 
   	    "DEF:g=$rrd_file:Rpm:AVERAGE",
   	    "DEF:h=$rrd_file:Rpm:MAX",
   	    "DEF:i=$rrd_file:Rpm:LAST", 
   	    "LINE1:c#ea0e2b:Temp\\r:", 
   	      "GPRINT:a:AVERAGE:Average\\t%6.0lf%s\\r", 
   	      "GPRINT:b:MAX:Max\\t%6.0lf%s\\r",
   	      "GPRINT:c:LAST:Last\\t%6.0lf%s\\r",
   	      "COMMENT:\\n",  
   	    "LINE1:f#EACC00:Speed\\r:", 
   	      "GPRINT:d:AVERAGE:Average\\t%6.0lf%s\\r",
   	      "GPRINT:e:MAX:Max\\t%6.0lf%s\\r",
   	      "GPRINT:f:LAST:Last\\t%6.0lf%s\\r",
   	      "COMMENT:\\n",
   	    "LINE1:g#d4dcf8:Rpm\\r:",
   	      "GPRINT:g:AVERAGE:Average\\t%6.0lf%s\\r",
   	      "GPRINT:h:MAX:Max\\t%6.0lf%s\\r",
   	      "GPRINT:i:LAST:Last\\t%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 $Speed1=shift;    
    #
    # If temp is over 42, increment fan speed.
    #
    if (  "$Temp" > $TargetTmp_upper ){ unless( $Speed1 eq 255){ ++$Speed1 ; } }    
    #
    # If temp is under 42, decrement fan speed.
    #
    if (  $Temp < $TargetTmp_lower ){ unless( $Speed1 eq 0 ){ --$Speed1 ; } }
    #
    # Return the new speed
    #
    return ( $Speed1 );
}
#-----------------------------------------------------------------
sub get_file_fanspeed {
    open ( FANSPEED, "<$ProcFile") || die "Cannot read fanspeed file: $?\n";
    chomp ( my $Speed1=<FANSPEED> );
    close ( FANSPEED ) || die "Cannot close fanspeed file: $?\n";
    return ( $Speed1 );
}
#-----------------------------------------------------------------
sub get_i2c {
    my $stat_ref = $_;
    my $temp1;
    my $temp2;
    my $temp3;
    my $rpm1;
    my $rpm2;
    my $rpm3;
    if ( $debug eq "1" ){  print "Parsing lm_sensors output\n"; }
    # 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" ){
    	#
	# Grab the main 
	#
	$bla=$_;
	# print "$bla";
    	#
	# Example string: temp1:       +18°C  (high =    -1°C, hyst =   -17°C)   sensor = thermistor   ALARM
    	#
    	if ( $bla =~ m{
			  temp1: 	# 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 "1" ){  print "\tTemp1:\t$1\n"; }
	       $temp1="$1";
	   }
    	#
	# Example string: temp2:       +18°C  (high =    -1°C, hyst =   -17°C)   sensor = thermistor   ALARM
    	#
    	if ( $bla =~ m{
			  temp2: 	# 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 "1" ){  print "\tTemp2:\t$1\n"; }
	       $temp2="$1";
	   }
    	#
	# Example string: temp3:       +18°C  (high =    -1°C, hyst =   -17°C)   sensor = thermistor   ALARM
    	#
    	if ( $bla =~ m{
			  temp3: 	# 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 "1" ){  print "\tTemp3:\t$1\n"; }
	       $temp3="$1";
	   }
	#  
        # Example string: fan1:     4528 RPM  (min =  941 RPM, div = 2)
        #
    	if ( $bla =~ m{
    			  ^fan1:        # starts with fan
			  \W*           # NonWord characters
			  (\d+)         # rpm number
			  \W*           # NonWord characters
			  RPM           # text RPM
			  .*            # Anything up to
    			  \n		# new line
    		      }xig		# allow comments, case insensetive, global
           ) { 
	       #
	       # Debug: Print the captured value
	       #
	       if ( $debug eq "1" ){  print "\tFan1:\t$1\n"; }
	       $rpm1="$1";
	   }

	#  
        # Example string: fan2:     4528 RPM  (min =  941 RPM, div = 2)
        #
    	if ( $bla =~ m{
    			  ^fan2:        # starts with fan
			  \W*           # NonWord characters
			  (\d+)         # rpm number
			  \W*           # NonWord characters
			  RPM           # text RPM
			  .*            # Anything up to
    			  \n		# new line
    		      }xig		# allow comments, case insensetive, global
           ) { 
	       #
	       # Debug: Print the captured value
	       #
	       if ( $debug eq "1" ){  print "\tFan2:\t$1\n"; }
	       $rpm2="$1";
	   }
	#  
        # Example string: fan3:     4528 RPM  (min =  941 RPM, div = 2)
        #
    	if ( $bla =~ m{
    			  ^fan3:        # starts with fan
			  \W*           # NonWord characters
			  (\d+)         # rpm number
			  \W*           # NonWord characters
			  RPM           # text RPM
			  .*            # Anything up to
    			  \n		# new line
    		      }xig		# allow comments, case insensetive, global
           ) { 
	       #
	       # Debug: Print the captured value
	       #
	       if ( $debug eq "1" ){  print "\tFan3:\t$1\n"; }
	       $rpm3="$1";
	   }
      } 
    }
    # Should never get here.
    close ( SENSORS );
    if ( 1 ){
        $stats_ref->{temp1} = "$temp1";
        $stats_ref->{temp2} = "$temp2";
	$stats_ref->{temp3} = "$temp3";
	$stats_ref->{rpm1}  = "$rpm1";
	$stats_ref->{rpm2}  = "$rpm2";
	$stats_ref->{rpm3}  = "$rpm3";

        if ( $debug eq "1" ){ 
            print "Contents of hash_reference\n";
	    for my $key ( sort ( keys ( %$stats_ref )) ){
	    print "\t$key:\t$stats_ref->{$key}\n";
	    }
	}
        return ( 1 ) ;
    } else {
        exit 1;
    }  
}
#-----------------------------------------------------------------