Raspberry Pi Home Server: Part 15–Power Failures

Article Obsolete

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:
(http://www.pluralsight.com/courses/raspberry-pi-home-server)
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:

  1. It has a USB connection to the computer.
  2. It was on sale for $40.
  3. 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

  1. A software driver to communicate with your particular UPS using whatever protocol it supports, and translate that into a common API.
  2. A daemon (service) that connects to the driver and acts as a communication hub.
  3. 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:

image

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”.

image

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:

image

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.

image

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.

image

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.

upsc rphs

You’ll get quite a long list of information about the configuration and status of your UPS.

image

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.

[admin]

password = mypasswd

actions = SET

instcmds = ALL

[upsmon]

password = mypasswd

upsmon master

image

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.

  1. The keyword “MONITOR”. It does have to be all uppercase, by the way.
  2. 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”.
  3. The “power value”. This only applies to big servers with multiple redundant power supplies. Just set it to “1”.
  4. The user name that you established in the upsd.users file (upsmon) .
  5. The password that you established in the upsd.users file (mypasswd).
  6. 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.

image

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

image

UPS Commands

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

image

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.

image

If you plug it back in, you’ll get another message that power has been restored.

image

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.

image

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.

image

Eventually, when the battery gets low enough, the system should shut itself down.

image

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.

What’s next?

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?

This entry was posted in Computers and Internet. Bookmark the permalink.

36 Responses to Raspberry Pi Home Server: Part 15–Power Failures

  1. Pingback: Raspberry Pi Home Server: Index | MelGrubb.ToBlog()

  2. Pingback: UPS with battery reading | DL-UAT

  3. Pingback: UPS for raspberry pi | DL-UAT

  4. Pingback: Using battery pack as a UPS | DL-UAT

  5. Pingback: Can I make my Pi shutdown safely in the event of a power outage? | DL-UAT

  6. Pingback: How do I build a UPS-like – battery backup – system? | DL-UAT

  7. Pingback: Raspberry Pi Home Server: Part 15b – Adding more Pis to the UPS | MelGrubb.ToBlog()

  8. Hi Mel,
    Thank you SO MUCH for this excellent step-by-step guide!
    I followed it with success and without any problem.
    I have a question: is it possible to setup NUT to send email notification on power failure?
    Thanks
    Thanassis

    • Mel Grubb says:

      It should be possible, yes. I just haven’t done it myself yet, but started looking into it. I think you’d just need a pop/smtp type account with your ISP. I’ll hope to add this to the article soon.

  9. Digging google I found this quite helpful guide for how to: “Make your UPS email you with NUT”: http://www.interphero.com/?p=139
    Finally the documentation http://www.networkupstools.org/docs/user-manual.pdf, and in particular chapter 7.2 made the difference. All the details you need are there.

    • AJ says:

      Any luck in getting the configs correct for this to email by executing the script referrenced in upsmon.conf? I can get a functioning script written, but cannot seem to get it it to execute the script upon Notify events.

      • Mel Grubb says:

        I have not done this yet, but I will be in the coming weeks, hopefully. Just as a wild guess, have you used chmod to make the script file executable?

      • AJ says:

        Yes, as I can see through logger that that it is call the script from NOTIFYCMD in upsmon.conf, but it is not executing. The script and upsmon.conf are both in the Nut group and I am using RUN_AS_USER nutmon, whom is also in the Nut group.

  10. AJ says:

    I can run the script from the command line with the output in the Syslog (via logger) and it executes as it is supposed to. It is just when NOTIFYCMD tries and executes it.

    • @AJ,
      NOTIFYCMD runs upssched which in turn has to be configured (/upssched.conf) with the CMDSCIRPT parameter [CMDSCRIPT /upssched-cmd] and finally the upssched-cmd is the script which runs our scripts for each case dependending on the ups status. Sounds all this complicated when it is described in one sentence 🙂 but I can tell you it is very simple if you follow line by line the instructions of the chapter 7.2 in the pdf file I mentioned in my earlier post.
      Hope it helped. If you need more help, just ask for it.

      • AJ says:

        So, NOTIFYCMD is a call to UPSSCHED? I swore I had read posts where NOTIFYCMD could run a script, but I will take your word for it and configure NOTIFYCMD to do so. I found this good example, as I will just need to take the email parameters from the Nut-Notify script and incorporate (http://wiki.ipfire.org/en/addons/nut/start).

  11. The instructions in the wiki link states under the Monitor deamon config states:
    NOTIFYCMD /usr/sbin/upssched only needet if you will follow this how-to to the end and want to use additional notifiying
    So, if you need extra notification or steps after the system is passed to battery (email notification and/or run some scripts before shutdown) then you must configure upssched and the rest.
    Take extra care that the cases in the upssched-cmd script are the ones in the AT … directives: eg.
    AT ONBATT * START-TIMER onbatt 300 in the upssched.conf
    The “onbatt” is the case name in upssched-cmd script. Then each case runs a notification or other script.
    Pls let us know the results of your attempt.

  12. AJ says:

    So, when UPSMON or UPSSCHED is running commands to send email via a script, is it doing it as root or RUN_AS_USER, as I cannot get root to send out any emails.

  13. Actually I haven’t set the RUN_AS_USER directive in upsmon.conf. I followed Mel’s guide and as far I can recheck there is not such instruction; I ‘ve only chowned the config files for security reasons (as in guide just above UPS COMMANDS) and that’s it!
    At the beginning of upsmon.conf in the RUN_AS_USER description says that the NUT process splits into two, one that has root previleges which will run the shutdown command and one that will do the rest of the jobs. Email notification does not need root previleges.

    • AJ says:

      I can see messages are posting to the wall and syslog from user Nutmon, so I know the user is still capable of reading the upsmon.config file. I will work on a basic UPSSCHED and UPSSCHED-CMD to see if that gets it to work, like we are now suggesting. I guess I will owe you guys a really good write up once we get this figured out 🙂

  14. amalott says:

    So, don’t shoot me but I went a completely different direction and have created a script to have it send notifications to Pushover (www.pushover.net) instead. So, NOTIFYCMD executes /usr/local/bin/pushover. I can work on a full write up, but I like the Pushover solution better because I have alerts for IFTTT, UPTime Robot, Loggly and Visualping.IO all going to Pushover, and now UPSMON!

    • DaveStLou says:

      amalott, I know your reply is over a year old, but a Pushover notifications from my Pi is exactly what I’d like to have for UPSMON alerts. Do you have a write up of your script somewhere?

      • AJ says:

        Hey there~
        Here is the script, as you will need to create a key pair on Pushover and insert below:
        – UPSMON (/usr/local/bin/pushover)
        – #!/usr/bin/python
        import httplib, urllib, datetime, time, sys
        timestamp = int(time.time())
        conn = httplib.HTTPSConnection(“api.pushover.net:443”)
        – conn.request(“POST”, “/1/messages.json”,
        urllib.urlencode({
        “token”: “app_token”,
        “user”: “user_token”,
        “message”:str(sys.argv[1]),
        “title”: “Raspberry Pi Notifications”,
        “timestamp”:timestamp,
        }), { “Content-type”: “application/x-www-form-urlencoded” })
        conn.getresponse()

        I don’t have my Pi hooked up right now, but let me know if you have any more questions, as this script is called by UPSMON for notifications. The output message was put in to the sys.argv[1] string and then passed into the script, as that was sent out by Pushover.

      • DaveStLou says:

        Thank you!

  15. Paul says:

    Hi Mel, really weird one. I have used this config for some time and it worked great off a 3 port USB hub that connected to the pi. I swapped that out for another usb hub which also had a gigabit ethernet adapter inbuilt, however it no longer works. The USB hub works. Ethernet works too, and i tested it with a USB flash drive and the pi recognises it. So nothing wrong with the hub. However, the pi just doesnt recognise the ups. Any ideas? Cheers

    • Mel Grubb says:

      Since the UPS shouldn’t need any power, I wouldn’t think it’s a supply problem, and since you’ve successfully used the new hub with other devices, it doesn’t seem like the hub is the problem either. My best guess would be the connection between the UPS and the hub itself. Try pulling the plug out just a little and see if anything changes. I’ve had problems with usb3 connectors and usb2 ports which were solved that way. Otherwise you’ve found a true mystery.

  16. Pingback: CrashPi – An off-Site backup for the whole family | MelGrubb.ToBlog()

  17. Bob says:

    I noticed that you mentioned upon plugging in the UPS after the simulated power failure (second to last paragraph) that the UPS and Pi powered back up. Can you confirm that the same is true if the UPS shuts down due to battery depletion, will everything power back up or do you to need to “push the button”? I am asking this because I have several remote sites and I can not drive miles to “push the button” after an extended power outage that totally drains the UPS battery. Thanks, Bob.

    • Mel Grubb says:

      That will depend entirely on the make and model of the UPS. I was pleasantly surprised to find that the UPS I chose behaves this way. Many others require someone to push the button. You just have to try yours and see. I’m not sure the behavior is documented anywhere.

  18. Jose says:

    Hi Mel,
    Is there a way to install the client in a PI running openelec ? I have a NUT server running on a synology Nas.
    Thanks

    • Mel Grubb says:

      I don’t know if it’s possible to add ANYTHING to OpenElec. The last I looked there was no package manager support (apt-get or otherwise). To be fair, I didn’t look too deeply into OpenElec because it’s not what I needed at the time. I have plenty of smart devices that can be media centers, what I needed was a media server. Maybe try the OpenElec forums, and see whether any kind of package manager has been added since I looked (years ago). There’s always the possibility of installing things more manually, of course, but I like to favor things that came from a package manager since it eases a lot of upgrade headaches down the line.

  19. Klaus says:

    Hi Mel, thanks for the guide which I followed. I face a problem when starting the drivers. After the start command I get the following Message:
    Network UPS Tools – UPS driver controller 2.7.2
    Network UPS Tools – Generic HID driver 0.38 driver (2.7.2)
    USB communication driver 0.32
    Fatal error: ‘maxretry’ is not a valid variable name for this driver.
    Look in the man pages or call this driver with -h for a list of valid variable names and flags.
    Looking into the man pages didn’t help. I use a cyperpower UPS which get recognizes on lsusb as: cp1500 AVR UPS. The ups.conf looks like: driver = usbhid-ups, port = auto, desc = “cp1500 avr”
    Any idea what’s wrong?
    Thanks

    • Mel Grubb says:

      Since maxretry isn’t something that gets explicitly set as part of these instructions, I don’t think it could be something you’ve done wrong there. It sounds like an error within the driver implementation itself. I think the NUT forums are probably going to be the best source of information on this one.

  20. Jim S says:

    I am wondering how the Pi restarts if the battery is not depleted until the UPS shuts down. The Pi normally boots when power is applied so that a power interruption is needed after shutdown command for it to restart. But with the UPS maintaining power to the Pi that interruption won’t happen. If the Pi is shutdown but power input is maintained by the UPS it won’t normally restart.

    • Mel Grubb says:

      The restart behavior is dependent on the UPS itself. The one I’m using shuts off the power when it detects that the Pi has turned off, and turns it back on when line power is restored. I won’t pretend to know the magic that makes this work, but my guess is that NUT receives a signal from the UPS that says the battery is running low, so it tells all of its slave systems to shut down, waits for them to complete, and then starts shutting itself down, but first it sends a signal back to the UPS that says “Okay, that’s everybody… when this USB connection dies, you can turn off the power”.

      That’s just mine though, and I was surprised to see it when I tested the system. I wasn’t expecting that from such an inexpensive UPS. Other brands may leave the power on until the battery finally dies, in which case you’ll have no choice but to go turn the whole thing off and on again if the power comes back on before then.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s