URI: 
       Installing and configuring NUT(Network UPS Tools) for your home lab
       
       Published on : 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.
       
  HTML 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
       
           lsusb
       
       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
       
           sudo nut-scanner -U
       
       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.
       
        - Configure Nut Server and Client on the connected PC via USB
       
       sudo pico /etc/nut/nut.conf
       
           MODE=netserver
       
       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"
       
           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.
       
   DIR  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
       
           MODE=netclient
       
       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
       
        * 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.
       
        * 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 thi
       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.
       
   IMG  Cluster diagram [light]
   IMG  Cluster diagram [dark]
       
       I've also created a GitHub repo containing all these files.
       
  HTML Nut Config on GitHub/SavaAlexandruStefan
       
       Because of Gopher's 67 character per line limit some code above
       has been truncated manually by me by adding line breaks in order 
       to be pretty. If you copy/paste the code from this page some 
       errors might occur.
       
       It may be easier for you to just clone the GitHub repo above, copy 
       the files to /etc/nut/ and modify them after.
       
       
   DIR  Back to my phlog