Handling power outages with an uninterruptible power supply and NUT

The main reason for having a UPS is to protect against data loss due to power outages whether it be unsaved work, or corruption due to the computer not having enough time to write things to disk. I only really started to take this seriously when I got my Synology networked attached storage (NAS) which holds all my data.

The UPS I chose is an APC model with 1300VA and a USB connection, which is powerful enough to power most of the critical equipment I have at home and to ensure they have enough time to shut down. One of the advantages of having an uninterruptible power supply (UPS) with a USB connection is that it is possible to smartly shut down any computers during a power outage.

My strategy is when the UPS goes on battery, I want the Windows PC and Linux server to shut down immediately (well after a 1 minute timeout). These are the heaviest load (roughly 100W each on idle) on the UPS and they aren’t running anything really important that I need during a power outage; they just need to shutdown cleanly. The Synology NAS is a lighter load so I don’t mind keeping that one on and only shut it down when the UPS battery is low. Keeping the cable modem and wireless router allows me to continue to have network access which is critical for NUT to work, but also for general productivity in case of a prolonged failure). I’ve found in past outages that the cable equipment in my apartment building has some sort of separate or backup power source as well so generally the internet can continue to work. With just the cable modem, router and Synology the power draw is about 50W. I can manually shut down the NAS if I want to prolong the network even further.

What’s this NUT you keep talking about?

NUT stands for Network UPS Tools which are a set of utilities that are cross platform and cross manufacturer that monitors and responds to changes in UPS statuses. As we will see in the following sections, Synology NAS already has built in support for NUT, and NUT tools can be installed on Windows and Linux.

Configuring the Synology NAS as NUT master

Although the UPS can power many computers, there is typically only one USB cable, which means that only one computer will be able to communicate with the UPS regarding its status. In my case, this will be the Synology NAS, and it is called the “master”. Other “NUT slaves” or “clients” will connect to the master in order to get updates about the UPS status.

As I mentioned before, Synology DiskStation Manager already has support for this, so go to Control Panel → Hardware & Power → UPS.

You’ll want to click “Enable UPS Support” and “Enable network UPS server”. In “Permitted DiskStation Devices”, add the IP addresses of the other devices that will be controlled by this NUT master. Apply the changes. If you click “Device Information”, it should show you the information about your UPS status.

Allowing access to the daemon from the network

One issue that I’ve found with the Synology configuration is that upsd (the NUT daemon) only listens for local connections. However, we want the daemon to be accessible by other devices on the network. The way I worked around this is by adding the following as a boot up task to the Task Scheduler in Synology’s control panel:

# Reconfigure upsd so that it listens on the network.
printf "LISTEN 127.0.0.1\nLISTEN 10.0.0.123\n" > /usr/syno/etc/ups/upsd.conf
/usr/sbin/upsd -c stop
/usr/sbin/upsd

Replace 10.0.0.123 with the IP address of your NAS. Also, I’m not really going into detail about security here; you will need to consider that yourself for your own circumstances.

Perhaps there is something that I am just missing, so if you know a way where this is not necessary, please do let me know in the comments.

Setting up Windows as a NUT client

The official place I’d look for a client is on the NUT website, however some of those links are out of date. Also there seems to be a newer Windows client in the works, but it’s not listed on the official site. The version I settled on is the older WinNUT 2.0.0.4a available here. It is old, but it still works to this day.

The main configuration tool looks like this:

