NUT Notification Improvements
Improving notifications
Recently I re-implemented NUT into the rack to monitor my 2 APC UPSes that are not network based. The current notification setup only sends a notification when a UPS is on/off battery, not it’s name, not it’s estimated runtime and does not have reoccuring notifications to update me on the runtime and load values.
I piped my notes from the NUT setup into Claude and asked it to revise the script to show UPS name, runtime and load percentage, and send reoccuring notifications while on battery.
It came up with the following:
#!/bin/bash
NTFY_URL="https://myntfyhost/alerts-networkinfra"
NTFY_AUTH=user:pass
POLL_INTERVAL=30
PIDDIR="/tmp/nut-onbatt"
mkdir -p "$PIDDIR"
send_notify() {
local title="$1" body="$2"
curl -s \
-H "Priority: 5" \
-H "Title: $title" \
-u $NTFY_AUTH \
-d "$body" \
"$NTFY_URL" >/dev/null
}
status_line() {
local ups="$1"
local charge runtime load mins secs
charge=$(upsc "$ups" battery.charge 2>/dev/null)
runtime=$(upsc "$ups" battery.runtime 2>/dev/null)
load=$(upsc "$ups" ups.load 2>/dev/null)
if [ -n "$runtime" ]; then
mins=$(( runtime / 60 ))
secs=$(( runtime % 60 ))
fi
echo "Charge: ${charge:-?}% | Est. runtime: ${mins:-?}m ${secs:-0}s | Load: ${load:-?}%"
}
monitor_loop() {
local ups="$1"
local pidfile="$PIDDIR/${ups%%@*}.pid"
# don't start a second loop for the same UPS
if [ -f "$pidfile" ] && kill -0 "$(cat "$pidfile" 2>/dev/null)" 2>/dev/null; then
return
fi
echo $$ > "$pidfile"
while true; do
sleep "$POLL_INTERVAL"
status=$(upsc "$ups" ups.status 2>/dev/null)
case "$status" in
*OB*)
send_notify "🪫 ${ups%%@*} still on battery [NUT]" "$(status_line "$ups")"
;;
*)
rm -f "$pidfile"
return
;;
esac
done
}
case "$1" in
on-battery)
send_notify "🪫 ${UPSNAME%%@*} is on Battery [NUT]" "$(status_line "$UPSNAME")"
( monitor_loop "$UPSNAME" & disown )
;;
online)
rm -f "$PIDDIR/${UPSNAME%%@*}.pid"
send_notify "🔋 ${UPSNAME%%@*} is no longer on Battery [NUT]" "Power restored. $(status_line "$UPSNAME")"
;;
esac
For the script to work, I had to modify the variables for the username/password to not include quotes.
Testing the script:
sudo UPSNAME=nutdev-usb1@localhost NOTIFYTYPE=ONBATT upssched ONBATT
sudo UPSNAME=nutdev-usb1@localhost NOTIFYTYPE=ONLINE upssched ONLINE

These look quite a bit better than before.
Testing the changes by unplugging the UPS and waiting for the notifications to come through. I also tested plugging it back in to see if the online notification worked:
