Network UPS Tools and MQTT
This post will cover the installation of NUT which will be used to monitor UPS units from a single host. The data gathered by NUT will then be published to a MQTT broker. From there the data will be processed in Node-Red to provide a at a glance view of the UPS units as well as conditional actions. There have been others who have built interfaces that are specific to a make and model of UPS, such as here https://www.jmayes.com/cyberpower-backup-serial-protocol-and-interface/. These methods have the potential to use an embedded solution such as wireless ESP32 modules. But the investment of time and effort were not affordable and NUT has such a wide range of support that it bridges the gap more efficiently. Here is a description provided by Claude AI about UPS units, NUT, and the benefit of bringing it all together.
When uptime matters and power failures threaten critical operations, an Uninterruptible Power Supply (UPS) can offer protection. This essential component ensures work flow by instantly stepping in during power disruptions, preventing costly equipment damage, or devastating data loss. More than just a backup battery, modern UPS systems deliver clean, consistent power while protecting against surges, sags, and other power anomalies. Each UPS acts as a vigilant sentry, monitoring a wealth of vital statistics including battery health, load levels, runtime estimates, and power conditions. By transforming uncertain power conditions into reliable, protected power delivery, these systems have become the cornerstone of system operations.
UPSs don’t just silently protect equipment, they’re constantly gathering vital intelligence about the power environment. Every data point they collect, from battery health and load levels to voltage fluctuations and temperature readings, tells a crucial part of the story. Monitoring these statistics helps spot potential issues before they become critical failures, plan maintenance windows, and ensures that backup power capacity matches actual needs. The estimated runtime calculations are particularly valuable for graceful shutdowns during extended outages. By transforming raw power metrics into actionable items, these monitoring capabilities elevate a UPS from a simple backup device to a strategic tool for maintaining uninterrupted operations.
Network UPS Tools (NUT) power monitoring breaks free from the limitations of single-device management. Instead of juggling multiple monitoring tools from different manufacturers, NUT unifies the entire power environment under one intelligent system. This open-source solution acts as a universal translator, speaking fluently with UPS units from various vendors while consolidating data into a standardized format. Whether monitoring two UPS units or twenty, NUT eliminates the complexity of multiple management interfaces, streamlines alert handling, and enables coordinated shutdown procedures across the network. This centralized approach not only simplifies monitoring but transforms scattered power data into a cohesive picture of the entire power protection strategy.
Here are the steps to install NUT on a linux host. Most of these steps were based off this posting, https://pimylifeup.com/raspberry-pi-nut-server/
sudo apt update sudo apt upgrade sudo apt install nut lsusb
This provided the following lines based off of the hardware that was installed, yours may be different.
- Bus 001 Device 002: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPS
- Bus 001 Device 003: ID 0764:0501 Cyber Power System, Inc. CP1500 AVR UPS
The two pieces required are specified after “ID“. These are the Vendor ID and Product ID, and they are separated by a semicolon (:).
For example, from the above line, we can see our vendor ID is “0764” and our product ID is “0501“.
Since we have identical model UPS units, this will be a challenge. The device entry of “002” and “003” could be defined, but this has proven to be unreliable. The second UPS unit will be commented out to give reference on how an additional UPS unit would be defined.
With this info in hand, we can modify NUT’s configuration file so that it loads drivers for either one of the UPS units.
sudo nano /etc/nut/ups.conf </> Nano Editor [CP1500UPS-Right] driver = usbhid-ups desc = "CP1500 Right" port = auto vendorid = 0764 productid = 0501 # device = 002 # [CP1500UPS-Left] # driver = usbhid-ups # desc = "CP1500 Left" # port = auto # vendorid = 0764 # productid = 0501 # device = 003
Next the listening port for the service needs to be set.
sudo nano /etc/nut/upsd.conf </> Nano Editor LISTEN 0.0.0.0 3493
The service uses credentials for access, be sure change them from what is provided below.
sudo nano /etc/nut/upsd.users </> Nano Editor [CP1500UPS-Right] password = something CP1500UPS-Right primary # [CP1500UPS-Left] # password = something # CP1500UPS-Left primary
The monitoring service then needs to be configured with the relative details.
sudo nano /etc/nut/upsmon.conf </> Nano Editor MONITOR CP1500UPS-Right@localhost 1 CP1500UPS-Right something primary # MONITOR CP1500UPS-Left@localhost 1 CP1500UPS-Left something primary
Finally, the NUT service needs to have network services activated
sudo nano /etc/nut/nut.conf </> Nano Editor MODE=netserver # Change this line from MODE=none
To commit the changes and active, both NUT services need to be restarted.
sudo systemctl restart nut-server sudo systemctl restart nut-monitor
If all is working, the following command should provide a listing of statistics for the UPS instance.
upsc CP1500UPS-Right@localhost # upsc CP1500UPS-Left@localhost
This concludes the NUT installation and configuration requirements for MQTT intagration. There are other options available for NUT, but those will not be convered here.
The following bash script was expanded from an earlier post about MQTT Node-Red system monitoring, covered here https://www.cloudacm.com/?p=4553.
#!/bin/bash # cloudacm.com # Localhost Systems Resources to MQTT while true; do sysname=$(hostname -s) upTime=$(awk '{print $1}' /proc/uptime) cpuUser=$(top -bn1 | awk '/Cpu/ { print $4}') cpuSystem=$(top -bn1 | awk '/Cpu/ { print $6}') loadAve=$(uptime | tr -d , | awk '/load average/ { print $9}') memUsage=$(free -m | awk '/Mem/{print $3}') diskSize=$(df | awk '/sda1/{print $2}') diskUsed=$(df | awk '/sda1/{print $3}') diskAvail=$(df | awk '/sda1/{print $4}') upsRightLoad=$(upsc CP1500UPS-Right@localhost | awk '/ups.load:/ {print $2}') upsRightRuntime=$(upsc CP1500UPS-Right@localhost | awk '/battery.runtime:/ {print $2}') upsRightUtility=$(upsc CP1500UPS-Right@localhost | awk '/input.voltage:/ {print $2}') upsRightBattery=$(upsc CP1500UPS-Right@localhost | awk '/battery.charge:/ {print $2}') # upsLeftLoad=$(upsc CP1500UPS-Left@localhost | awk '/ups.load:/ {print $2}') # upsLeftRuntime=$(upsc CP1500UPS-Left@localhost | awk '/battery.runtime:/ {print $2}') # upsLeftUtility=$(upsc CP1500UPS-Left@localhost | awk '/input.voltage:/ {print $2}') # upsLeftBattery=$(upsc CP1500UPS-Left@localhost | awk '/battery.charge:/ {print $2}') mosquitto_pub -h <Broker> -m "$upTime" -t $sysname/upTime mosquitto_pub -h <Broker> -m "$cpuUser" -t $sysname/cpuUser mosquitto_pub -h <Broker> -m "$cpuSystem" -t $sysname/cpuSystem mosquitto_pub -h <Broker> -m "$loadAve" -t $sysname/loadAve mosquitto_pub -h <Broker> -m "$memUsage" -t $sysname/memUsage mosquitto_pub -h <Broker> -m "$diskSize" -t $sysname/diskSize mosquitto_pub -h <Broker> -m "$diskUsed" -t $sysname/diskUsed mosquitto_pub -h <Broker> -m "$diskAvail" -t $sysname/diskAvail mosquitto_pub -h <Broker> -m "$upsRightLoad" -t $sysname/upsRightLoad mosquitto_pub -h <Broker> -m "$upsRightRuntime" -t $sysname/upsRightRuntime mosquitto_pub -h <Broker> -m "$upsRightUtility" -t $sysname/upsRightUtility mosquitto_pub -h <Broker> -m "$upsRightBattery" -t $sysname/upsRightBattery # mosquitto_pub -h <Broker> -m "$upsLeftLoad" -t $sysname/upsLeftLoad # mosquitto_pub -h <Broker> -m "$upsLeftRuntime" -t $sysname/upsLeftRuntime # mosquitto_pub -h <Broker> -m "$upsLeftUtility" -t $sysname/upsLeftUtility # mosquitto_pub -h <Broker> -m "$upsLeftBattery" -t $sysname/upsLeftBattery sleep 10; done