You are on page 1of 3

PROGRAMMING Perl: Uninterruptible Power Supply

Power through power outages

PROLONGED LIFE

An uninterruptible power supply can help get you through a short power outage without los-

ELEN, fotolia
ing data or damaging hardware. A Nagios script written in Perl checks UPS health and initi-
ates a controlled powerdown if the unit exhausts its battery capacity. BY MICHAEL SCHILLI

W
hile going through my drawers tems and a daemon to communicate it into the first serial jack, /dev/ttyS0
full of old computer hardware, with the UPS unit through the drivers. would have been the port.
I found a cheap, old, uninter- Installing the NUT software was a
ruptible power supply (UPS). I must breeze; the documentation that came Limit Access
have bought it because it was on sale, with the distribution is stellar. After The daemon configuration file upsd.conf
since the “Cyberpower 325SL” only pro- compiling and running make install, defines rules on who can access the UPS
vides 185 watts for about five minutes. three configuration files must be created. data from the NUT daemon (Figure 3). I
But I figured that’s good enough for First, the ups.conf file sets the parame- opened the file for my PC’s static IP ad-
helping a desktop PC, a DSL modem, ters for the UPS used (Figure 2). In my dress, and the /32 at the end defines that
and a router go through a short power case, I chose the genericups driver, only status data can be read.
outage unharmed. which works with cheap UPS units and For home use, defining user-based ac-
just provides basic online/offline status cess via upsd.users is probably overkill,
Send Like It’s 1999 without fancy UPS stats or battery ca- but the file needs to be there, so an
The UPS features a serial interface jack pacity left. Looking at the driver docu- empty file will do.
(Figure 1) that can be connected to a PC mentation revealed that, for CyberPower You could define a new user “nut”
with a serial cable. That’s what I call units, “type 7” has to be used. I called with an associated group, but I decided
retro! The unit also came with Windows- the device “elcheapo,” and that’s how it to let the daemon run as the default user
only software that I remember discard- is going to be referenced later on when nobody, on whose behalf we need to cre-
ing way back, right after opening the its status is checked. ate a state directory:
package. When searching the web, how- Because I plugged the serial cable into
ever, I found the NUT project [1], which the second serial port of my PC, the con- # mkdir /var/state/ups
offers drivers for all kinds of UPS sys- figured port is /dev/ttyS1. Had I plugged # chown nobody /var/state/ups

74 ISSUE 80 JULY 2007 W W W. L I N U X - M A G A Z I N E . C O M


Perl: Uninterruptible Power Supply PROGRAMMING

Figure 2: UPS configuration in /usr/local/


ups/etc/ups.conf.

Figure 1: The UPS system with two power plugs on top and one serial cable plugged in on the
right. The “Kill-A-Watt” meter indicates that PC, DSL modem, and router combined are using
about 114 watts.
Figure 3: NUT daemon configuration in /usr/
# chmod 700 /var/state/ups above upsc call will return OB instead of local/ups/etc/upsd.conf.
returning OL.
Next, the driver daemon and then the goes well, the script prints UPS OK - OL
NUT daemon must be started as root: Over in Nagios Land and returns an exit code of 0. If the UPS
How should you monitor the UPS? Regu- is on battery power, the script returns
# /usr/local/ups/bin/U lar readers will remember that I’ve UPS CRITICAL - OB and exits with exit
upsdrvctl start talked about Nagios in this column be- code 2 to tell Nagios about the problem.
# /usr/local/ups/sbin/upsd fore [2]. Nagios watches over all kinds
of systems in my home, including room And … Action!
If the output from these commands indi- temperature, hard-disk capacity, and the Nagios follows the notion of “soft” and
cates success, a quick test with the upsc performance of the hosting service I’m “hard” status changes. If a check indi-
utility (which comes with NUT) will re- using for my websites. So, I decided to cates a critical condition for the first time
veal that the UPS is online, drawing juice add a UPS watcher as just another Nag- but the parameter max_check_attempts
from the power outlet: ios task to my existing setup (Figure 4). is set to 3, Nagios makes a note of the
The script in Listing 1, check_myups, problem but sets the status to SOFT first.
$ upsc elcheapo@localhostU uses the upsc utility mentioned above to When subsequent checks retry_check_
ups.status query the UPS status but adds a wrapper interval seconds later also fail and max_
OL so that the script can be used as a Nag- check_attempts is finally reached, the
ios plugin. It uses a few extra Perl mod- status is set to HARD and the notifica-
When unplugging the UPS so that it ules, which can be downloaded from tion mechanisms kick in. It’s possible
powers the PC from its battery, the CPAN. If the UPS is up and the check to configure emails to be sent out to

