UPS Monitoring for Your Homelab with NUT
UPS Monitoring for Your Homelab with NUT
Photo by Antonino Visalli on Unsplash
A UPS (Uninterruptible Power Supply) protects your homelab from unexpected power loss, but without software, it's just a battery — when the power goes out and the battery runs low, your servers hard-shutdown and you risk filesystem corruption. Network UPS Tools (NUT) bridges the gap: it monitors UPS status over USB, exposes metrics, and triggers graceful shutdowns when the battery runs low.
Why NUT?
NUT is the standard open-source UPS monitoring stack. It supports hundreds of UPS models from APC, CyberPower, Eaton, and others. Key features:
- USB and network communication with the UPS
- Client/server architecture: one server monitors the UPS, multiple clients can react
- Configurable thresholds: shut down at X% battery or Y minutes remaining
- Hooks: run custom scripts on power events (email alerts, notifications)
- Prometheus exporter: integrate with Grafana for battery history graphs
Supported UPS Models
Before buying or configuring, check the NUT hardware compatibility list. Most UPS devices that support USB monitoring work with NUT.
Common well-supported models:
- APC Back-UPS series: USB, excellent NUT support
- APC Smart-UPS series: USB or serial, full feature support
- CyberPower CP series: USB, good NUT support
- Eaton 5E/5P series: USB, good support
For the best NUT experience, APC Smart-UPS (used units are cheap on eBay) or CyberPower are solid choices.
Architecture
NUT uses a client/server model:
[UPS] --USB-- [NUT Server (upsd)] <-- [upsmon clients]
|
(shutdown command)
upsd: Daemon that talks to the UPS and serves status over the networkupsmon: Client that monitorsupsdand triggers shutdownsupsc: Command-line tool for querying UPS status
For a single-server homelab, run both server and client on the same machine. For a multi-node setup (e.g., Proxmox cluster), run the NUT server on the host with USB access and NUT clients on all other hosts.
Like what you're reading? Subscribe to HomeLab Starter — free weekly guides in your inbox.
Installation
Debian/Ubuntu/Proxmox Host
apt install nut nut-client nut-server
Identifying the UPS
Plug the UPS USB cable into your server. Find the device:
lsusb | grep -i ups
# Example output: Bus 001 Device 003: ID 051d:0002 American Power Conversion UPS
nut-scanner -U
# Scans for USB UPS devices and outputs driver config
nut-scanner output will look like:
[ups]
driver = usbhid-ups
port = auto
vendorid = 051d
productid = 0002
desc = "APC Back-UPS"
Save this — you'll need it for configuration.
Configuration
NUT config lives in /etc/nut/. You'll edit four files.
1. /etc/nut/nut.conf — Mode
MODE=netserver
Use standalone for single-host; netserver for multi-host (exposes TCP port 3493).
2. /etc/nut/ups.conf — UPS Driver
[myups]
driver = usbhid-ups
port = auto
vendorid = 051d
productid = 0002
desc = "APC Back-UPS 1500"
# Poll interval in seconds (default 2)
pollinterval = 2
Replace vendorid/productid with the values from nut-scanner.
3. /etc/nut/upsd.conf — Server Access
# Listen on localhost and LAN
LISTEN 127.0.0.1 3493
LISTEN 192.168.20.10 3493 # Your server's IP on the Servers VLAN
4. /etc/nut/upsd.users — Credentials
[admin]
password = strongpassword
upsmon master
[monitor]
password = monitorpassword
upsmon slave
master is the host with USB access. slave is any other host that monitors remotely.
5. /etc/nut/upsmon.conf — Shutdown Config
# Connect to local UPS
MONITOR myups@localhost 1 admin strongpassword master
# Shut down when battery drops below 20%
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h +0"
# Wait up to 45 seconds for other systems to shut down first
HOSTSYNC 45
# Notification settings
NOTIFYMSG ONLINE "UPS %s: On line power"
NOTIFYMSG ONBATT "UPS %s: On battery"
NOTIFYMSG LOWBATT "UPS %s: Battery is low!"
NOTIFYMSG SHUTDOWN "UPS %s: Shutting down"
NOTIFYFLAG ONLINE SYSLOG+WALL
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT SYSLOG+WALL+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXEC
# Script to run on power events
NOTIFYCMD /etc/nut/notify.sh
Create /etc/nut/notify.sh:
#!/bin/bash
# Called by upsmon for EXEC notifications
echo "$(date): UPS Event: $1" >> /var/log/nut-notify.log
# Add your alerting here (email, ntfy.sh, etc.)
chmod +x /etc/nut/notify.sh
Starting NUT
# Start the driver
upsdrvctl start
# Start the server
systemctl enable --now nut-server
# Start the monitor
systemctl enable --now nut-monitor
# Verify
upsc myups@localhost
upsc output should show real-time UPS data:
battery.charge: 100
battery.charge.low: 20
battery.runtime: 3600
battery.voltage: 27.10
input.voltage: 120.0
output.voltage: 120.0
ups.load: 35
ups.status: OL
ups.status: OL = on line (normal). OB = on battery. LB = low battery.
Multi-Host Setup (Proxmox Cluster)
If you have multiple Proxmox nodes or other servers, configure NUT clients on each host to shut down gracefully when the UPS server signals low battery.
On each client host:
apt install nut-client
Edit /etc/nut/nut.conf:
MODE=netclient
Edit /etc/nut/upsmon.conf:
MONITOR [email protected] 1 monitor monitorpassword slave
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h +0"
HOSTSYNC 45
POWERDOWNFLAG /etc/killpower
The slave hosts shut down first. After HOSTSYNC seconds, the master (with USB) shuts down last and sends the UPS shutdown signal.
Proxmox Integration
Proxmox nodes handle their own shutdown, but you also want to shut down VMs gracefully. Add to the Proxmox node's /etc/nut/upsmon.conf:
SHUTDOWNCMD "/usr/sbin/pveshutdown"
Or use a custom script:
#!/bin/bash
# Gracefully stop all running VMs, then shut down node
for vmid in $(qm list | awk 'NR>1 && $3=="running" {print $1}'); do
qm shutdown $vmid --timeout 60
done
sleep 30
shutdown -h now
Alerts with ntfy.sh
Add push notifications to your notify script:
#!/bin/bash
NTFY_TOPIC="your-homelab-alerts"
case "$NOTIFYTYPE" in
ONBATT)
curl -s -X POST https://ntfy.sh/$NTFY_TOPIC \
-H "Title: UPS on Battery" \
-H "Priority: high" \
-H "Tags: warning" \
-d "Power outage detected — on battery power"
;;
LOWBATT)
curl -s -X POST https://ntfy.sh/$NTFY_TOPIC \
-H "Title: UPS Low Battery — Shutting Down" \
-H "Priority: urgent" \
-H "Tags: rotating_light" \
-d "Battery critically low. Graceful shutdown starting."
;;
ONLINE)
curl -s -X POST https://ntfy.sh/$NTFY_TOPIC \
-H "Title: Power Restored" \
-H "Tags: white_check_mark" \
-d "Grid power restored. Back online."
;;
esac
Prometheus Metrics
If you run Prometheus + Grafana, use the NUT exporter:
# docker-compose.yml
services:
nut-exporter:
image: hon96/nut-upsd-exporter:latest
ports:
- "9199:9199"
environment:
NUT_EXPORTER_SERVER: 192.168.20.10
NUT_EXPORTER_PORT: 3493
NUT_EXPORTER_UPS: myups
NUT_EXPORTER_USERNAME: monitor
NUT_EXPORTER_PASSWORD: monitorpassword
Add to Prometheus scrape_configs:
- job_name: nut
static_configs:
- targets: ['localhost:9199']
In Grafana, import dashboard ID 14371 (NUT UPS Monitoring) for pre-built panels showing battery charge, load percentage, input/output voltage, and runtime estimates.
Testing the Shutdown
Never assume your shutdown chain works until you've tested it.
Test with upsmon:
# Simulate a low battery condition
upsmon -c fsd
# This sends a "forced shutdown" — all clients will begin their shutdown sequence
Watch what happens: clients should start shutting down in order. The master shuts down last. Make sure VMs stop gracefully, not hard-killed.
Run this test during a maintenance window before you trust the system.
Common Issues
Driver won't start: Check dmesg | grep -i hid for USB detection issues. Try unplugging and replugging the UPS USB cable. Check upsdrvctl start output for specific error messages.
Permission denied on USB device: Add the nut user to the dialout group:
usermod -a -G dialout nut
upsmon says "MONITOR failed": Check that upsd is running and that the credentials in upsd.users match upsmon.conf. Test manually: upsc myups@localhost.
Shutdown happens too early: Increase BATTERY.CHARGE.LOW threshold (set in ups.conf as override.battery.charge.low = 20) or check battery.runtime.low.
Wrapping Up
A UPS without monitoring software is only half-useful. NUT closes the loop: it watches the UPS, warns you on power events, and shuts everything down gracefully before the battery dies. For a homelab with a NAS, Proxmox, or any service that needs clean shutdown, NUT is essential infrastructure.
The initial setup takes an hour. After that, it runs silently in the background until you need it.
