#!@@PERL@@ -w
# -*- perl -*-
#
# Munin plugin to monitor hdd temperature from a hddtemp daemon.
#
# This plugin is an alternative to the hddtemp_smartctl, which is the 
# preferred one.
#
# Author: Stein Magnus Jodal <jodal at users.sourceforge.net>
#
# Depends on `hddtemp` <http://coredump.free.fr/linux/hddtemp.php> by
# Emmanuel Varagnat <coredump@free.fr> running as a daemon.
#
# If fetching temp from another machine, remember to bind hddtempd to the right
# interface. Loopback only is default.
#
# Parameters understood:
#
# 	host   - Change which host to graph (default localhost)
# 	port   - Change which port to connect to (default 7634)
# 	scale  - C for Celsius, F for Farenheit (default C)
#
# This plugin is based on the apt plugin.
#
#
# Usage: place in /etc/munin/node.d/ (or link it there using ln -s)
#
# Parameters understood:
# 	config   (required)
# 	autoconf (optional - used by munin-config)
#
#
# v1.2 2004-06-07
#  - Renamed to hddtempd
#  - Now more generic, not only localhost
# v1.1 2004-05-23
#  - Fixed support for multiple disks
# v1.0 2004-05-17
#  - Initial version
#
#
# Magic markers - optional - used by installation scripts and
# munin-config:
#
#%# family=contrib
#%# capabilities=autoconf

use strict;
use IO::Socket::INET;

# Config
our $address = $ENV{host}  || "localhost";	# Default: localhost
our $port    = $ENV{port}  || 7634;		# Default: 7634
our $scale   = $ENV{scale} || "C";		# C (celcius) or F (fahrenheit)

# Don't edit below this line

if ($ARGV[0] and $ARGV[0] eq "autoconf") {
	# Try to connect to the daemon
	my $socket = IO::Socket::INET->new("$address:$port")
		or my $failed = 1;

	if ($failed) {
		print "no (failed to connect to $address port $port)\n";
		exit 0;
	} else {
		print "yes\n";
		exit 0;
	}
}

if ($ARGV[0] and $ARGV[0] eq "config") {
        print "graph_title HDD temperature\n";
	print "graph_args --base 1000 -l 0\n";
	print "graph_vlabel Degrees $scale\n";

	my @data = get_data();

	for my $this (@data) {
		print "${$this}[0].label ";
		${$this}[0] =~ tr#_#/#;
		print "${$this}[0]\n";
	}
	
        exit 0;
}

my @data = get_data();

for my $this (@data) {
	# device.value temp
	print "${$this}[0].value ${$this}[2]\n";
}

# Connect to hddtemp daemon and collect data from it
sub get_data {
	my($socket, @raw, @data);

	# Connect to the hddtemp daemon
	$socket = IO::Socket::INET->new("$address:$port")
		or die("Couldn't connect to $address port $port: $!");

	# Read data and split into an array
	@raw = split(/\|/, <$socket>);

	# Parse data
	for (my $i = 1; $i < scalar @raw; $i+=5) {
		my @this = @raw[$i..$i+3];

		# Remove /dev/-prefix on device
		#$this[0] =~ s#.*/([^/]+)#$1#;

		# Or, replace / with _
		$this[0] =~ tr#/#_#;

		# Adjust temp to the right scale
		if ($scale eq "C" and $this[3] eq "F") {
			# Convert from F to C
			$this[2] = (5/9) * ($this[2] - 32);
		} elsif ($scale eq "F" and $this[3] eq "C") {
			# Convert from C to F
			$this[2] = (9/5) * $this[2] + 32;
		}

		# Put @this into @data
		push @data, [ @this ];
	}

	close($socket);

	return @data;
}

# vim:syntax=perl
