#!/usr/bin/env perl
# kate: hl perl;

use strict;
use warnings;
use RRDs;

my $admin = 'user@localhost';
my $sender = 'usbtenkimux@localhost';
my $RRD = '/home/user/usbtenki-mux/aggregator/temperatures.rrd';
my $COM = '/home/user/usbtenki-mux/client/usbtenkiget';

my $version = 0.3;
my $interval = 60;
my $debug = 0;
my $sendmail = '/usr/sbin/sendmail';
my @channels = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);

my $is = join(',', @channels);
my $ss = '';
foreach my $c (@channels) {
	$ss .= ':' if ($ss);
	$ss .= 's'.($c+1);
}
my $GETTEMP = "$COM -i$is -TF";
my $RESET = "$COM -r";
my $maxnums = $#channels+1;
my $hasReset = 0;
my %deadChannels = ();
my $hasRrdErr = 0;

while (1) {
	sleep $interval - (time % $interval);
	my $time = time;
	$time -= ($time % $interval);
	my $isFirst = 1;
	while (1) {
		my $nums = `$GETTEMP`;
		chomp $nums;
		my @data = split(/\s*,\s*/, $nums);
		if ($#data != $maxnums-1) {
			if ($isFirst) {
				# try resetting
				system($RESET);
				$isFirst = 0;
				if (!$hasReset) {
					# send an email if this just started
					&sendEmail("Failed to get $maxnums numbers from [$nums] just reset.\n");
				}
				next;
			}
			if (!$hasReset) {
				$hasReset = 1;
				&sendEmail("Failed to get $maxnums numbers from [$nums] resetting failed\n");
			}
			last;
		}
		if ($hasReset) {
			$hasReset = 0;
			&sendEmail("Succeeded to get $maxnums numbers from [$nums] again\n");
		}
		my $dataLine = $time;
		my $i = 0;
		my $errors = '';
		my $repairs = '';
		my $couldReset = 0;
		foreach my $num (@data) {
			$i++;
			unless ( $num =~ m/^\d+\.\d+$/ ) {
				unless (defined($deadChannels{$i})) {
					$deadChannels{$i} = 1;
					$errors .= "Channel $i was invalid [$num]\n";
				}
				$dataLine .= ':U';
				$couldReset = 1;
				next;
			} elsif (defined($deadChannels{$i})) {
				$repairs .= "Channel $i was valid again [$num]\n";
				delete($deadChannels{$i});
			}
			$dataLine .= ":$num";
		}
		if ($repairs) {
			&sendEmail("$repairs");
		}
		if ($couldReset) {
			if ($isFirst) {
				# try resetting
				system($RESET);
				$isFirst = 0;
				if ($errors) {
					&sendEmail($errors);
				}
				next;
			}
		}
		print "$dataLine\n" if ($debug);
		RRDs::update ($RRD, "--template", $ss,
#					  "s1:s2:s3:s4:s5:s6:s7:s8:s9:s11:s12:s13:s14:s15:s16",
					$dataLine);
		my $ERR=RRDs::error;
		if ($ERR) {
			unless ($hasRrdErr) {
				&sendEmail("ERROR while updating $RRD: $ERR\n");
				$hasRrdErr = 1;
			}
		} elsif ($hasRrdErr) {
			&sendEmail("RRD ERROR resolved again\n");
			$hasRrdErr = 0;
		}
		last;
	}
};

#
# Send email to admin
#
sub sendEmail
{
	my $data = shift;
#	print "$data\n"; return;
    open (OUT ,"| $sendmail -t -oi") or print "Couldn't talk to sendmail because $!\n";
    print OUT <<EOF ;
To: $admin
From: $sender
Subject: usbtenki-mux error
$data
EOF
	close OUT;
}

