[home]
Linux and the APC Back-UPS ES
Written Oct 23, 2005.
Updated Jan 5, 2007


Introduction

I recently bought an APC Back-UPS ES 650 uninterruptible power supply (shown on the right). It connects to my computer via a USB cable (actually, via a special APC-supplied cable that has a standard USB connector on the computer end and a standard Ethernet connector on the UPS end - it behaves like a USB though).

To get this to work under Linux, I used the NUT (Network UPS Tools) package with the "usbhid-ups" driver. Note that this driver was called "newhidups" until nut-2.0.5. The instructions below have been updated to reflect the new name.

Update, December 2010: I just bought another APC Back-UPS, since the battery was failing on my old one. Except for minor cosmetic changes, this UPS is identical, including its interface, functionality, and cables, to the one I bought in 2005. I am still using a version of NUT from 2007, which works fine. I'll update this page if I upgrade to a newer NUT version.

Supported variables and instant commands

The usbhid-ups driver supports the following variables and instant commands for the APC Back-UPS ES 650. Additional variables and commands might be supported by different UPS models.

Variables:

VariableTypical valueMeaning
battery.charge100Current battery level (percent)
battery.charge.low10Battery level when UPS switches to "LB" low battery (percent)
battery.charge.warning50Battery level when UPS switches to "Warning"
battery.datenot setDate when the battery should be changed
battery.mfr.date2005/04/02Date when the battery was manufactured
battery.runtime1980Current battery runtime (seconds)
battery.runtime.low120Battery runtime when UPS switches to "LB" low battery (seconds)
battery.typePbAcBattery chemistry
battery.voltage13.0Current battery voltage (Volt)
battery.voltage.nominal12.0Nominal battery voltage
driver.nameusbhid-upsDriver name
driver.parameter.portautoMeaningless for USB
driver.version2.2.0NUT version
driver.version.dataAPC HID 0.7usbhid-ups/APC version
driver.version.internal0.28usbhid-ups version
input.transfer.high139High voltage transfer point (Volt)
input.transfer.low88Low voltage transfer point (Volt)
input.voltage120.0Current input voltage
input.voltage.nominal120Nominal input voltage
ups.beeper.statusenabledState of the beeper: enabled, disabled, or muted
ups.delay.shutdown-1Time left until shutdown (seconds)
ups.firmware818.w1.DFirmware version
ups.firmware.auxw1Firmware version
ups.load9Current load on UPS (percent)
ups.mfrAPCUPS manufacturer
ups.mfr.date2005/04/02Date when UPS was manufactured
ups.modelBack-UPS ES 650UPS model
ups.serialQB0514132764 UPS serial number
ups.statusOLUPS status (OL=on line, OB=on battery, CHRG=charging, DISCHRG=discharging, etc

Instant commands:

Instant commandMeaning
test.panel.startStart testing the UPS panel (this will beep)
test.panel.stopStop a UPS panel test (this will do nothing)
load.offTurn off the load immediately, and return when power is back
shutdown.returnTurn off the load after a 60 second delay, and return when power is back
shutdown.stopStop a shutdown in progress
beeper.onEnable the UPS beeper
beeper.offMute the UPS beeper (it will revert to "enabled" once the UPS goes back online)

Download

You will need two things:
  1. Libusb, version 0.1.8 or better: http://libusb.sourceforge.net/
  2. The NUT source distribution: http://www.networkupstools.org/source.html
You might also be able to install NUT from a pre-compiled package; in this case, the instructions below may or may not apply. Some of the packages might install themselves more or less automatically, while others might require you to do some configuration.

Installation instructions

The following installation instructions assume that you have downloaded the source distribution, as described under "Download" above. They are more or less similar to the instructions contained in the files INSTALL and in the FAQ that comes with NUT. I have customized them for the usbhid-ups driver, which has some special requirements (e.g. there is no "port" to specify, and "upsdrvctl shutdown" does not work).

In the instructions below, the commands shown in blue must be issued as root; the commands shown in green can be issued as an ordinary user.

Disclaimer: The the following instructions are distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. They are supplied "as is", may or may not have been tested, and they may or may not work for you. They may damage your UPS, your computer, your marriage, or all of the above. THERE IS NO WARRANTY. See the GNU General Public License for more details.

  1. Check if you need to install libusb. Do:
    ls /usr/lib/libusb* /usr/include/usb.h
    
    If you see /usr/include/usb.h and libusb-0.1.so.4.4.0 or higher, or libusb-0.1.4.4.0 or higher, you don't need to install or upgrade libusb. Otherwise, download libusb at the website mentioned above, and install it using the instructions that come with it. Here is how I did it.
    tar zxf libusb-0.1.10a.tar.gz
    ./configure --prefix=/usr
    make
    make install
    
    Check where the file "hiddev.h" was installed. For example, in /usr/include/linux/hiddev.h.
  2. Unpack NUT. (Here I am assuming you have version 2.2.0 or better. You can change this to a later version if one is available).
    tar zxf nut-2.0.3.tar.gz
    cd nut-2.0.3
    
    All following commands in these instructions are assumed to be issued from inside the "nut-2.0.3" directory.
  3. Configure and compile the NUT binaries. Give the location of the "hiddev.h" file, found in step 1, with the --with-linux-hiddev configuration option. More or less follow the instructions in the file INSTALL that came with NUT, and also those in doc/FAQ under usbhid-ups. You only need to build the usbhid-ups driver, not the million other drivers that NUT has, so by giving the "--with-drivers=usbhid-ups" configuration option, the build is a lot faster. Here is how I did it:
    ./configure --with-user=ups --with-group=ups --with-drivers=usbhid-ups --prefix=/usr
    make
    
    Note: the "--prefix=/usr" options causes all files to be installed in /usr, rather than /usr/local (the default). I prefer this because sometimes /usr/local is not mounted when the system's shutdown script runs, and you definitely need to be able to access your UPS while the computer shuts down.

    Also note: if you happen to re-run "./configure" with different options, then you must also run "make clean" before you run "make" again.

    Trouble shooting: if you get an error message saying "usb.h: No such file or directory", then you did not install libusb correctly. Go back to step 1. above.

  4. Create the "ups" user. The driver and daemon will run with this user id.
    useradd -r ups
    
  5. Configure the driver. As root, create and edit the following file:
    /usr/etc/ups.conf:
    ----------------------------------------------------------------------
    [apc]
            driver = usbhid-ups
            port = auto
            desc = "APC Back-UPS ES 650"
    ----------------------------------------------------------------------
    
    Set up the ownership and permissions of the file you just created:
    chown ups:ups /usr/etc/ups.conf
    chmod 0600 /usr/etc/ups.conf
    
  6. Create the /var/state/ups directory.
    mkdir -p /var/state/ups
    chmod 0700 /var/state/ups
    chown ups:ups /var/state/ups
    
  7. At this point, you should be able to test the driver. Attach your UPS to your computer via the USB port, and turn on the UPS.
    drivers/usbhid-ups -u root -DD -a apc
    
    This should give you lots of debugging output and should announce that your UPS was found. This is just a test. Don't forget to stop the driver again by pressing CTRL-C.

    Note: until you install the hotplug script (see the next step below), the usbhid-ups driver must be run as the root user, which is specified by the "-u root" option.

    Trouble shooting note: if the debugging output does not contain any lines starting with "Checking device...", then libusb is not finding your USB devices. On Linux, check the contents of /proc/bus/usb. If this does not exist or is empty, you might have to mount the USB filesystem: try "mount -t usbfs usbfs /proc/bus/usb".

  8. Next, try if you can kill the UPS load by typing the following command. NOTE: For this test, it is really important that your computer is not plugged into the UPS. Otherwise, this command will shut it off ungracefully.
    drivers/usbhid-ups -u root -k -a apc
    
    This should shut off your load for a short time. The best way to see this is by plugging a desk lamp (not your computer!) into your UPS. Make sure you plug it into one of the outlets marked "Battery Backup plus Surge Protection", and not just "Surge Protection".
  9. Set up the hotplug script. Since USB devices are "plug and play", it is necessary to give the "ups" user read/write access each time your UPS is plugged in. This is done by a hotplugging script that you need to set up. Depending on whether your operating system uses "old-style" or "new-style" hotplugging, use either the files in "scripts/hotplug" or "scripts/hotplug-ng". (If you are not sure which one it is using, try old-style first. If it doesn't work, try new-style). The following instructions are for the old style.

    Do the following. Note that the file "scripts/hotplug/libhidups" should have been generated by "./configure" above.

    cp scripts/hotplug/libhidups /etc/hotplug/usb/
    cp scripts/hotplug/libhid.usermap /etc/hotplug/usb/
    chmod 0755 /etc/hotplug/usb/libhidups
    chmod 0644 /etc/hotplug/usb/libhid.usermap
    
    Check if the hotplug script is working. You will need to know the answer to this before you continue. Unplug and re-plug the USB cable of your UPS. Do
    ls -lR /proc/bus/usb/
    
    You should see listings of several directories. You should see at least one file owned by "root ups", for example:
    /proc/bus/usb/002:
    total 0
    -rw-r--r--  1 root root 43 Aug 28 16:33 001
    -rw-r--r--  1 root ups  52 Aug 28 16:33 002
    
    The actual file names will most likely be different; it is the ownership that matters. If you see a file owned by "root ups", then skip the next paragraph and continue with the instructions.

    If not, then you might have to call "update-usb.usermap" or something similar depending on the operating system you are running (mine does not need this so I have not tested this). Then repeat the above test (including the unplugging and replugging). If you still see no files owned by "root ups", then you may continue with the instructions below, except that you must add the option "-u root" to all calls of "upsdrvctl", "upsd", and "usbhid-ups" below. Your driver and daemon will have to run as the "root" user rather than the "ups" user.

  10. If hotplugging works correctly, you should now be able to run the commands from Step 6+7 above without the "-u root" option. Don't forget to follow the same precautions as in Step 7.
    drivers/usbhid-ups -DD -a apc
    drivers/usbhid-ups -k -a apc
    
  11. Install the NUT binaries. Here is how:
    make install
    
  12. Configure the UPS daemon and UPS monitor. Choose two passwords, which we will call "password1" and "password2". Do not use your login password. Create new passwords, possibly with a utility such as "mkpasswd" or similar. Then create the following files, replacing the passwords by the ones you have chosen. Note: you may customize these files, following the instructions in the file INSTALL. The following is what I used.
    /usr/etc/upsd.conf:
    ----------------------------------------------------------------------
    ACL all 0.0.0.0/0
    ACL localhost 127.0.0.1/32
    
    ACCEPT localhost
    REJECT all
    ----------------------------------------------------------------------
    
    /usr/etc/upsd.users:
    ----------------------------------------------------------------------
    [admin]
            password = password1
            allowfrom = localhost
            actions = SET
            instcmds = ALL
    
    [monuser]
            password = password2
            allowfrom = localhost
            upsmon master
    ----------------------------------------------------------------------
    
    /usr/etc/upsmon.conf:
    ----------------------------------------------------------------------
    MONITOR apc@localhost 1 monuser password2 master
    MINSUPPLIES 1
    SHUTDOWNCMD "/sbin/shutdown -h +0"
    POLLFREQ 5
    POLLFREQALERT 5
    HOSTSYNC 15
    DEADTIME 15
    POWERDOWNFLAG /etc/killpower
    RBWARNTIME 43200
    NOCOMMWARNTIME 300
    FINALDELAY 5
    ----------------------------------------------------------------------
    
    Set up the ownership and permissions of the configuration files:
    chown ups:ups /usr/etc/upsd.conf
    chown ups:ups /usr/etc/upsd.users
    chown ups:ups /usr/etc/upsmon.conf
    chmod 0600 /usr/etc/upsd.conf
    chmod 0600 /usr/etc/upsd.users
    chmod 0600 /usr/etc/upsmon.conf
    
  13. Check if the driver and daemon work. You should now be able to start the UPS driver and daemon with the following commands:
    upsdrvctl start apc
    upsd
    
    To test whether this worked, see if you can get a listing of the UPS state variables:
    upsc apc@localhost
    
    This should output a list of variables and their values similar to the following:
    
    battery.charge: 100
    battery.charge.low: 10
    battery.charge.warning: 50
    battery.date: not set
    battery.mfr.date: 2005/04/02
    battery.runtime: 2850
    battery.runtime.low: 120
    battery.voltage: 13.0
    battery.voltage.nominal: 12.0
    driver.name: usbhid-ups
    driver.parameter.port: auto
    driver.version: 2.0.3
    driver.version.data: APC HID 0.8
    driver.version.internal: 0.28
    input.transfer.high: 139
    input.transfer.low: 88
    input.voltage: 110.0
    input.voltage.nominal: 120
    ups.beeper.status: disabled
    ups.delay.shutdown: -1
    ups.firmware: 818.w1.D
    ups.firmware.aux: w1
    ups.load: 20
    ups.mfr: APC
    ups.mfr.date: 2005/04/02
    ups.model: Back-UPS ES 650
    ups.serial: QB0514132764  
    ups.status: OL
    
    You should also be able to issue some instant commands. For a list of available commands, type
    upscmd -l apc@localhost
    Instant commands supported on UPS [apc@localhost]:
    
    test.panel.start - Start testing the UPS panel
    test.panel.stop - Stop a UPS panel test
    load.off - Turn off the load immediately
    shutdown.return - Turn off the load and return when power is back
    shutdown.stop - Stop a shutdown in progress
    beeper.on - Enable the UPS beeper
    beeper.off - Disable the UPS beeper
    
    To issue an instant command, type a command like the following:
    upscmd -u admin apc@localhost load.off
    
    This should briefly shut off the load. When prompted for a password, type password1 from above.
  14. Check if the UPS monitor works. With the driver and daemon already running (as in the previous step), start the monitor as follows:
    upsmon
    
    The UPS monitor is a program that is responsible for shutting down your computer if there is a power outage and the battery is low. Simulate a power failure by unplugging the UPS from the wall socket. Within a few seconds, you should receive a message from the daemon on your terminal announcing the fact. Try plugging the UPS back in. You should receive another message.
  15. Edit your system's shut-down scripts. The location of this depends on your operating system and distribution. On RedHat and Fedora Linux, add something like this near the end of /etc/init.d/halt, just before "halt" or "poweroff" or similar is called. The exact location to put it depends on your system. However, it should be near the end of the script, when your machine is ready to be turned off. The command will kill the power supply of your computer.
    if [ -f /etc/killpower ] ; then
        # if USB is already disabled, re-enable it.
        if [ ! -f /proc/bus/usb/devices ]; then
            echo "Mounting USB filesystem"
            mount -t usbfs usbfs /proc/bus/usb
        fi
    
        # hotplugging is probably off, so run driver as -u root
        echo "Killing the power, bye!"
        /usr/bin/upsdrvctl -u root shutdown apc
        sleep 20
    
        # uh oh... the UPS power-off failed
        # you probably want to reboot here so you don't get stuck!
        # *** see the section on power races in shutdown.txt! ***
        echo "Rebooting."
        reboot
    fi
    
  16. Do not plug your computer's power supply into the UPS yet. Instead, plug a desk lamp or some similar gadget into the UPS. Make sure you plug the lamp into one of the outlets marked "Battery Backup plus Surge Protection", and not just "Surge Protection".

    Next, try out your shutdown script. Make sure you read the rest of the instructions for Step 15 before issuing the command below, as that command will shut down your computer.

    One way to test your shutdown scripts is to unplug your UPS from the wall and to wait until the battery runs out. This method takes a very long time. A better method is to leave your UPS plugged in, and issue the command below. (I am assuming that "upsmon" is already running, otherwise, repeat Step 13 above).

    Note: this command will cause your computer to go through its ordinary shutdown sequence, as if there had been a power failure and low battery condition. At the end of the shutdown sequence, you should see the message "Killing the power, bye!", and the desk lamp (or whatever you have attached to your UPS) should briefly go off. Then after about 20 seconds, your computer will reboot. Note: if it had been your computer, and not the lamp, plugged into the UPS, then your computer would have gone off too.

    upsmon -c fsd
    
  17. If Step 15 worked as expected, plug your computer into the UPS (again, make sure you plug it into one of the outlets marked "Battery Backup plus Surge Protection", and not just "Surge Protection"). If your computer rebooted, you will have to re-start the driver, daemon, and monitor.
    upsdrvctl start apc
    upsd
    upsmon
    
    Then repeat Step 15. If you want, unplug the UPS from the wall power before issuing the "upsmon -c fsd" command; the computer should stay off until you plug the power back in.
  18. Edit your system's startup scripts so that the UPS driver, UPS daemon, and UPS monitor are started automatically when the system boots. The basic way to do this is to put the following commands in your /etc/rc.local (or similar file):
    echo "Starting UPS driver, daemon, and monitor."
    /usr/bin/upsdrvctl start
    /usr/sbin/upsd
    /usr/sbin/upsmon
    
    You must check if this is working. To do so, reboot your computer, then do
    /bin/ps -ef | grep ups
    
    You should see, among other things, four lines resembling the following:
    ups       7491     1  0 13:32 ?        00:00:00 /usr/bin/usbhid-ups -a apc
    ups       7493     1  0 13:32 ?        00:00:00 /usr/sbin/upsd
    root      7495     1  0 13:32 ?        00:00:00 /usr/sbin/upsmon
    ups       7496  7495  0 13:32 ?        00:00:00 /usr/sbin/upsmon
    
  19. In your computer's BIOS (the "setup menu" that you can enter when you turn on your computer, typically by pressing "F1" or "ESC" or "F12"), there is a setting where you can choose whether you want the computer to boot automatically when the power is turned on. You probably want this if you have a UPS, because in the event of a power failure, you'd want the computer to reboot at the end of the power failure. In most BIOS's, you can also set the computer to go to the "last state" after a power failure, which means, boot if the computer was on before the failure. This is probably the most useful setting in most cases.
  20. If everything is set up correctly, you should restart your computer, plug it into the UPS, and check several times that everything is running correctly by simulating power failures. In particular, you should test what happens (1) when the battery runs out before the power failure ends, and (2) when the power failure ends before the battery runs out, (3) when the power failure ends while your computer is booting, (4) if there is a (second) power failure while your computer is recovering from a previous power failure, and so forth. If everything is set up correctly, your computer should never lose power ungracefully. Good luck!

Special Notes

Sponsored Links



Back to Peter Selinger's UPS page.
Back to Peter Selinger's Homepage: [home]
Peter Selinger / Department of Mathematics and Statistics / Dalhousie University
selinger@mathstat.dal.ca / PGP key