#!/usr/bin/perl

use strict;
use Net::SNMP;

my $TIMEOUT = 30;
$SIG{ALRM} = sub { print "ERROR: No response\n"; exit 3; };
alarm($TIMEOUT);

my $debug = 0;

my %ups_oids = (
#default
'_default'=>'.1.3.6.1.2.1.33.1.6.3.2',
#apc ?
'apc'=>'.1.3.6.1.4.1.318.1.1.1.4.1.1',
#eaton
'eaton'=>'.1.3.6.1.4.1.534.1.4.5.0',
);

my $res_state = {
'apc' =>{
    '1' =>'ERROR Current APC status is  unknown(1)',
    '2' =>'OK Current APC status is  onLine(2)',
    '3' =>'WARNING Current APC status is  onBattery(3)',
    '4' =>'OK Current APC status is  onSmartBoost(4)',
    '5' =>'WARNING Current APC status is  timedSleeping(5)',
    '6' =>'WARNING Current APC status is  softwareBypass(6)',
    '7' =>'ERROR Current APC status is  off(7)',
    '8' =>'WARNING Current APC status is  rebooting(8)',
    '9' =>'WARNING Current APC status is  switchedBypass(9)',
    '10' =>'ERROR Current APC status is  hardwareFailureBypass(10)',
    '11' =>'WARNING Current APC status is  sleepingUntilPowerReturn(11)'
    },
'eaton' => {
    '1' => 'UNKNOWN State: other',
    '2' => 'OK Offline mode: Load not powered',
    '3' => 'OK State normal',
    '4' => 'WARNING On bypass',
    '5' => 'WARNING On battery',
    '6' => 'OK Battery booster',
    '7' => 'OK Battery reducer',
    '8' => 'WARNING parallelCapacity',
    '9' => 'WARNING parallelRedundant',
    '10'=> 'OK highEfficiencyMode',
    }
};

my $res_retcode = {
'apc'=>{
    '1' =>'2',
    '2' =>'0',
    '3' =>'1',
    '4' =>'0',
    '5' =>'1',
    '6' =>'1',
    '7' =>'2',
    '8' =>'1',
    '9' =>'1',
    '10' =>'2',
    '11' =>'1'
    },
'eaton'=>{
    '1' =>'3',
    '2' =>'0',
    '3' =>'0',
    '4' =>'1',
    '5' =>'1',
    '6' =>'0',
    '7' =>'0',
    '8' =>'1',
    '9' =>'1',
    '10' =>'0',
    }
};

exit if (!$ARGV[0]);

my $hostip=$ARGV[0];

my ($session, $error) = Net::SNMP->session(
   -hostname  => shift || $hostip,
   -community => shift || 'public',
   -port      => shift || '161',
   -timeout   => 5,
   -version   => shift || '1',
);

if (!defined($session)) { printf("ERROR: %s.\n", $error); exit 1; }

my %result;
foreach my $key (sort keys %ups_oids) {
my $key_oid = $ups_oids{$key};
my $ret = $session->get_request( -varbindlist => [$key_oid] );

my $value;
if (!$ret) {
    #search in subtree
    $ret = $session->get_next_request( -varbindlist => [$key_oid] );
    my @keys_next = keys %$ret;
    if (scalar @keys_next and $keys_next[0]) {
        my $get_key = $keys_next[0];
        if ($get_key=~/^$key_oid/) {
            $value = $ret->{$get_key};
            print STDERR "Get-Next for key $key_oid: $get_key => $value\n" if ($debug);
            }
        }
    } else {
    $value = $ret->{$key_oid};
    print STDERR "Get: $key_oid => $value\n" if ($debug);
    }
next if (!defined($value));
$result{$key_oid}{value}=$value;
$result{$key_oid}{vendor}=$key;
last;
}

$session->close;

if (!%result) { printf("OK: Unknown model. \n"); exit 0; }

my $result_ok = 0;
foreach my $key (keys %result) {
next if (!$key);
my $return_value = $result{$key}{value};
next if (!defined($return_value));
$result_ok = 1;
#apc
if ($result{$key}{vendor} eq 'apc') {
    print($res_state->{apc}->{$return_value}."\n");
    exit $res_retcode->{apc}->{$return_value};
    }
#default
if ($result{$key}{vendor} eq '_default') {
    printf("ERROR: Alarm OnBattery detected! %s\n", $return_value);
    exit 2;
    }
#eaton
if ($result{$key}{vendor} eq 'eaton') {
    print($res_state->{eaton}->{$return_value}."\n");
    exit $res_retcode->{eaton}->{$return_value};
    }
}

printf("OK Alarm OnBattery not found.\n\n");
exit 0;
