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:
Variable | Typical value | Meaning |
---|---|---|
battery.charge | 100 | Current battery level (percent) |
battery.charge.low | 10 | Battery level when UPS switches to “LB” low battery (percent) |
battery.charge.warning | 50 | Battery level when UPS switches to “Warning” |
battery.date | not set | Date when the battery should be changed |
battery.mfr.date | 2005/04/02 | Date when the battery was manufactured |
battery.runtime | 1980 | Current battery runtime (seconds) |
battery.runtime.low | 120 | Battery runtime when UPS switches to “LB” low battery (seconds) |
battery.type | PbAc | Battery chemistry |
battery.voltage | 13.0 | Current battery voltage (Volt) |
battery.voltage.nominal | 12.0 | Nominal battery voltage |
driver.name | usbhid-ups | Driver name |
driver.parameter.port | auto | Meaningless for USB |
driver.version | 2.2.0 | NUT version |
driver.version.data | APC HID 0.7 | usbhid-ups/APC version |
driver.version.internal | 0.28 | usbhid-ups version |
input.transfer.high | 139 | High voltage transfer point (Volt) |
input.transfer.low | 88 | Low voltage transfer point (Volt) |
input.voltage | 120.0 | Current input voltage |
input.voltage.nominal | 120 | Nominal input voltage |
ups.beeper.status | enabled | State of the beeper: enabled, disabled, or muted |
ups.delay.shutdown | -1 | Time left until shutdown (seconds) |
ups.firmware | 818.w1.D | Firmware version |
ups.firmware.aux | w1 | Firmware version |
ups.load | 9 | Current load on UPS (percent) |
ups.mfr | APC | UPS manufacturer |
ups.mfr.date | 2005/04/02 | Date when UPS was manufactured |
ups.model | Back-UPS ES 650 | UPS model |
ups.serial | QB0514132764 | UPS serial number |
ups.status | OL | UPS status (OL=on line, OB=on battery, CHRG=charging, DISCHRG=discharging, etc |
Instant commands:
Instant command | Meaning |
---|---|
test.panel.start | Start testing the UPS panel (this will beep) |
test.panel.stop | Stop a UPS panel test (this will do nothing) |
load.off | Turn off the load immediately, and return when power is back |
shutdown.return | Turn off the load after a 60 second delay, and return when power is back |
shutdown.stop | Stop a shutdown in progress |
beeper.on | Enable the UPS beeper |
beeper.off | Mute the UPS beeper (it will revert to “enabled” once the UPS goes back online) |
Download
You will need two things:
- Libusb, version 0.1.8 or better: http://libusb.sourceforge.net/
- 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.
- 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.
- 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.
- 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.
- Create the “ups” user. The driver and daemon will run with this user id.
useradd -r ups
- 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
- Create the /var/state/ups directory.
mkdir -p /var/state/ups chmod 0700 /var/state/ups chown ups:ups /var/state/ups
- 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”.
- 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”.
- 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.
- 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
- Install the NUT binaries. Here is how:
make install
- 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
- 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.
- 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.
- 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
- 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
- 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.
- 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
- 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.
- 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
- Question: I’m running Fedora on a MacMini and can’t figure out how to turn on the BIOS option to automatically restart after a power failure. OSX has an option in the System Preferences, but since I’m running Fedora, I’m not sure how to do it.Answer: As root, do:
echo server_mode=1 > /proc/pmu/options
(Thanks to Erick Calder for this question and answer).
Sponsored Links
- Refurbished APC UPS. I have not tried this myself, but you may be able to get a good deal on a refurbished UPS (with brand-new batteries) from this site. I’d be happy to receive feedback from people who buy a UPS via this link. (Added November 24, 2009).