📆 2025-06-28 13:20
Do you have an UPS ? And a home lab? Awesome. This post is about configuring all your servers, raspberry pi's and even your gaming PC to shutdown gracefully in the event of a power outage.
The thing is that you can plug in the power cord for multiple devices in your UPS but, usually, an UPS comes with 1 data cable and, wait for it, a Windows application. With the USB data cable the UPS communicates with only one computer.
To connect all your computers/servers to the UPS you are going to install Nut. Also known as Network UPS Tools.
What is Nut
It's an open UPS networking monitoring tool that runs on many different operating systems.
This means you can run the server on Linux, MacOS, or BSD and run the client on Windows, MacOS and Linux. It works well for your Raspberry Pi, server, or desktop.
It works with a lot of UPS devices, PDUs and many other power management systems.
Visit Network UPS Tools website
Setting up the hardware
It's easy. Plug your UPS into an power outlet, plug all your devices power cords into the UPS, connect it's data cable to the server or whatever device you know you'll choose to shutdown last. SSH into it and
Install Nut Server and Nut Client
I have an Ace Magician Tiny PC which is also the cluster leader. I chose this one to be the leader and the last pc to shutdown in case of a power outage because it draws the smallest amount of power. So I connected the UPS to it. This tiny pc will have both the NUT server and NUT client installed on it.
Locate UPS and setup driver
make sure the UPS is shown:
sava@tiny:~$ lsusb
Bus 001 Device 003: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
If your UPS shows up you can
sudo apt update
sudo apt install nut nut-client nut-server
Use nut-scanner to scan for the UPS
You should get something like:
[nutdev1]
driver = "usbhid-ups"
port = "auto"
vendorid = "051D"
productid = "0002"
product = "Back-UPS ES 700G FW:871.O3 .I USB FW:O3"
serial = "5B**********"
vendor = "APC"
bus = "001"
device = "003"
busport = "002"
###NOTMATCHED-YET###bcdDevice = "0106"
Copy vendorit and productid as it's needed in the next step.
sudo pico /etc/nut/nut.conf
sudo pico /etc/nut/ups.conf
maxretry = 3
# Name your UPS in the [] below
#this name has to be present also in /etc/nut/upsmon.conf
#MONITOR apc@localhost 1 admin securepass master
[apc]
driver = usbhid-ups
port = auto
desc = "APC UPS"
### Your vendorid and productid
vendorid = 051d
productid = 0002
###
serial = 5B15********
sudo pico /etc/nut/upsd.conf
LISTEN 0.0.0.0 3493
# Listens on port 3493 on all interfaces
sudo pico /etc/nut/upsd.users
[admin]
password = securepass
actions = SET FSD
instcmds = ALL
upsmon master
[monitor]
password = securepass
upsmon slave
# First user - admin - can issue commands to the UPS
# Seconds user - monitor - can only read data from the UPS
sudo pico /etc/nut/upsmon.conf
RUN_AS_USER root
MONITOR apc@localhost 1 admin securepass master
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h"
NOTIFYCMD /usr/sbin/upssched
POLLFREQ 2
POLLFREQALERT 1
HOSTSYNC 15
DEADTIME 15
POWERDOWNFLAG /etc/killpower
NOTIFYMSG ONLINE "UPS %s on line power"
NOTIFYMSG ONBATT "UPS %s on battery"
NOTIFYMSG LOWBATT "UPS %s battery is low"
NOTIFYMSG FSD "UPS %s: forced shutdown in progress"
NOTIFYMSG COMMOK "Communications with UPS %s established"
NOTIFYMSG COMMBAD "Communications with UPS %s lost"
NOTIFYMSG SHUTDOWN "Auto logout and shutdown proceeding"
NOTIFYMSG REPLBATT "UPS %s battery needs to be replaced"
NOTIFYMSG NOCOMM "UPS %s is unavailable"
NOTIFYMSG NOPARENT "upsmon parent process died - shutdown impossible"
NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT SYSLOG+WALL+EXEC
NOTIFYFLAG FSD SYSLOG+WALL+EXEC
NOTIFYFLAG COMMOK SYSLOG+WALL+EXEC
NOTIFYFLAG COMMBAD SYSLOG+WALL+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXEC
NOTIFYFLAG REPLBATT SYSLOG+WALL
NOTIFYFLAG NOCOMM SYSLOG+WALL+EXEC
NOTIFYFLAG NOPARENT SYSLOG+WALL
RBWARNTIME 43200
NOCOMMWARNTIME 600
FINALDELAY 5
sudo pico /etc/nut/upssched.conf
CMDSCRIPT /bin/upssched-cmd
PIPEFN /etc/nut/upss/upssched.pipe
LOCKFN /etc/nut/upss/upssched.lock
# Send alerts immediately on change in line power
AT ONBATT * EXECUTE onbatt
AT ONLINE * EXECUTE onpower
# Silence the UPS beeper after 1 minutes
AT ONBATT * START-TIMER mute_beeper 60
AT ONLINE * CANCEL-TIMER mute_beeper
# Shutdown after 20 seconds if battery is critical
AT LOWBATT * START-TIMER critical_shutdown 20
# Cancel shutdown timer if power's restored
AT ONLINE * CANCEL-TIMER critical_shutdown
# Starts a timer on communication failure with the UPS
AT COMMBAD * START-TIMER commbad_timer 120
# Cancels the communication failure timer when communication is restored
AT COMMOK * CANCEL-TIMER commbad_timer
# Executes shutdown on persistent communication failure
AT NOCOMM * EXECUTE commbad_shutdown
AT SHUTDOWN * EXECUTE powerdown
sudo pico /bin/upssched-cmd
#!/bin/sh
case $1 in
onbatt)
logger -t upssched-cmd "UPS running on battery. Battery is now discharging."
;;
onpower)
logger -t upssched-cmd "UPS running on mains. Battery is now charging."
;;
mute_beeper)
upscmd -u admin -p securepass apc@server.ip.address beeper.mute
logger -t upssched-cmd "1 minute limit exceeded, muting beeper"
;;
commbad_timer)
logger -t upssched-cmd "UPS communication failure persists, initiating shutdown"
/usr/sbin/upsmon -c fsd
;;
commbad_shutdown)
logger -t upssched-cmd "UPS communication failed! Shutting down!"
/sbin/upsmon -c fsd
;;
critical_shutdown)
logger -t upssched-cmd "UPS battery is almost empty. Shutting down"
/sbin/upsmon -c fsd
;;
powerdown)
logger -t upssched-cmd "Executing powerdown command"
;;
*)
logger -t upssched-cmd "Unrecognized command: $1"
;;
esac
Remember to make it executable
chmod +x /bin/upssched-cmd
We're done setting up the main computer ( the one connected to the UPS with the USB data cable) !
Setting up NUT client on network computers / workers
I have 3 Lenovo M53's and 1 Lenovo ThinkStation P510 as workers of my cluster. A 5 port switch is also plugged in and connects the Lenovo's to my main router.
🗄️ My Cluster information
I chose to shutdown these network computers/workers if the UPS is running on battery for 2 minutes and mains power did not return or the communication to the UPS has been lost for 2 minutes. This way I keep most of my UPS battery charge for my modem, router, switch and Ace Magician/Master.
sudo apt update
sudo apt install nut-client
sudo pico /etc/nut/nut.conf
sudo pico /etc/nut/upsmon.conf
RUN_AS_USER root
##################################################
# Make sure to enter the UPS name, the ip of the
# computer connected via USB cable and
# monitor user and pass configured in
# /etc/nut/upsd.users
##################################################
MONITOR apc@server.ip.address 1 monitor securepass master
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h"
NOTIFYCMD /usr/sbin/upssched
POLLFREQ 2
POLLFREQALERT 1
HOSTSYNC 15
DEADTIME 15
POWERDOWNFLAG /etc/killpower
NOTIFYMSG ONLINE "UPS %s on line power"
NOTIFYMSG ONBATT "UPS %s on battery"
NOTIFYMSG LOWBATT "UPS %s battery is low"
NOTIFYMSG FSD "UPS %s: forced shutdown in progress"
NOTIFYMSG COMMOK "Communications with UPS %s established"
NOTIFYMSG COMMBAD "Communications with UPS %s lost"
NOTIFYMSG SHUTDOWN "Auto logout and shutdown proceeding"
NOTIFYMSG REPLBATT "UPS %s battery needs to be replaced"
NOTIFYMSG NOCOMM "UPS %s is unavailable"
NOTIFYMSG NOPARENT "upsmon parent process died - shutdown impossible"
NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC
NOTIFYFLAG LOWBATT SYSLOG+WALL+EXEC
NOTIFYFLAG FSD SYSLOG+WALL+EXEC
NOTIFYFLAG COMMOK SYSLOG+WALL+EXEC
NOTIFYFLAG COMMBAD SYSLOG+WALL+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXEC
NOTIFYFLAG REPLBATT SYSLOG+WALL
NOTIFYFLAG NOCOMM SYSLOG+WALL+EXEC
NOTIFYFLAG NOPARENT SYSLOG+WALL
RBWARNTIME 43200
NOCOMMWARNTIME 600
FINALDELAY 5
sudo pico /etc/nut/upssched.conf
CMDSCRIPT /bin/upssched-cmd
PIPEFN /etc/nut/upssched.pipe
LOCKFN /etc/nut/upssched.lock
# Starts a timer when the UPS switches to battery power
AT ONBATT * START-TIMER shutdown_timer 120
# Cancels the shutdown timer when power is restored
AT ONLINE * CANCEL-TIMER shutdown_timer
#############################################
# These 2 actions are here just in case your
# UPS battery is faulty and discharges very fast
# Shutdown if battery is critical
AT LOWBATT * START-TIMER critical_shutdown 20
# Cancel timer if power's restored
AT ONLINE * CANCEL-TIMER critical_shutdown
#############################################
# Starts a timer on communication failure
AT COMMBAD * START-TIMER commbad_timer 120
#AT COMMBAD * EXECUTE commbad_timer
# Cancels the communication failure timer when communication is restored
AT COMMOK * CANCEL-TIMER commbad_timer
# Executes shutdown on persistent communication failure
AT NOCOMM * EXECUTE commbad_shutdown
# Executes powerdown on system shutdown
AT SHUTDOWN * EXECUTE powerdown
sudo pico /bin/upssched-cmd
#!/bin/sh
case $1 in
shutdown_timer)
logger -t upssched-cmd "UPS is on battery. Shutting down in 2 minutes if power is not restored!"
/sbin/upsmon -c fsd
;;
critical_shutdown)
logger -t upssched-cmd "Triggering shutdown in 20 seconds because battery is critical!"
/sbin/upsmon -c fsd
;;
commbad_timer)
logger -t upssched-cmd "UPS communication failure persists, initiating shutdown"
/usr/sbin/upsmon -c fsd
;;
commbad_shutdown)
logger -t upssched-cmd "UPS communication failed! Shutting down to be safe!"
/sbin/upsmon -c fsd
;;
powerdown)
logger -t upssched-cmd "Executing powerdown command"
;;
*)
logger -t upssched-cmd "Unrecognized command: $1"
;;
esac
What happens when a power outage occurs
My UPS battery can keep my cluster online with all computers, modem, switch and router turned on for about 15 minutes. If I shutdown the 3 Lenovo M53's and the P510 after 2 minutes, the battery can hold my Ace Magician Tiny, modem and router for about 35 minutes.
What NUT client does on the computer connected to the UPS with the data cable
Power goes down. What NUT server does:
- starts a timer for 60 seconds to mute the buzzer - this means that the UPS will buzz for only 1 minute when power goes down. Trust me, you don't want to hear that buzzer for 35 minutes straight.
- all NUT clients are notified that the UPS is running on battery (including the Ace Magician Tiny that runs the server)
- initiates a shutdown only if the UPS battery reaches 10%
- the remaining 10% are used only by my modem and router after this point in hope that mains power returns.
What NUT client does on the other connected devices
- receives the notification that the UPS is running on battery
- waits for 2 minutes. If the UPS is still on battery power it will initiate a shutdown on the Lenovo's. As I mentioned earlier, I chose to run the 4 worker nodes ( Lenovo ) for only 2 minutes to conserve the UPS battery.
Here's a diagram on how my cluster is connected and behaves in case of a power outage.
Be sure to click the image that coresponds to your light/dark preference.
Cluster diagram [light]
Cluster diagram [dark]
I've also created a GitHub repo containing all these files.
Nut Config on GitHub/SavaAlexandruStefan
It may be easier for you to just clone the repo and copy the files to /etc/nut/
🚶 Back to my blog