UPS monitoring in Proxmox
After some networking instability in one of my Proxmox cluster nodes, I decided to connect an APC UPS to the node and configure proper UPS monitoring and email notifications.
The UPS model I’m using is:
root@pve01:~# lsusb | grep American
Bus 003 Device 002: ID 051d:0002 American Power Conversion Uninterruptible Power SupplyThe node where the UPS is connected is pve01.
Install NUT packages
Install the required packages on the Proxmox node:
root@pve01:~# apt update
root@pve01:~# apt install nut nut-client nut-server mailutilsConfigure the UPS device
Edit /etc/nut/ups.conf:
root@pve01:~# nano /etc/nut/ups.confAdd the UPS definition:
[apcups]
driver = usbhid-ups
port = auto
pollinterval = 5
desc = "APC Back-UPS ES 650G2"Configure standalone mode
Edit /etc/nut/nut.conf:
root@pve01:~# nano /etc/nut/nut.confSet:
MODE=standaloneConfigure NUT users
Edit /etc/nut/upsd.users:
root@pve01:~# nano /etc/nut/upsd.usersAdd:
[admin]
password = strongpassword
actions = SET
instcmds = ALL
[monuser]
password = monitorpassword
upsmon masterConfigure UPS monitoring
Edit /etc/nut/upsmon.conf:
root@pve01:~# nano /etc/nut/upsmon.confUse the following configuration:
MONITOR apcups@localhost 1 monuser monitorpassword master
MINSUPPLIES 1
SHUTDOWNCMD "/usr/bin/sync"
NOTIFYCMD /etc/nut/notify.sh
NOTIFYFLAG ONLINE SYSLOG+EXEC
NOTIFYFLAG ONBATT SYSLOG+EXEC
NOTIFYFLAG LOWBATT SYSLOG+EXEC
NOTIFYFLAG FSD SYSLOG+EXEC
NOTIFYFLAG COMMOK SYSLOG+EXEC
NOTIFYFLAG COMMBAD SYSLOG+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+EXEC
FINALDELAY 5
HOSTSYNC 15
DEADTIME 30
NOCOMMWARNTIME 300
OFFDURATION 30
POLLFREQ 5
POLLFREQALERT 5
POWERDOWNFLAG "/etc/killpower"
RBWARNTIME 43200In my case, I did not want the Proxmox node to power off automatically. Instead, the shutdown command simply flushes pending writes to disk with sync.
Configure email notifications
Create /etc/nut/notify.sh:
root@pve01:~# nano /etc/nut/notify.shContent:
#!/bin/bash
EMAIL="your@email.com"
HOSTNAME=$(hostname)
case $NOTIFYTYPE in
ONLINE)
SUBJECT="[$HOSTNAME] UPS back on utility power"
BODY="UPS is back ONLINE."
;;
ONBATT)
SUBJECT="[$HOSTNAME] UPS running on battery"
BODY="Power failure detected. UPS is ON BATTERY."
;;
LOWBATT)
SUBJECT="[$HOSTNAME] UPS battery LOW"
BODY="UPS battery is LOW."
;;
FSD)
SUBJECT="[$HOSTNAME] UPS forced shutdown"
BODY="UPS initiated forced shutdown."
;;
COMMBAD)
SUBJECT="[$HOSTNAME] UPS communication lost"
BODY="Communication with UPS lost."
;;
COMMOK)
SUBJECT="[$HOSTNAME] UPS communication restored"
BODY="Communication with UPS restored."
;;
SHUTDOWN)
SUBJECT="[$HOSTNAME] UPS shutdown"
BODY="System shutting down due to UPS event."
;;
*)
SUBJECT="[$HOSTNAME] UPS event: $NOTIFYTYPE"
BODY="UPS event detected: $NOTIFYTYPE"
;;
esac
echo "$BODY" | mail -s "$SUBJECT" "$EMAIL"Make it executable:
root@pve01:~# chmod +x /etc/nut/notify.shConfigure USB permissions
Create a udev rule:
root@pve01:~# nano /etc/udev/rules.d/99-nut-ups.rulesAdd:
SUBSYSTEM=="usb", ATTR{idVendor}=="051d", ATTR{idProduct}=="0002", MODE="0660", GROUP="nut"Reload udev rules:
root@pve01:~# udevadm control --reload-rules
root@pve01:~# udevadm triggerThen unplug and reconnect the UPS USB cable.
Verify that permissions are now correct:
root@pve01:~# ls -l /dev/bus/usb/003/002
crw-rw---- 1 root nut 189, 257 May 17 23:26 /dev/bus/usb/003/002Start NUT services
Start the services cleanly:
root@pve01:~# systemctl stop nut-monitor
root@pve01:~# systemctl stop nut-server
root@pve01:~# systemctl stop 'nut-driver@apcups.service'
root@pve01:~# pkill -f usbhid-ups || true
root@pve01:~# rm -f /run/nut/usbhid-ups-apcups.pid
root@pve01:~# rm -f /run/nut/usbhid-ups-apcups
root@pve01:~# systemctl start 'nut-driver@apcups.service'
root@pve01:~# systemctl start nut-server
root@pve01:~# systemctl start nut-monitorVerify UPS communication
After everything was configured correctly, the UPS became fully operational.
Verify with:
root@pve01:~# upsc apcups@localhostExample output:
battery.charge: 100
battery.runtime: 2652
battery.voltage: 13.5
device.model: Back-UPS ES 650G2
driver.name: usbhid-ups
input.voltage: 232.0
ups.load: 12
ups.realpower.nominal: 400
ups.status: OLThe important field is:
ups.status: OLwhich means the UPS is online and utility power is present.
Test notifications
To test notifications manually:
root@pve01:~# NOTIFYTYPE=ONBATT /etc/nut/notify.shYou should receive the notification email immediately.
Test battery operation
To test the UPS under battery mode, disconnect the UPS from mains power and check the status again:
root@pve01:~# upsc apcups@localhostExample output while on battery:
battery.charge: 75
battery.runtime: 2571
input.transfer.reason: input voltage out of range
input.voltage: 0.0
ups.load: 10
ups.status: OB DISCHRGThe important status in this case is:
ups.status: OB DISCHRGMeaning:
OB: On BatteryDISCHRG: Battery is discharging
In this specific test:
battery.runtime: 2571- means approximately 42 minutes and 51 seconds remaining runtime.
Wrap up
With this setup:
- Proxmox receives UPS events correctly.
- Email notifications are sent automatically.
- UPS runtime and battery health can be monitored from the shell.
- USB communication survives service restarts correctly.
- The cluster node does not power off automatically, but pending writes are flushed to disk during critical events.
This setup has worked well for monitoring an APC Back-UPS ES 650G2 connected directly to a Proxmox VE node.