#!/usr/bin/perl

# title:  ilm_sensors.pl
# author: John Stile <jstile@stilen.com>
# version: 0.02
#
# desc:   use to make lm_sensors metrics available to ganglia
#

########################################## 
#            Set executable paths
##########################################
$modprobe="/sbin/modprobe";             # modprobe binary 
$lsmod="/sbin/lsmod";                   # lsmod binary
$sensors="/usr/bin/sensors";            # Sensors binary
$gmetric_bin="/usr/bin/gmetric";        # Ganglia Gmetric binary

##########################################
#            Set Sensors and Ganglia
##########################################
if ( `hostname` =~ m/deathstar/){

  print "hostname:\tdeathstar\n";
  # MotherBoard:  Tyan 7
  # Chipset:      WindBond W83627HF-AW
  $Module_base="i2c-amd756";             # Mother board i2c
  $Module_sensor="w83781d";              # Sensor chip i2c
  $Sensor_string="w83782d-i2c-0-2d";                     # Header in sensors output
  $Module_sensor_Options="init=0 force_subclients=0,0x2c,0x4a,0x4b";
  $mcast_if="eth0";                       # Nic
  $mcast_channel="239.2.11.71";           # Multicast Channel
  $mcast_port="8649";                     # Multicast Port

} elsif ( `hostname` =~ m/daman/){

  print "hostname:\tdaman\n";
  # MotherBoard: IWill K7S5A
  # Chipset:      SiS735
  $Module_base="i2c-proc i2c-core";  
  $Module_sensor="sis5595";             
  $Sensor_string="sis5595-isa-8088"; 
  $Module_sensor_Options="";          
  $mcast_if="eth0";                       # Nic
  $mcast_channel="239.2.11.71";           # Multicast Channel
  $mcast_port="8649";                     # Multicast Port

} elsif ( `hostname` =~ m/webber/ ){
  
  print "hostname:\twebber\n";
  # MotherBoard:  Intel ??? 
  # Chipset:      Windbond W83977EF-AW 
  $Module_base="i2c-proc i2c-core";      
  $Module_sensor="w83781d";             
  $Sensor_string="w83781d-isa-0290";    
  $Module_sensor_Options="";           
  $mcast_if="eth0";                       # Nic
  $mcast_channel="239.2.11.71";           # Multicast Channel
  $mcast_port="8649";
}

##########################################
#            Error Checking
##########################################

# - Unless the module is already loaded, 
#   load it.

unless ( `$lsmod |grep $Module_sensor` ){ 
    system(`$modprobe $Module_base`) || die "Could no load\n";
    system(`$modprobe  $Module_sensor $Module_sensor_Options`) || die "Could no load\n";	
}

# - Check process table for this program. Expect to see on. 
# - Die if there is more than 1 copy of this program running.

$self_count="0"; $total=0;
open ( PROCESSES, "ps -elf |")  || die "Cannot run ps:\t$!\n";
while (<PROCESSES>){
  if ( $_ =~ m/ilm_sensors\.pl/ ){  ++$self_count ; }
}
if  ( "$self_count" > 1 ) { 
  die "Already running ilm_sensors.pl:\t$!\n"; 
}

# - Check if gmond is runing.
# - Restart gmond if not running correctly (it gets locked some times).
# - Die if it can't be restarted.

open (GMOND, "/etc/init.d/gmond status |") || die "Cannot stat gmond:\t$!\n";
while(<GOND>){ 
  unless ( $_ =~ m/running/ ){ 
    system ( `/etc/init.d/gmond restart` ) || die "Cannot restart gmond:\t$!\n";
 }
}

##########################################
#            Send the Metrics
##########################################

# Declair and set default data.
$Start="0"; @GoodData="";

