A new version of this series has been published. Please refer to the new index for updated articles and ordering. This article is kept for historical reference, but should be considered out of date.
Note: This article is part of a series. See the Index for more information.
Self-promotion: I’ve recorded this series as a screencast for Pluralsight:
If you have a Pluralsight subscription, please consider watching it. Thanks!
Updates: I haven’t had any reports of issues with this post under the Jessie release of Raspbian, so I assume it all still works. I don’t have a spare UPS to test with, though, so unless someone reports an issue under Jessie, I think everything still works.
My previous home “server” before embarking on this series was just an old laptop of mine. It wasn’t particularly strong, but it could run CrashPlan, and serve files. One advantage it had was that, being a laptop, it had a built-in battery and knew how to shut itself down if the power went out. Of course, I had to go downstairs and start it back up once the power was restored, but at least nothing got corrupted.
If you have a desktop computer at home or at work, you may also have an Uninterruptable Power Supply (UPS) under your desk. This is basically a battery big enough to power your computer and monitor long enough for you to save what you are doing and shut down gracefully. Most modern UPS units also have a USB port on them and come with software so that when the power goes out, the UPS can tell the computer to suspend, hibernate, or shut itself down depending on how you’ve configured it.
I’ve had a one of these small UPS units at home for years now, although it hasn’t been running my computer, which is always a laptop anyway. Instead, the UPS is there to keep my overly-sensitive cable modem and network router from getting freaked out by the occasional power glitch. I used to have to reset my router once every couple of weeks, but since I put it on a battery I’ve hardly touched it.
It shouldn’t surprise you that there are UPS options available for the Raspberry Pi as well. Take the CW2 “Pi UPS” (http://www.piups.net), for example. This product will work fine for most simple Raspberry Pi projects running off of an SD card, but my particular installation has a 2TB RAID enclosure hooked up to it. I don’t think AA batteries are going to cut it. What I need is something that will keep the hard drives spinning long enough for the Pi to shut down safely.
I’ve had my Raspberry Pi Home Server plugged into this same UPS for months now, because it makes for a conveniently-placed power strip and evens out the power supply. My UPS is a little older, though, and doesn’t have a USB connection for communicating with the computer attached to it. It does have a serial port, but a few experiments with serial to USB adapters got me nowhere. The level of sophistication on older UPSes (like mine) can be pretty low, and they often use the serial port in a way that doesn’t exactly count as proper serial communication.
With that in mind, I’ve replaced my old UPS with a newer one, specifically a CyberPower SX550G. I chose this model because:
- It has a USB connection to the computer.
- It was on sale for $40.
- I’m cheap.
It’s a 550VA battery backup, which probably wouldn’t get you very far with a full-sized desktop computer, but it should be more than adequate for a Router, a Raspberry Pi, and a couple of drives. It could probably run those devices for a good couple of hours if needed, actually. I haven’t done the math, but if not for the external drives, it could probably run the Pi for days.
So how can we get the Pi to use it intelligently? It certainly didn’t come with a ready-made software package for the Pi, although Linux software is available for it.
Network UPS Tools (NUT)
The Network UPS Tools package, aka “NUT” (http://www.networkupstools.org), is a collection of programs meant to make UPS hardware from different manufacturers work in roughly the same way. It’s available for a wide variety of platforms, one of which happens to be Debian Linux, of which Raspbian is a variant.
NUT consists of three major components
- A software driver to communicate with your particular UPS using whatever protocol it supports, and translate that into a common API.
- A daemon (service) that connects to the driver and acts as a communication hub.
- A client program that can perform various tasks such as shutting down the computer when the power state reported by the server changes.
There are a few other components, such as command-line utilities that can tell you about the current state of the UPS, or allow you to make changes to the UPS configuration. For the most part though, we’re concerned with these three components.
Note: NUT works with a wide range of UPSes, but without owning one from each different manufacturer and/or vintage, I can’t create instructions specific to each model. Questions about how to get NUT working with your particular UPS are best addressed on the project’s own site, or its GitHub site. For the most part, though, they should all work the same way. If your UPS is older, and doesn’t have a USB port, but has a 9-pin serial port, you are totally on your own. Maybe you could hack something together using the GPIO pins. If so, you’re a better man than me.
Installing Network UPS Tools (NUT)
Simplicity itself. Like most things we’ve installed in this series, NUT is available through apt-get
sudo apt-get install nut
Select your driver
Find the driver for your particular UPS by looking at the compatibility list on the NUT site (http://www.networkupstools.org/stable-hcl.html). If you can purchase a UPS that’s on the list, then that’s great. If you don’t find your UPS on the list, that doesn’t mean it won’t work, though. For instance, my new UPS isn’t on the list, but a ton of other devices from the same company are, and they all seem to use the same driver (usbhid-ups). I gave it a shot, and it works just fine. YMMV
Configure the UPS
Once you’ve identified the driver for your UPS, you’ll need to edit the ups configuration file.
sudo nano /etc/nut/ups.conf
This file, like all of the NUT configuration files, is very well documented inline, and explains all of its different options. At the bottom of the file, you’ll add an entry for your UPS. You’ll need to give it a name, specify a driver, and give it a description. There is also an option to specify a port. For units that connect via a USB cable, this is meaningless, but it’s still required, so use the value “auto”.
[RPHS] driver = usbhid-ups port = auto
desc = “CyberPower SX550G”
The name in square brackets is so you can tell multiple UPS devices apart in case you have one NUT server monitoring multiple devices. Unless you’re building something really esoteric, you probably only have one UPS like me, so for lack of anything better to call it, I’ve named mine “RPHS” after the computer it serves. You can put anything you want in the description, so I just put the make and model of the device for reference. The end result should look something like this:
That’s it for configuring the UPS itself. Close and save the file (ctrl-x, y, enter).
Configure the daemon
A daemon is the Unix/Linux term for any invisible background process. Windows folks call these “services”. For NUT, there is a daemon that is in charge of listening to the UPS via the driver, and telling the client applications what to do. Edit its configuration file like this:
sudo nano /etc/nut/nut.conf
For this simple application, where both the client and the server programs will be on the same computer (the Pi), go to the bottom of the file and set the MODE to “standalone”.
Close and save the file.
Verify hardware configuration
To check whether the driver and daemon are configured correctly, you can simply start up the service.
sudo upsdrvctl start
You should see a message confirming your configuration. It should look something like this:
The first time I tried to connect to the UPS I got the error “could not detach kernel driver from interface 0: Operation not permitted”. I rebooted and tried again, and everything was fine.
Notice that this time I got a message about “Duplicate driver instance detected”. This is because now that I have things configured correctly, the driver started up automatically when I rebooted. Not only that, but the daemon should be running now as well. Check it like this:
sudo service nut-server status
You should get a message that the NUT server is running.
You can now ask the NUT server questions about the status of the UPS using “upsc”, one of several command line utilities that apt-get installed. Substitute the name you gave your UPS above as needed.
You’ll get quite a long list of information about the configuration and status of your UPS.
Depending on the make and model, you’ll get more or less detailed information.
Configure the monitor
That’s two out of the three layers. Last but certainly not least is the “upsmon” client. This is the part that will actually shut down the computer when the NUT server says so.
Define credentials that the monitor client program will use to connect to the server.
sudo nano /etc/nut/upsd.users
Go to the bottom and define two users, one called “admin” and one called “upsmon”. You can actually name them anything you want, but naming the “monitor” user after the program that will use it (upsmon), seems to be the convention. You give the “admin” user rights to issue commands and change configurations with the “actions” and “instcmds” settings. The “upsmon” user has no such rights, it’s just there to listen and shut the computer down when the power goes out.
password = mypasswd
actions = SET
instcmds = ALL
password = mypasswd
Since this is the computer that’s actually in charge of monitoring the UPS, set the “upsmon” setting to “master”.
Next, edit the configuration file for the upsmon client program.
sudo nano /etc/nut/upsmon.conf
This configuration file is pretty long, and has a lot of options. The one we’re interested in is about five pages down. Look for the example lines that start with “MONITOR”, and create a new entry on the blank line below that section. There are six parts to this setting.
- The keyword “MONITOR”. It does have to be all uppercase, by the way.
- The “system” name in the format UpsName@HostName. I called my UPS “RPHS”, and since we’re running in standalone mode, we can just use “localhost” for the host name, so the resulting “system name” is “RPHS@localhost”.
- The “power value”. This only applies to big servers with multiple redundant power supplies. Just set it to “1”.
- The user name that you established in the upsd.users file (upsmon) .
- The password that you established in the upsd.users file (mypasswd).
- A value indicating whether this computer is the master or slave. You can read about the distinction in the upsmon.conf file itself, but for a standalone system like this, use “master”.
When you’re done, it should look something like this.
Close and save the file.
Next up, a little permissions wrangling. You need to set up the various configuration files to be readable by the NUT components that use them, but not by other users. This prevents anyone from reading the password, and sending unauthorized commands to the server to shut everything down. It may be overkill for a simple home network, but it’s also really simple to do.
sudo chown nut:nut /etc/nut/*
sudo chmod 640 /etc/nut/upsd.users /etc/nut/upsmon.conf
You should get no complaints
Depending on the sophistication of your particular UPS, you may be able to send it commands to do things like initiate a self-test, or simulate a power failure. You can get a list of what your particular UPS supports with sudo upscmd –l rphs
The number and type of commands will vary by manufacturer and model, so your output may not match mine. There are a few commands here worth mentioning, though. The “load.off” command will shut down the UPS immediately. Think of it as the “goodbye world” command. You generally don’t want to mess with that one. You could actually use this command to turn a second UPS on and off, allowing your Pi to control the power to something else. I’ll leave that one up to your imagination, but there are certainly cheaper ways to automate things.
The “beeper.mute” command will temporarily silence the warning beep that my UPS makes when the power goes out. This will make testing the system a bit less annoying here in the next section. The “beeper.disable” command would probably have the same effect, but on a more permanent basis.
Testing the system
At this point, you can unplug your UPS from the wall and, after a short delay, you should get a message that the system is now running on battery power.
If you plug it back in, you’ll get another message that power has been restored.
So far, so good. Now for the real test. Unplug the UPS from the wall and leave it unplugged. If your UPS supports it, now is a good time to issue that “beeper.mute” command.
You can sit and stare at the screen, wondering when it will shut down, or you can periodically check on the status to see how fast you’re using up the battery. I plugged my laptop charger and a television into the UPS to speed things along. A good, old-fashioned 100-Watt bulb would help, too.
Eventually, when the battery gets low enough, the system should shut itself down.
Plug the UPS back in, and if you’re lucky, everything will start back up again. For some models, even after the power is restored, you may have to physically press a button on the UPS to start everything back up. Mine starts up on its own, so a few minutes later I was back up and running.
Next up, I’ll show you how to attach additional Pis to the same UPS, and have them all shut down when the power gets low. I was going to make it all part of this post, but this one’s long enough already, don’t you think?