#!/usr/bin/perl -w
our $VERSION = '0.1.0';

# Global Modules
use strict;
use FindBin;
use Socket;
use lib "$FindBin::Bin";
use IPC::Open3;
use POSIX qw/ strftime /;
#use Hobbit;
use vars qw(%g);

# -f or --fahrenheit      Show temperatures in degrees fahrenheit
my @values = `/usr/bin/sensors -A`;

$ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin';
$ENV{'LC_ALL'} = 'C';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

%g = (
		'fan'        => {},
		'volts'      => {},
		'temp'       => {},
		'tempU'      => "",
		'status'     => "green",
		'dateformat' => { 'default' => ( defined $ENV{'BBDATEFORMAT'} and $ENV{'BBDATEFORMAT'} ne '' ) ? $ENV{'BBDATEFORMAT'} : '',
		                 'regex' => '.+',
                         'set'   => 0,
                         'case'  => 1 },
         'dispserv' => { 'default' => ( defined $ENV{'BBDISP'} and $ENV{BBDISP} ne '' ) ? $ENV{'BBDISP'} : 'localhost'},
         'dispport' => { 'default' => ( defined $ENV{'BBPORT'} and $ENV{'BBPORT'} ne '' ) ? $ENV{'BBPORT'} : 1984}
		);
		