# 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" ){
    #
    # Temp = Single CPU systems
    #
    $bla=$_;
    if ( $bla =~ m{
                      ^temp:        # Starts with temp:
                      \W*           # NonWord characters
                      ((\d+\.)?\d+) # Copy temp decimal value in $1
                      °C            # Degree Celcius
                      .*            # anything up to
                      \n            # new line
                  }xig              # allow comments, case insensetive, global	
     ) {  
	 print "CPU Tmep:\t$1\n";
	 #system(`logger -i -s -p cron.notice -t "ILM_SENSORS.PL-->" -- "CPU Temp $1 "`);
	 system(`$gmetric_bin -i $mcast_if --mcast_channel=\'$mcast_channel\' --mcast_port=$mcast_port  -t float -n \"CPU Temp\"  --units Celcius -v $1 `);
	 #system(`$gmetric -t float -n \"CPU Temp\"  --units Celcius -v $1 `);
    }
    #
    # Temp1 = CPU1 Temp
    #   
    if ( $bla =~ m{
                      ^temp1:       # Starts with temp1:
                      \W*           # NonWord characters 
                      ((\d+\.)?\d+) # Copy temp decimal value to $1
                      °C            # Degree Celcius
                      .*            # anything up to 
		      \n            # new line 
                  }xig              # allow comments, case insensetive, global	
     ) {    
	 print "CPU1 Temp:\t$1\n";
         # system(`logger -i -s -p cron.notice -t "ILM_SENSORS.PL-->" -- "CPU1 Temp $1 "`);
	 # system(`$gmetric -t float -n \"CPU1 Temp\"  --units Celcius -v $1`);
	 system(`$gmetric_bin -i $mcast_if --mcast_channel=\'$mcast_channel\' --mcast_port=$mcast_port  -t float -n \"CPU1 Temp\"  --units Celcius -v $1 `);
    }
    #
    # Temp2 = Core Temp
    #   
    if ( $bla =~ m{
                      ^temp2:       # Starts with temp2:
                      \W*           # NonWord characters
                      ((\d+\.)?\d+) # Copy temp decimal value to $1
                      °C            # Degree Celcius
                      .*            # anything up to
		      \n            # new line
                  }xig              # allow comments, case insensetive, global	
     ) {
	 print "Core Tmep:\t$1\n";
 	 #system(`logger -i -s -p cron.notice -t "ILM_SENSORS.PL-->" -- " Core Temp: $1 "`);
	 #system(`$gmetric -t float -n \"Core Temp\"  --units Celcius -v $1`);
	 system(`$gmetric_bin -i $mcast_if --mcast_channel=\'$mcast_channel\' --mcast_port=$mcast_port  -t float -n \"Core Temp\"  --units Celcius -v $1 `);
    }
    #
    # Temp3 = CPU2 Temp
    #   
    if ( $bla =~ m{
                      ^temp3:        # Starts with temp3:
                      \W*            # NonWord characters 
                      ((\d+\.)?\d+) # Copy temp decimal value in $1
                      °C             # Degree Celcius
                      .*             # Anything up to
		      \n             # New line
                  }xig               # allow comments, case insensetive, global	
     ) {
	print "CPU2 Tmep:\t$1\n";
 	#system(`logger -i -s -p cron.notice -t "ILM_SENSORS.PL-->" -- "$gmetric -t float -n "CPU2 Temp"  --units Celcius" -v $1`);
	#system(`sh -x $gmetric -t float -n 'CPU2 Temp' --units Celcius -v $1`);
	system(`$gmetric_bin -i $mcast_if --mcast_channel=\'$mcast_channel\' --mcast_port=$mcast_port  -t float -n \"CPU2 Temp\"  --units Celcius -v $1 `);
    }
    #
    # Fan1 = CPU1 Fan
    #   
    if ( $bla =~ m{
                     ^fan1:     # Starts with fan1:
		     \W*        # One or more NonWord characters
		     (\d+)      # Copy speed into $1
		     \W+        # One or more NonWord characters
		     RPM        # RPM
		     .*         # Anything up to 
		     \n         # a new line
                  }xig          # allow comments, case insensetive, global	
     ) {
	print "CPU1 Fan:\t$1\n";
	#system(`logger -i -s -p cron.notice -t "ILM_SENSORS.PL-->" -- "CPU1 Fan  $1 "`);
	system(`$gmetric_bin -i $mcast_if --mcast_channel=\'$mcast_channel\' --mcast_port=$mcast_port -t uint32 -n \"CPU1 Fan" -u RPM -v $1`);
    }
    #
    # Fan2 = CPU2 Fan
    #      
    if ( $bla =~ m{
                     ^fan2:     # Starts with fan2:
		     \W*        # One or more NonWord characters
		     (\d+)      # Copy speed into $1
		     \W+        # One or more NonWord characters 
		     RPM        # RPM
		     .*         # Anything up to
		     \n         # a new line
                  }xig          # allow comments, case insensetive, global	
     ) {
	print "CPU2 Fan:\t$1\n";
	#system(`logger -i -s -p cron.notice -t "ILM_SENSORS.PL-->" -- "CPU2 Fan  $1 "`);
	system(`$gmetric_bin -i $mcast_if --mcast_channel=\'$mcast_channel\' --mcast_port=$mcast_port -t uint32 -n \"CPU2 Fan\" -u \"RPM"\ -v $1`);
    }
    #
    # Fan3 = System fan ? have yet to determin.
    #   
    if ( $bla =~ m{
                     ^fan3:     # Starts with fan3:
		     \W*        # One or more NonWord characters
		     (\d+)      # Copy speed into $1
		     \W+        # One or more NonWord characters
		     RPM        # RPM
		     .*         # Anything up to
		     \n         # a new line 
                  }xig          # allow comments, case insensetive, global	
     ) {
	print "System Fan:\t$1\n";
	#system(`logger -i -s -p cron.notice -t "ILM_SENSORS.PL-->" -- "System Fan $1 "`);
	system(`$gmetric_bin -i $mcast_if --mcast_channel=\'$mcast_channel\' --mcast_port=$mcast_port  -t uint32 -n \"System Fan\" -u "RPM" -v $1`);
     }
  }
   		   
}
# END of SENSORS data
close ( SENSORS );

exit ;