Listing 1: check_myups
01 #!/usr/bin/perl 13 help_subref => sub { 24
02 ############################# 14 print "usage: $0\n"; 25 if ($data eq "OB") {
03 # check_myups 15 }, 26 $status = "critical";
04 # Mike Schilli, 2007 16 version => $version, 27 }
05 ############################# 17 mandatory_args => [], 28
06 use strict; 18 ); 29 print "UPS ", uc($status),
07 use Log::Log4perl qw(:easy); 19 30 " - $data\n";
08 use Nagios::Clientstatus; 20 my $data = `upsc elcheapo\ 31
09 @localhost ups.status`; 32 exit $ncli->exitvalue(
10 my $version = "0.01"; 21 33 $status);
11 my $ncli = 22 chomp $data;

12 Nagios::Clientstatus->new( 23 my $status = "ok";

W W W. L I N U X - M A G A Z I N E . C O M ISSUE 80 JULY 2007 75


PROGRAMMING Perl: Uninterruptible Power Supply

provide a rude awakening to the system


administrator on call.
Nagios also allows you to initiate ac-
tions when status changes occur. This
way, scripts can try to fix the problem, Figure 5: Nagios shows that the UPS is running on battery power.
and if the solution is as simple as restart-
ing a web server, it’s probably a good But be careful, Nagios calls the script out having to type a password. Both
idea to do that instead of bothering a defined with the event handler directive scripts, check_myups and powerdown,
system administrator. In the case of a with every status change: first, when the have to be installed in the Nagios plugin
UPS at home running out of battery status changes from OK to CRITICAL/ directory, /usr/local/nagios/libexec.
power, we just want the Linux system to SOFT, then when it changes from CRITI- When the changes to the Nagios config-
shut itself down properly to avoid a hard CAL/SOFT to CRITICAL/HARD, and fi- uration have been made, Nagios needs
landing. The event handler in Listing 2, nally after it recovers from CRITICAL to be restarted.
powerdown, does exactly that. HARD to OK. Now you'll be ready when the next
The powerdown script, which gets power outage comes! ■
the status information that is passed in,
makes sure that a poweroff of the ma- INFO
chine only happens in case a critical
[1] Network UPS Tools (NUT):
hard state is encountered and ignores
http://www.networkupstools.org/
all other requests.
[2] “The Watcher” by Michael Schilli.
Per the configuration in Figure 4, Nag-
Linux Magazine, June 2006:
ios passes in the two variables SERVIC-
http://www.linux-magazine.com/
ESTATE (ok/critical) and SERVICESTA- issue/67/Perl_Nagios_Plugins.pdf
TETYPE (soft/hard) so powerdown can
[3] Turnbull, James. Pro Nagios 2.0.
make an informed decision.
Apress, 2006.
If I’m out of battery power, the event
[4] Listings for this article:
handler will want to run the Linux pow-
http://www.linux-magazine.com/
eroff script, but only root can do that. To
Magazine/Downloads/80
make sure that the nagios user running
the Nagios application has permission to
do that, the following entry is added to Michael Schilli works
as a Software Devel-
the sudoers file:
THE AUTHOR

oper at Yahoo!,
Sunnyvale, Califor-
# /etc/sudoers nia. He wrote “Perl
nagios ALL= NOPASSWD:U Power” for Addison-
/usr/bin/poweroff Wesley and can be
contacted at mschilli@perlmeister.
com. His homepage is at
Figure 4: Nagios configuration for the UPS With this setting, the nagios user can
http://perlmeister.com.
check and its powerdown event handler. run sudo /usr/bin/poweroff as root with-

Listing 2: powerdown
01 #!/usr/bin/perl -w 15 29 exit 0;
02 ############################# 16 my ($state, $softhard) = 30 }
03 # powerdown event handler 17 @ARGV; 31
04 # Mike Schilli, 2007 18 32 if ($softhard eq "SOFT") {
05 ############################# 19 LOGDIE 33 DEBUG "Ignoring soft mode";
06 use strict; 20 "usage: $0 state SOFT|HARD" 34 exit 0;
07 use Sysadm::Install qw(:all); 21 if !$softhard 35 }
08 use Log::Log4perl qw(:easy); 22 or $softhard !~ /SOFT|HARD/; 36
09 23 37 # Shut PC off
10 Log::Log4perl->easy_init({ 24 DEBUG 38 INFO "Shutting down";
11 file => 25 "Called $0 $state $softhard"; 39 tap("sudo",
12 ">>/tmp/powerdown.log", 26 40 "/usr/bin/poweroff");
13 level => $DEBUG 27 if ($state eq "OK") {
14 }); 28 DEBUG "Ignoring OK";

76 ISSUE 80 JULY 2007 W W W. L I N U X - M A G A Z I N E . C O M

You might also like