watch -n2 'upsc ups@192.168.1.246 ups.load; upsc ups2@192.168.1.246 ups.load' then shut down each node and watch which load dropsupsmon.conf on each node to monitor only its own UPS once mapping is confirmedupsmon -c fsdupscmd -u monuser -p secret ups@192.168.1.246 test.battery.start.quickups battery (May 2020, approaching 5 years)UPS monitoring configured using Network UPS Tools (NUT) across the infrastructure:
APC UPS #1 (USB) ──┐
├──→ Synology (jgmelon) - NUT Server on port 3493
APC UPS #2 (USB) ──┘ ↓ (network)
├─→ thing-1 (NUT client/slave)
└─→ thing-2 (NUT client/slave)
| Name | Serial | Mfr Date | USB Port | Load | Runtime |
|---|---|---|---|---|---|
ups |
4B2021P00308 | 2020/05/19 | 1-2 | 16% | ~47 min |
ups2 |
4B2120P06316 | 2021/05/21 | 3-1 | 8% | ~73 min |
Both UPSes are configured in /etc/ups/ups.conf on the Synology. DSM's UPS GUI only manages [ups] — [ups2] is managed manually via SSH.
/etc/ups/ups.confpollinterval = 5
[ups]
driver = usbhid-ups
port = auto
serial = 4B2021P00308
[ups2]
driver = usbhid-ups
port = auto
serial = 4B2120P06316
desc = APC Back-UPS RS 1500G 2
Pinning by serial number ensures NUT doesn't swap devices on reboot when two identical UPSes are connected.
Run lsusb on the Synology to map each UPS to its physical USB port:
guernica@jgmelon:~$ lsusb
|__usb1 1d6b:0002 (xHCI Host Controller)
|__1-2 051d:0002 (American Power Conversion Back-UPS RS 1500G ... 4B2021P00308)
|__usb3 1d6b:0002 (xHCI Host Controller)
|__3-1 051d:0002 (American Power Conversion Back-UPS RS 1500G ... 4B2120P06316)
APC vendor ID is 051d. The port number (1-2, 3-1) and serial are both visible inline. This is how the inventory table was built — cross-reference with upsc output to confirm which NUT name maps to which serial.
After editing ups.conf via SSH:
# Stop and start the driver
sudo upsdrvctl stop ups2
sudo upsdrvctl start ups2
Alternatively, toggle Enable network UPS server off and back on in DSM:
Control Panel → Hardware & Power → UPS → uncheck → Apply → check → Apply
This restarts the entire NUT stack cleanly, useful if the driver isn't connecting after a config change.
upsc ups@192.168.1.246
upsc ups2@192.168.1.246
Both should return full stats with ups.status: OL.
Synology's NUT version is sensitive to # characters inside quoted values in ups.conf. If you see:
Parse error: /etc/ups/ups.conf:127: Unbalanced word due to unescaped # in quotes
Remove all commented-out lines (#) from inside UPS blocks. The long block of commented SNMP directives that DSM adds by default will trigger this.
sudo dnf install epel-release
sudo dnf install nut-client
/etc/ups/upsmon.confEach node monitors both UPSes:
MONITOR ups@192.168.1.246 1 monuser secret slave
MONITOR ups2@192.168.1.246 1 monuser secret slave
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h +0"
NOTIFYCMD /usr/sbin/upssched
NOTIFYFLAG ONBATT SYSLOG+WALL
NOTIFYFLAG LOWBATT SYSLOG+WALL+EXEC
NOTIFYFLAG ONLINE SYSLOG+WALL
POLLFREQ 5
POLLFREQALERT 5
FINALDELAY 5
RUN_AS_USER nut
MINSUPPLIES 1means either UPS going critical triggers shutdown. Set to2if you want both to fail before shutting down.
Set permissions:
sudo chmod 640 /etc/ups/upsmon.conf
sudo chown root:nut /etc/ups/upsmon.conf
Enable and start:
sudo systemctl enable nut-monitor
sudo systemctl start nut-monitor
sudo systemctl status nut-monitor
Configure via GUI:
DSM only manages
[ups].[ups2]is invisible to DSM and will not affect Synology shutdown behavior.
When power fails:
ups.status: OBups.status: OB LB# Check both UPSes
upsc ups@192.168.1.246 | grep -E "ups.status|battery.charge|battery.runtime|ups.load"
upsc ups2@192.168.1.246 | grep -E "ups.status|battery.charge|battery.runtime|ups.load"
# Watch live
watch -n 5 'upsc ups@192.168.1.246 ups.status; upsc ups2@192.168.1.246 ups.status'
# Check monitoring service on Dell nodes
sudo systemctl status nut-monitor
sudo journalctl -u nut-monitor -f
# Battery self-test
upscmd -u monuser -p secret ups@192.168.1.246 test.battery.start.quick
upscmd -u monuser -p secret ups2@192.168.1.246 test.battery.start.quick
# Simulate forced shutdown (CAUTION — triggers real shutdown sequence)
upsmon -c fsd
| Code | Meaning |
|---|---|
OL |
Online (normal operation) |
OB |
On Battery (power failure) |
LB |
Low Battery (shutdown imminent) |
RB |
Replace Battery |
CHRG |
Charging |
DISCHRG |
Discharging |
# Test NUT port connectivity
nc -zv 192.168.1.246 3493
# Verbose driver start for debugging
sudo upsdrvctl -D start ups2
# Check SELinux denials
sudo ausearch -m avc -ts recent | grep upsmon
# Reload upsmon config without restart
sudo upsmon -c reload
ups battery: May 2020 — approaching 5 years, plan replacementups2 battery: May 2021# Weekly
upsc ups@192.168.1.246 | grep -E "battery.charge|battery.runtime|ups.status"
upsc ups2@192.168.1.246 | grep -E "battery.charge|battery.runtime|ups.status"
# Monthly
sudo systemctl status nut-monitor
# Quarterly
sudo journalctl -u nut-monitor --since "3 months ago" | grep -i battery
| Component | Location |
|---|---|
| NUT server config | /etc/ups/ups.conf (Synology) |
| Client monitor config | /etc/ups/upsmon.conf (thing-1, thing-2) |
| Logs | /var/log/messages |
| Service | nut-monitor.service |
| Client binary | /usr/sbin/upsmon |
| Query tool | /usr/bin/upsc |