diff --git a/apcupsd_pwr b/apcupsd_pwr new file mode 100644 index 0000000..2e4452a --- /dev/null +++ b/apcupsd_pwr @@ -0,0 +1,259 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use Carp; +use Pod::Usage; + +our $APCACCESS = $ENV{apcaccess} || "/sbin/apcaccess"; +our $UPS_MODEL = $ENV{ups_model} || "ES 725"; +our $VERSION = 1.0; +my %Graph; +my %Metric; + +MAIN: { + decide_monitor_type(); + + my $mode = $ARGV[0] || "fetch"; + $mode =~ /^-/ && pod2usage(); + + ### $mode + eval "do_${mode}();" + or croak "do_${mode}: $@"; + + ### end + exit 0; +} + +=begin comment + +pct + LOADPCT is the percentage of load capacity as estimated by the UPS. + 15.0 Percent Load Capacity + BCHARGE is the percentage charge on the batteries. + 100.0 Percent + +volt + LINEV is the current line voltage as returned by the UPS. + 102.0 Volts + BATTV is the battery voltage as supplied by the UPS. + 13.5 Volts + +time + TIMELEFT is the remaining runtime left on batteries as estimated by the UPS. + 38.4 Minutes + +pwr + LOADPCT is the percentage of load capacity as estimated by the UPS. + 15.0 Percent Load Capacity + NOMPOWER + 330 Watts + LOADMETRIC=LOADPCT/100*NOMPOWER gives realtime power consumption in WATTS + +=end comment + +=cut + +sub decide_monitor_type { + my $type = $0 =~ /_pct/ ? "pct" : + $0 =~ /_volt/ ? "volt" : + $0 =~ /_time/ ? "time" : + $0 =~ /_pwr/ ? "pwr" : undef + or croak "unknown monitor type: $0"; + + # common + %Graph = ( + graph_title => "APC Status".($UPS_MODEL?" ($UPS_MODEL)":"")." - ", + graph_category => "sensors", + graph_info => "This graph shows information about your APC UPS", + graph_args => "--base 1000 --lower-limit 0", + ); + + if ($type eq "pct") { + $Graph{graph_title} .= "Percentage"; + $Graph{graph_vlabel} = "%"; + %Metric =( + LOADPCT => { + label => "load capacity pct", + }, + BCHARGE => { + label => "charge on the batteries pct", + }, + ); + } elsif ($type eq "volt") { + $Graph{graph_title} .= "Voltage"; + $Graph{graph_vlabel} = "Volts"; + %Metric =( + LINEV => { + label => "line voltage as returned by the UPS", + }, + BATTV => { + label => "battery voltage as supplied by the UPS", + }, + ); + } elsif ($type eq "time") { + $Graph{graph_title} .= "Time"; + $Graph{graph_vlabel} = "minutes"; + %Metric =( + TIMELEFT => { + label => "remaining runtime left on batteries", + }, + ); + } elsif ($type eq "pwr") { + $Graph{graph_title} .= "Power"; + $Graph{graph_vlabel} = "watts"; + %Metric =( + LOADMETRIC => { + label => "absolute power consumption", + }, + ); + } +} + +sub do_fetch { + ### do_fetch + + my @status_data = retrieve_apcupsd_status() + or croak "failed: retrieve_apcupsd_status"; + ### status_data: \@status_data + + my $status = parse_status_data(@status_data); + ### status: $status + my $prod_status = proccess_status($status); + + my $FIELD; + while (my($field,$attr) = each %Metric) { + $field = lc $field; + $FIELD = uc $field; + printf "%s.value %.1f\n", $field, (exists $status->{$FIELD} ? ($status->{$FIELD} =~ /([\d]+\.?[\d]*)/) : ( exists $prod_status->{$FIELD} ? ( $prod_status->{$FIELD} =~ /([\d]+\.?[\d]*)/) : 0 ) ); + } + + return 1; +} + +sub do_config { + ### do_config + + while (my($k,$v) = each %Graph) { + printf "%s %s\n", $k, $v; + } + while (my($field,$attr) = each %Metric) { + $field = lc $field; + while (my($k,$v) = each %$attr) { + printf "%s.%s %s\n", $field, $k, $v; + } + } + + return 1; +} + +sub do_autoconf { + ### do_config + print "yes\n"; +} + +sub retrieve_apcupsd_status { + open my $apc, '-|', $APCACCESS + or croak $!; + my @status_data = <$apc>; + close $apc; + chomp @status_data; + return @status_data; +} + +sub proccess_status { + my $prod = {}; + my($status) = @_; + + if (exists $status->{NOMPOWER} && exists $status->{LOADPCT}) { + my $pwr_pct = sprintf "%.1f", ($status->{LOADPCT} =~ /([\d]+\.?[\d]*)/) ; + my $nom_pwr = sprintf "%.1f", ($status->{NOMPOWER} =~ /([\d]+\.?[\d]*)/) ; + $prod->{LOADMETRIC} = $pwr_pct/100 * $nom_pwr ; + } + + return $prod; +} + +sub parse_status_data { + my $status = {}; + my($k,$v); + for (@_) { + ($k,$v) = split /\s*:\s*/, $_, 2; + $status->{$k} = $v; + } + return $status; +} + + +__END__ + +=head1 NAME + +B, B, B, B- munin plugin for APC UPS + +=head1 SYNOPSIS + +B [ I|I ] + +B [ I|I ] + +B [ I|I ] + +B [ I|I ] + +=head1 DESCRIPTION + +munin plugin to monitor APC UPS via apcupsd by apcaccess. + +=head1 INSTALLATION + + cp apcupsd_pct $MUNIN_LIBDIR/plugsin/ + + cd YOUR_MUNIN_PLUGINS_DIR + (make symbolic links different name) + ln -s $MUNIN_LIBDIR/plugsin/apcupsd_pct apcupsd_pct + ln -s $MUNIN_LIBDIR/plugsin/apcupsd_pct apcupsd_volt + ln -s $MUNIN_LIBDIR/plugsin/apcupsd_pct apcupsd_time + ln -s $MUNIN_LIBDIR/plugsin/apcupsd_pwr apcupsd_pwr + + restart munin-node + +=head1 REPOSITORY + +L + + git clone git://github.com/hirose31/munin-apcupsd.git + +patches and collaborators are welcome. + +=head1 SEE ALSO + +L + +L, +L + +=head1 AUTHOR + +HIROSE, Masaaki Ehirose31 _at_ gmail.comE + +=head1 CHANGELOG + + * 10/11/2010 - basos - added support for absolute power display + +=head1 COPYRIGHT & LICENSE + +This program is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=cut + +# for Emacsen +# Local Variables: +# mode: cperl +# cperl-indent-level: 4 +# indent-tabs-mode: nil +# coding: utf-8 +# End: + +# vi: set ts=4 sw=4 sts=0 :