Table of Contents
After the recent snow apocalypse that swept through Texas followed by widespread power crisis, I realized that my UPS monitoring strategy needed improvement. One had batteries that were near death and my other two had loads that were not well balanced.
I have a few CyberPower UPS units and an old APC UPS. Although CyberPower does offer relatively expensive monitoring cards that puts the UPS on the local network, none of them worked with my 1350/1500VA units. However, all of them do have USB serial connectivity and I wondered how I could monitor them more effectively.
Enter the Raspberry Pi Zero W #
The Pi Zero W is an extension of the old Pi Zero with wireless network connectivity included. It also has a USB port available that would allow me to connect it to a UPS. It runs an older Broadcom BCM2835 and only has 512MiB of RAM, but that’s plenty to do the job.
The Vilros kit contains nearly everything you need for a Pi Zero W. I added on a 64GB SD card for $11 and that brought the total to just under $40 per UPS.
Setting up #
While the Raspberry Pi OS is popular, I’ve been using Arch Linux a lot lately and decided to use their build for the Pi Zero W. The installation instructions for Arch we perfect, except for one step: I needed wireless network connectivity as soon as the Pi booted.
You can enable wireless network at boot time by following the Arch Linux instructions and stopping just before you unmount the filesystems on the SD card. The first step is to add a systemd-networkd config to use DHCP on the wireless network interface:
cat << EOF >> root/etc/systemd/network/wlan0.network
Next, we need to store our
wpa_supplicant configuration for
wpa_passphrase "YOUR_SSID" "WIFI_PASSWORD" \
This prepares the
wpa_supplicant configuration at boot time, but we need to
tell systemd to start
wpa_supplicant when the Pi boots:
ln -s \
We’ve now enabled DHCP at boot time, stored the wireless connection
credentials, and enabled
wpa_supplicant at boot time. Follow the remaining
Arch Linux installation instructions starting with unmounting the
Pop the SD card into the Pi, connect your UPS’ USB cable, and connect it to power. Once it boots, be sure to follow the last two steps from the Arch Linux installation instructions:
pacman-key --populate archlinuxarm
Nuts and bolts #
When it comes to monitoring UPS devices in Linux, it’s hard to beat
UPS Tools, or
nut. Install it on your Pi:
pacman -S nut usbutils
Start by running
lsusb to ensure your USB is connected and recognized:
Bus 001 Device 003: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPS
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
If you can’t see the UPS, double check your USB cable. You may need to
disconnect and reconnect it after installing
nut to pick up udev changes.
Next, it’s time to update some configuration files. Start by opening
/etc/nut/nut.conf and setting the server mode to
netserver so that nut can
listen on the network:
/etc/nut/ups.conf and tell
nut how to talk to your UPS:
driver = usbhid-ups
port = auto
desc = "CyberPower 1500VA AMD Desktop"
Almost all modern UPS units will use the
usbhid-ups driver. The name in the
section header (
amd-desktop in my example) is how the UPS is named when you
nut for status.
Now we need to tell
nut to listen on the network. I trust my local network,
so I open it up to the LAN. Edit
/etc/nut/upsd.conf and adjust
# LISTEN <address> [<port>]
# LISTEN 127.0.0.1 3493
# LISTEN ::1 3493
LISTEN 0.0.0.0 3493
# This defaults to the localhost listening addresses and port 3493.
# In case of IP v4 or v6 disabled kernel, only the available one will be used.
The next step is to set up an admin user for
nut. This is completely
optional, but you will need this if you want to tell
nut to execute certain
commands on the UPS, such as disabling the beeping alarm or running self
/etc/nut/upsd.users and add a user:
password = ihavethepower
actions = SET
instcmds = ALL
We’re ready to start the service and ensure it comes up on reboots:
systemctl enable --now nut-server
We can test it:
$ upsc -l
$ upsc amd-desktop@localhost
device.model: CP 1350C
driver.version.data: CyberPower HID 0.4
ups.model: CP 1350C
ups.test.result: Done and passed
Sweet! You can test connectivity from another system on your network by
specifying the IP address instead of
Adding HomeAssistant #
Setting up HomeAssistant is well outside the scope of this post, but it can monitor all kinds of things on your home network and allow you to run certain automations when devices get into a certain state. You can put a sensor on your garage door and get a text when it opens or closes. You can lower your thermostat when your CPU temperature gets too hot.
Fortunately, you can also monitor UPS devices and create alerts! Follow these steps to add your UPS to HomeAssistant:
- From the main HomeAssistant screen, click Configuration.
- Click Integrations.
- Click Add Integration at the bottom right.
- Search for
nutin the list and add it.
- In the next window, specify your Pi’s IP address and port for
nut. Add your username and password that you configured in
- Click Submit.
- Choose all of the aspects of your UPS you want to monitor. I keep an eye on load, battery voltage, input voltage, and runtime.
- Click Submit again and your UPS should appear in the integrations list!
Once HomeAssistant monitors your UPS for a while, you should have some useful data! Here’s a graph of my UPS load during my workday:
You can see that my workday starts just after 6AM and ends after 4PM. Using this data, you can set up all kinds of automations when UPS load is too high, input voltage is too low (brownout/blackout), or the runtime falls to a low level (could be dying batteries).
The Pi Zero W draws a tiny amount of power and can monitor your UPS for an extended period without having an impact on the runtime or your wallet! 💸
Photo credit: Johannes Plenio on Unsplash