Uninterruptible Power Supply

Posted on 4 2026

Network UPS Tools (NUT) is a client/server system for monitoring UPS devices and coordinating safe shutdowns across multiple machines. The UPS is physically connected to one machine, which runs the NUT server and monitors the battery state. All other machines on the network run NUT clients. When the server detects a critical battery condition, it instructs all clients to shut down cleanly before the power cuts entirely.

In this network’s architecture:

  • The homelab server (February) is the NUT primary. The APC UPS is connected to it via USB. It monitors the UPS and informs all other devices of the power state.
  • The desktop (Kubuntu) is a NUT secondary client. It connects to the NUT server over the network, receives power state updates, and shuts down cleanly when instructed.
  • The NAS is also a secondary client, handled in the NAS section of this series.

The NUT server setup on the homelab is covered in the server section. This page covers the desktop client configuration only.

Installing the NUT client

sudo apt install nut-client

This installs upsmon and the associated client utilities without the server components.

Configuring upsmon

The desktop’s NUT configuration lives in /etc/nut/. Only two files are needed for a client-only setup.

/etc/nut/nut.conf

This file tells NUT what role this machine plays:

sudo tee /etc/nut/nut.conf << 'EOF'
# /etc/nut/nut.conf
# This machine is a NUT client only (netclient mode)
MODE=netclient
EOF

/etc/nut/upsmon.conf

This file tells upsmon where to find the NUT server and what to do during power events:

sudo tee /etc/nut/upsmon.conf << 'EOF'
# /etc/nut/upsmon.conf
# NUT client configuration for Kubuntu desktop

# Drop privileges to the nut user after startup
RUN_AS_USER nut

# UPS to monitor
# Format: upsname@hostname[:port] powervalue username password type
# powervalue 1 = this machine has 1 power supply connected to this UPS
# type = secondary (this machine is a client, not the server)
MONITOR apc@server.yourdomain.net 1 upsmon-secondary <password> secondary

# Minimum number of power supplies that must be receiving power
MINSUPPLIES 1

# Command to run when shutting down
SHUTDOWNCMD "/bin/systemctl poweroff"

# Notification command (optional, for alerts)
# NOTIFYCMD "/usr/sbin/upssched"

# Delay between polling the UPS
POLLFREQ 5
POLLFREQALERT 5

# Maximum time to wait for the primary to acknowledge shutdown
HOSTSYNC 15

# How long to wait before declaring the primary dead
DEADTIME 15

# Power down the UPS after shutdown (set to 0 for client-only)
POWERDOWNFLAG /etc/killpower

# Notification settings
NOTIFYFLAG ONLINE    SYSLOG+WALL
NOTIFYFLAG ONBATT    SYSLOG+WALL
NOTIFYFLAG LOWBATT   SYSLOG+WALL
NOTIFYFLAG FSD       SYSLOG+WALL
NOTIFYFLAG COMMOK    SYSLOG
NOTIFYFLAG COMMBAD   SYSLOG
NOTIFYFLAG SHUTDOWN  SYSLOG+WALL
NOTIFYFLAG REPLBATT  SYSLOG+WALL
NOTIFYFLAG NOCOMM    SYSLOG+WALL
NOTIFYFLAG NOPARENT  SYSLOG

# Notification messages
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"
NOTIFYMSG COMMOK    "UPS %s communications established"
NOTIFYMSG COMMBAD   "UPS %s communications lost"
NOTIFYMSG SHUTDOWN  "Desktop shutting down"
NOTIFYMSG REPLBATT  "UPS %s battery needs replacing"
NOTIFYMSG NOCOMM    "UPS %s is unavailable"
NOTIFYMSG NOPARENT  "upsmon parent process died"

# Minimum seconds to wait before polling after a state change
RBWARNTIME 43200

# Seconds before an apparent battery fault causes action
NOCOMMWARNTIME 300
FINALDELAY 5
EOF

Replace server.yourdomain.net with the actual hostname or IP address of your NUT server, and <password> with the upsmon-secondary password configured on the server.

Set correct permissions:

sudo chown -R root:nut /etc/nut
sudo chmod 0770 /etc/nut
sudo chmod 0640 /etc/nut/*

Starting and enabling upsmon

sudo systemctl enable --now nut-monitor

Check the status:

sudo systemctl status nut-monitor

The service should show as active. Check the journal for any connection errors:

sudo journalctl -u nut-monitor -f

Testing the connection

Query the UPS via the NUT server:

upsc apc@server.yourdomain.net

This should return a list of UPS variables including battery charge, load percentage, input voltage, and status. A successful response confirms the desktop can reach the NUT server and authenticate.

Check the current UPS status specifically:

upsc apc@server.yourdomain.net ups.status

Common status values:

StatusMeaning
OLOn line (mains power)
OBOn battery
LBLow battery
OL CHRGOn line, battery charging
OL DISCHRGOn line, battery discharging (unusual)
FSDForced shutdown initiated

Graphical monitoring: KNutClient

KNutClient is the KDE-native graphical client for monitoring NUT-connected UPS devices. It displays battery charge, load, voltage, and temperature in a live dashboard.

sudo apt install knutclient

Open KNutClient from the application launcher. Configure the connection:

  • Host: server.yourdomain.net
  • Port: 3493 (default NUT port)
  • UPS name: apc
  • Username: upsmon-secondary
  • Password: the secondary password from the server configuration

KNutClient displays real-time UPS telemetry and can be configured to show alerts when the UPS switches to battery.

System tray monitoring

For a lightweight system tray indicator showing UPS status without the full KNutClient dashboard, the nut-monitor utility provides a GNOME/Python-based tray icon that also works on KDE Plasma:

sudo apt install nut-monitor

Run it from the application launcher or add it to KDE autostart. It displays battery percentage and status in the system tray and shows a notification when the UPS switches to battery.

What happens during a power event

When the mains power fails:

  1. The UPS switches to battery and notifies the NUT server
  2. The server broadcasts the ONBATT event to all connected clients
  3. upsmon on the desktop logs the event and sends a wall notification
  4. If the battery drops to the low battery threshold, the server broadcasts LOWBATT
  5. The server instructs all secondaries to shut down by broadcasting FSD (Forced Shutdown)
  6. upsmon on the desktop runs SHUTDOWNCMD (systemctl poweroff)
  7. Once all secondaries have confirmed shutdown, the primary shuts down and instructs the UPS to cut power

The desktop never loses data: it shuts down cleanly with all processes closed before the power cuts. The HOSTSYNC value (15 seconds) is how long the primary waits for secondaries to acknowledge the shutdown before proceeding anyway.

Adjusting shutdown timing

The timing of when the desktop shuts down relative to the battery level is controlled on the server side, not the client side. The NUT server configuration sets the LOWBATT threshold and the HOSTSYNC timer. If the desktop needs more time to close running applications before shutdown, increase HOSTSYNC in the server’s upsmon.conf.

For a desktop that regularly has long-running processes (a video render, a large file copy), consider increasing HOSTSYNC to 60 seconds to give those processes time to reach a stable checkpoint before the forced shutdown.

The password in /etc/nut/upsmon.conf is stored in plaintext. The file permissions (640, root:nut) are the minimum. Store the password in KeePassXC and ensure it is different from any other credentials in the setup.