The main thing after installing is that you need to press “Edit” beside the Configuration File Path option in order to configure where WinNUT is to connect. The configuration file is a bit ugly, but you just need to add the following line to the file (it doesn’t really matter where, but it’s “nicer” if it’s in the place where it talks about the MONITOR configuration.

MONITOR [email protected] 1 monuser secret slave

Just change 10.0.0.123 again to your NUT master’s IP address. For a Synology NAS, the [email protected], monuser and secret are the values that are configured by default.

I’d recommend installing WinNUT as a service and having it started automatically.

When you’re done the above configuration, click on “Apply and Start WinNUT”. You should see “Status: Running as a Service”. If you click on “View” beside the “Log File Path”, you should see something like this which indicates proper communication with the NAS.

Level     INFO	04/10/2021 15:19:21	Detected OS as Windows NT
Level   NOTICE	04/10/2021 15:19:21	Network UPS Tools upsmon 2.0.0.4
Level     INFO	04/10/2021 15:19:21	UPS: [email protected] (slave) (power value 1)
Level     INFO	04/10/2021 15:19:21	Config Load: MINSUPPLIES set to 1
Level     INFO	04/10/2021 15:19:21	Config Load: NOTIFYCMD set to "c:\Program Files\WinNUT\alertPopup.exe"
Level     INFO	04/10/2021 15:19:21	Config Load: POLLFREQ set to 5
Level     INFO	04/10/2021 15:19:21	Config Load: POLLFREQALERT set to 5
Level     INFO	04/10/2021 15:19:21	Config Load: HOSTSYNC set to 15
Level     INFO	04/10/2021 15:19:21	Config Load: DEADTIME set to 15
Level     INFO	04/10/2021 15:19:21	Config Load: RBWARNTIME set to 43200
Level     INFO	04/10/2021 15:19:21	Config Load: NOCOMMWARNTIME set to 300
Level     INFO	04/10/2021 15:19:21	Config Load: FINALDELAY set to 5
Level    ALERT	04/10/2021 15:19:21	WinNUTUpsMon Service is starting to monitor UPS

Configuring a Debian/Ubuntu/Proxmox server as a NUT client

The remaining computer I would like to shut down is my Proxmox host, which is basically a Debian server, so also any Debian derivative should be able to be configured like this.

First, install NUT by running:

apt install nut-client

The initial installation will report that the service wasn’t able to be started, but that is fine because we need to configure it first.

In /etc/nut/nut.conf, we need to change the last line to the following:

MODE=netclient

This tells NUT to access the UPS status using another network server (rather than having the UPS USB directly connected to the computer).

In /etc/nut/upsmon.conf, add the following lines where appropriate:

MONITOR [email protected] 1 monuser secret slave

Just change 10.0.0.123 again to your NUT master’s IP address. For a Synology NAS, the [email protected], monuser and secret are the values that are configured by default.

Start the service by running:

systemctl start nut-monitor

There shouldn’t be any message or errors. You can check the status in /var/log/syslog. The logs should look like this for a successful startup:

Apr 10 15:36:12 cypress systemd[1]: Starting Network UPS Tools - power device monitor and shutdown controller...
Apr 10 15:36:12 cypress upsmon[22164]: fopen /var/run/nut/upsmon.pid: No such file or directory
Apr 10 15:36:12 cypress upsmon[22164]: UPS: [email protected] (slave) (power value 1)
Apr 10 15:36:12 cypress upsmon[22164]: Using power down flag file /etc/killpower
Apr 10 15:36:12 cypress upsmon[22165]: Startup successful
Apr 10 15:36:12 cypress systemd[1]: nut-monitor.service: Can't open PID file /run/nut/upsmon.pid (yet?) after start: No such file or directory
Apr 10 15:36:12 cypress systemd[1]: nut-monitor.service: Supervising process 22166 which is not our child. We'll most likely not notice when it exits.
Apr 10 15:36:12 cypress upsmon[22166]: Init SSL without certificate database
Apr 10 15:36:12 cypress systemd[1]: Started Network UPS Tools - power device monitor and shutdown controller.

You can also check the status of the UPS connection by using the upsc utility. For example the following command will grab the current status of the UPS over the network:

[email protected]:/var/log# upsc [email protected]
Init SSL without certificate database
battery.charge: 75
battery.charge.low: 10
battery.charge.warning: 50
battery.date: 2001/09/25
battery.mfr.date: 2015/08/09
battery.runtime: 432
battery.runtime.low: 120
battery.type: PbAc
battery.voltage: 27.2
battery.voltage.nominal: 24.0
device.mfr: American Power Conversion
device.model: Back-UPS XS 1300G
device.serial: 3B1532X20535
device.type: ups
driver.name: usbhid-ups
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 5
driver.parameter.port: auto
driver.version: DSM6-2-25510-201118
driver.version.data: APC HID 0.95
driver.version.internal: 0.38
input.sensitivity: medium
input.transfer.high: 139
input.transfer.low: 88
input.transfer.reason: input voltage out of range
input.voltage: 119.0
input.voltage.nominal: 120
ups.beeper.status: enabled
ups.delay.shutdown: 20
ups.firmware: 864.L8 .D
ups.firmware.aux: L8
ups.load: 29
ups.mfr: American Power Conversion
ups.mfr.date: 2015/08/09
ups.model: Back-UPS XS 1300G
ups.productid: 0002
ups.realpower.nominal: 780
ups.serial: 3B1532X21234
ups.status: OL CHRG
ups.test.result: No test initiated
ups.timer.reboot: 0
ups.timer.shutdown: -1
ups.vendorid: 051d

Shutdown immediately after on UPS battery

By default NUT will only shutdown when forced to by the master (generally when the power is low). But in my circumstance, I want to shut this computer down immediately in order to prolong the battery life.

In /etc/nut/upsmon.conf, add the following lines where appropriate:

NOTIFYCMD /etc/nut/notifycmd
NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC
NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC

Create the file /etc/nut/notifycmd with the following contents (I found this script from this “Stuart’s Notes” blog post):

#!/bin/bash
#
# NUT NOTIFYCMD script

PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/sbin:/usr/local/bin

trap "exit 0" SIGTERM

if [ "$NOTIFYTYPE" = "ONLINE" ]
then
        echo $0: power restored | wall
        # Cause all instances of this script to exit.
        killall -s SIGTERM `basename $0`
fi

if [ "$NOTIFYTYPE" = "ONBATT" ]
then
        echo $0: 1 minutes till system powers down... | wall
        # Loop with one second interval to allow SIGTERM reception.
        let "n = 60"
        while [ $n -ne 0 ]
        do
                sleep 1
                let "n--"
        done
        echo $0: commencing shutdown | wall
        upsmon -c fsd
fi

Make the script executable by nut:

chmod a+x /etc/nut/notifycmd

Restart NUT to pick up the new changes:

systemctl restart nut-monitor

(The more proper way is probably to use upssched instead of a custom NOTIFYCMD script, but for something simple it works.)

Test the setup from time to time

One lesson I learned is that the UPS setup should be tested every now and then to ensure that all the parts are still working. The reason this was my focus today was because yesterday I had an extended power outage. It turns out there were multiple problems with my previous setup:

  • For some reason the Synology NAS was not allowing external connections from the network (resolved with the Task Scheduler script above), so even though the Windows PC was configured correctly, it couldn’t communicate with the master.
  • The Linux server (relatively new addition to the network) didn’t have NUT installed, but it was on the NAS. In addition, it wasn’t connected to a UPS-backed switch so I couldn’t easy remotely shut it down.

My focus was also in a work meeting during that time, so needless to say with 2 PCs on, the UPS didn’t last more than 10 minutes.

Leave a Reply

Your email address will not be published. Required fields are marked *