#!/usr/bin/perl
# update-envirosnmp, Boone, 04/02/09
# Update environsnmp RRD databases with current observations
#
# Modifications:
# 04/02/09 Boone      Initial coding
# 12/02/09 Boone      MIB path seems to have changed in some underlying
#                     SNMP kit
# End Modifications

# Libraries

	use SNMP;

# Initialize

	$configfile = shift || "/etc/envirosnmp.cf";
	$rrddir = "/matrix/data/envirosnmp";

	$varlist{apcups} =
	{
		inlinevoltage => "upsAdvInputLineVoltage.0",
		inlinefreq => "upsAdvInputFrequency.0",
		outlinevoltage => "upsAdvOutputVoltage.0",
		outlinecurrent => "upsAdvOutputCurrent.0",
		outlineload => "upsAdvOutputLoad.0",
		batterycap => "upsAdvBatteryCapacity.0",
		batteryruntime => "upsAdvBatteryRunTimeRemaining.0",
	};

	$varlist{liebertac} =
	{
		roomrelhumidity => "lgpEnvHumidityMeasurementRel.1",
		roomtemperature => "lgpEnvTemperatureMeasurementDegF.1",
	};

	$fixups{apcups} =
	{
		batteryruntime => sub { $v = shift; return $v / 6000; },
	};

	$SNMP::debugging = 0;
	$SNMP::use_enums = 1;
	$SNMP::use_long_names = 0;
	&SNMP::addMibDirs("/usr/share/snmp/mibs", "/usr/share/mibs")
	&SNMP::loadModules("PowerNet-MIB");
	&SNMP::loadModules("LIEBERT-GP-REGISTRATION-MIB");
	&SNMP::loadModules("LIEBERT-GP-CONDITIONS-MIB");
	&SNMP::loadModules("LIEBERT-GP-AGENT-MIB");
	&SNMP::loadModules("LIEBERT-GP-ENVIRONMENTAL-MIB");
	&SNMP::loadModules("LIEBERT-GP-NOTIFICATIONS-MIB");
	&SNMP::loadModules("LIEBERT-GP-CONTROLLER-MIB");
	&SNMP::loadModules("LIEBERT-GP-POWER-MIB");
	&SNMP::loadModules("LIEBERT-GP-SYSTEM-MIB");
	&SNMP::initMib();

# Config file

	&debug("parsing config");
	open(CFG, $configfile) ||
		die "unable to open $configfile: $!";
	while (<CFG>)
	{
		s/#.*$//;
		s/\s+/ /g;
		s/^\s+|\s+$//;
		next if (/^$/);
		($verb, $parm) = split(/ /);

		if		($verb eq "community")
		{
			$community = $parm;
		}
		elsif	($verb eq "apcups")
		{
			push(@target, { type => "apcups", name => $parm });
		}
		elsif	($verb eq "liebertac")
		{
			push(@target, { type => "liebertac", name => $parm });
		}
		elsif	($verb eq "graphdir")
		{
			next;
		}
		else
		{
			die "unrecognized config file directive $verb";
		}
	}
	close(CFG);

# Get the data

	&debug("fetching data");
	foreach $ref (@target)
	{
		$host = $ref -> {name};
		&debug("\thost $host");
		$type = $ref -> {type};
		$sess = new SNMP::Session(DestHost => $host, Community => $community,
			Version => 1) ||
			die "new session failed: " . $sess -> {ErrorStr};
		$vref = $varlist{$type};
		foreach $var (keys(%$vref))
		{
			&debug("\t\tvar $var");
			$value = $sess -> get($vref -> {$var});
			if ($sess -> {ErrorStr})
			{
				warn "host $host var $var get failed: " . $sess -> {ErrorStr};
			}
			else
			{
				&debug("pre fixup value $value");
				if ($fixups{$type}{$var})
				{
					$subref = $fixups{$type}{$var};
					$value = &$subref($value);
					&debug("post fixup value $value");
				}
				$result{$host}{$var} = $value;
				&debug("\t\t\tval $value\n");
			}
		}
	}

# Run the updates

	&debug("updating rrds");
	foreach $ref (@target)
	{
		$host = $ref -> {name};
		&debug("\thost $host");
		$type = $ref -> {type};
		$rrdfile = $host . "_" . $type . ".rrd";
		$cmdhead = "rrdtool update ${rrddir}/${rrdfile} -t ";
		$template = "";
		$cmdtail = "N";
		$vref = $result{$host};
		foreach $var (keys(%$vref))
		{
			&debug("\t\tvar $var");
			if ($template) { $template .= ":"; }
			$template .= $var;
			$cmdtail .= ":" . $result{$host}{$var};
		}
		&debug("\t\tcommand $cmdhead $template $cmdtail");
		system("$cmdhead $template $cmdtail");
	}

# Done

	exit(0);

# Subs

	sub debug
	{
		my $s = shift;

		if ($SNMP::debugging)
		{
			print STDERR $s, "\n";
		}
	}

__END__