sub send_msgs {
	my @msg = @_;
    # Determine the address we are connecting to
    my $host = $g{'dispserv'}{'default'};
    my $addr = inet_aton($host)
      or print "temperature.pm: Can't resolve display server $host ($!)" and return;
    my $p_addr = sockaddr_in( $g{'dispport'}{'default'}, $addr );


 

	# Open our socket to the host
	socket( SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp') )
	  or print  "temperature.pm: Failed to create socket ($!)" and
		return;
	if ( !connect( SOCK, $p_addr ) ) {
		print  "temperature.pm: Can't connect to display server $host ($!)";

		close SOCK;
		return;
	}

	# Tell the display server that we are sending a combo msg
	print SOCK "combo\n";

	# Now print to this socket until we hit the max msg size

	# Make sure this is a valid message
	if ( ! defined(@msg) or @msg eq '' ) {
		print "temperature.pm: No valid message";
		close SOCK;
		return;
	}

	#print @msg;
	
	print SOCK "@msg\n";

	close SOCK;

}		
#
#
# main
#
#
		
#my $bb = new Hobbit('temperature');

my $cpu       = 0;
my $header    = 0;
my $fheader   = 0;
my $vheader   = 0;
my $bogus_max = 21;

# collect data
foreach my $line (@values) {
	$line =~ /^\S+/ or next;
	next if $line =~ /^coretemp-isa|^adt[0-9]*|^nouveau-pci|^i5k_amb-isa-0000|^temp3/;
	my ( $probe, $rest) = split(":",$line);
	$rest =~ s/^\s+//;
	if ( $probe =~ /^Core|DIMM|temp1|M\/B/ ) {
		# Temperatures
		(my $reading = $rest) =~ s/^([-\+]\d+?\.\d+?).+$/$1/;
		$reading =~ s/[\+]//;
		chomp($reading);
		$rest =~ s/^[-\+]\d+?\.\d+?(.+$)/$1/;
		(my $max_warn = $rest) =~ s/^.*high[ ]*=[ ]*[+-]*(\d+\.\d+).*$/$1/;
		chomp($max_warn);
		if ( $g{'tempU'} !~ m/[CF]/) {
			if ($rest =~ m/\d+..C/) {
				$g{'tempU'} = 'C';
			} elsif ($rest =~ m/\d+..F/) {
				$g{'tempU'} = 'F';
			}
		}

		if ($probe =~ /^Core/ ) {
			if ( $cpu > 1 ) { $cpu = 0 };
			$probe ="Cpu " . $cpu . " " . $probe;
			$cpu += 1;
		}
		if (exists($g{'temp'}{$probe} ) ) {
			# key exists, gen a different key
			if (exists($g{'temp'}{$probe}{'dup'} )) {
				$g{'temp'}{$probe}{'dup'} += 1;
			} else {
				$g{'temp'}{$probe}{'dup'} = 0;
			}
			if ( $g{'temp'}{$probe}{'dup'} == 0 ) {
					# rename current key
					my $temp1  = $g{'temp'}{$probe}{'reading'};
					my $temp2  = $g{'temp'}{$probe}{'max_warn'};
					my $colour = $g{'temp'}{$probe}{'colour'};
					delete($g{'temp'}{$probe});
					my $temp3 = $probe . "_0";
					$g{'temp'}{$temp3}{'reading'}  = $temp1;
					$g{'temp'}{$temp3}{'max_warn'} = $temp2;
					$g{'temp'}{$temp3}{'colour'}   = $colour;
					$g{'temp'}{$probe}{'dup'} = 0;	
			}
			my $t = $g{'temp'}{$probe}{'dup'} + 1;
			$probe .= "_$t";
		}
			
		$g{'temp'}{$probe}{'reading'}  = $reading;
		$g{'temp'}{$probe}{'max_warn'} = $max_warn;
		if ( $max_warn <= $bogus_max ) {
			$g{'temp'}{$probe}{'colour'} = "&green";
		} elsif ( $reading >= $max_warn) {
			$g{'temp'}{$probe}{'colour'} = "&red";
			if ($g{'status'} !~ m/red/ ) { $g{'status'} = "red" };
		}  else {
			$g{'temp'}{$probe}{'colour'} = "&green";
		}
	} elsif ( $probe =~ /fan/ ) {
		# Fans
		(my $rpm = $rest) =~ s/([0-9.]*).*$/$1/;
		chomp($rpm);
		$g{'fan'}{$probe}{'reading'} = $rpm;
		$g{'fan'}{$probe}{'colour'}  = "&green";
	} elsif ( $rest =~ /[0-9.] V/ ) {
		# Voltages
		(my $reading = $rest)  =~ s/^[-+]?([0-9.]*).*$/$1/;
		(my $max_warn = $rest) =~ s/^.*max[ ]*=[ ]*[+-]*(\d+\.\d+).*$/$1/;
		(my $min = $rest)      =~ s/^.*min[ ]*=[ ]*[+-]*(\d+\.\d+).*$/$1/;
		chomp($reading);
		chomp($max_warn);
		chomp($min);
		$g{'volts'}{$probe}{'reading'}  = $reading;
		$g{'volts'}{$probe}{'max_warn'} = $max_warn;
		$g{'volts'}{$probe}{'min'}      = $min;
		if ( $reading >= $max_warn) {
			$g{'volts'}{$probe}{'colour'} = "&red";
			if ($g{'status'} !~ m/red/ ) { $g{'status'} = "red" };
		} else {
			$g{'volts'}{$probe}{'colour'} = "\&green";
		}
	}
}

my $hostname = $ENV{CLIENTHOSTNAME} || $ENV{MACHINEDOTS} || $ENV{MACHINE} || "unknown";

my $msg = '';
my $now = $g{'dateformat'}{default} ? strftime( $g{'dateformat'}{default}, localtime ) : scalar(localtime);

# output data to xymon
$msg = "status $hostname.motherboard $g{'status'} $now\n\n";

my $www = "";
my $rrd = "";

# first Voltages
$www = "Voltages:\n<table border=1 cellpadding=5>\n<tr><td>Sensor</td><td>V</td><td>Min</td><td>Max</td></tr>\n";

for  my $probe (keys %{$g{'volts'}}  ) {
	$www .= "<tr><td>" . $g{'volts'}{$probe}{'colour'} ." ".  $probe . "</td><td>" . $g{'volts'}{$probe}{'reading'} . "</td><td>" . $g{'volts'}{$probe}{'min'} . "</td><td>" . $g{'volts'}{$probe}{'max_warn'} . "</td></tr>\n";
}

$www .= "</table>\n";
$msg .= $www;

# second fan
$www = "\nFan Status:\n<table border=1 cellpadding=5>\n<tr><td>Fan</td><td>RPM</td></tr>\n";
$rrd = "<!--DEVMON RRD: fan 0 0\nDS:ds0:GAUGE:600:0:U\n";
for  my $probe (sort keys %{$g{'fan'}}  ) {
	$www .= "<tr><td>" . $probe . "</td><td>" . $g{'fan'}{$probe}{'reading'} . "</td></tr>\n";
	$rrd .= $probe . " " . $g{'fan'}{$probe}{'reading'};
}
$www .= "</table>\n";
$rrd .= "-->\n";
$msg .= $www;
# last temperatures
$www = "\nTemperatures:\n<table border=1 cellpadding=5>\n<tr><td>Device</td><td>Temp(" . $g{'tempU'} . ")</td><td>Threshold(" .$g{'tempU'} . ")</td></tr>\n";
$rrd = "<!--DEVMON RRD: temp 0 0\nDS:ds0:GAUGE:600:0:U\n";
for  my $probe (sort keys %{$g{'temp'}}  ) {
	my $temp = $probe;
	if (! defined($g{'temp'}{$probe}{'dup'})) {
		$temp =~ s/[\s*\.\/]//g;
		$temp = "A" . $temp;
		$www .= "<tr><td>" . $g{'temp'}{$probe}{'colour'} ." ".  $probe . "</td><td>" . $g{'temp'}{$probe}{'reading'} . "</td><td>" .  $g{'temp'}{$probe}{'max_warn'} . "</td></tr>\n";
		$rrd .= "$temp ";
		$temp = $g{'temp'}{$probe}{'reading'}*9.0/5.0+32.0;
		$rrd .= "$g{'temp'}{$probe}{'reading'}\n"
	}
}

$www .= "</table>\n\n";
$rrd .= "-->\n";
$msg .= $www . $rrd;
send_msgs($msg);

print $msg;

#$ENV{'XYMSRV'}
