I have an APC UPS, and initially my Synology NAS had full control over it. Most UPS’s have a USB port so you can plug it in to a device and get statistics and shut it down before the UPS runs out of battery. I wanted to expand this from just my NAS to all of my devices connected to the UPS. I have my router, Synology NAS, a Raspberry Pi, and a mini PC running Proxmox all connected. Getting this done is scattered all over the place and confusing, so I will try and simplify it all into one.
Getting it to work on pfSense
You need to install the nut package at a minimum. You may have to install the apcupsd package if you can’t get a connection with the usbhid driver when using Local USB. I do not recommend the apcupsd package as it is quite unreliable. If you are able to get a connection with usbhid driver, please use that instead. If you are able to get a connection with the usbhid driver, please skip the rest of the section. The next three paragraphs are for if you CANNOT get the Local USB working.
If you need to use apcupsd, the apcupsd package will communicate with the UPS. The NUT server will use the remote apcupsd driver to get information about the NAS, and make it available for any clients running NUT as well. You will want to plug in the UPS to the USB port, and set the UPS cable and UPS type to both usb. You can leave the device field blank. This is the only configuration you should need to do on apcupsd. You can go to the Status tab and you should see your UPS is recognized.
Now, you can go to the Services > UPS tab and click on UPS Settings. For the UPS type, set it to “Remote apcupsd”. Set the ups name to “ups”. You will need to make sure this is the name if you intend to have it interface with a Synology NAS.
For the “Remote IP address or hostname” under the Driver settings, you can put that as 127.0.0.1. The apcupsd and NUT server are on the same machine, your pfSense box. You should now be able to go to “UPS Status” and it should connect and you should see various fields like the runtime.
Getting it to work with Synology
You’ll want to go to your Control Panel > Hardware and Power > UPS. You will want to use “Synology UPS server”. For the Network UPS server IP, put your pfSense IP address. If you try and hit save, it won’t work yet. What we have to understand is that pfSense will be our master and the Synology will be a slave. Synology is looking on pfSense for some hardcoded and default user credentials with the NUT protocol to establish a connection.
The defaults are the following:
UPS name: ups
Username: monuser
Password: secret
We can take this information and put it on pfSense and then the Synology will think it’s communicating with another Synology, even though it’s pfSense. Under the hood, it’s just the NUT protocol, but with Synology branding and some hardcoded defaults.
On your pfSense device, go back to the UPS tab and UPS settings. Under the advanced tab, add the following to the upsd.users
file:
[monuser]
password = secret
upsmon slave
We also need to tell pfSense to listen on its LAN IP address, not just on localhost. On the additional configuration for the upsd.conf
file, add the LISTEN keyword followed by your pfSense’s local IP address. Mine is the following:
LISTEN 192.168.2.1
You can now hit Save. At the top of the page where the “Services / UPS / Settings” text is, to the right of it, you should see some icons. Click the first one, which will restart the service. Hitting Save is not good enough, we need to actually restart the service.
You can now go back to the Synology, and reenter your settings. This time, it should connect successfully.
Finishing the pfSense configuration
YOU DO NOT NEED TO FOLLOW THIS SECTION IF YOU ARE USING LOCAL USB. THIS SECTION IS FOR IF YOU’RE USING APCUPSD!!!
We want pfSense to be our master for the rest of our NUT clients. The other NUT clients will be slaves. The will be the ones to shut down first. We need to add another pfSense user that has admin privileges, and tell pfSense to monitor itself using NUT.
Under upsd.users
, add the following:
[pfsense]
password = changeme
actions = SET
instcmds = ALL
upsmon master
We now need to add the following under upsmon.conf
:
MONITOR [email protected] 1 pfsense changeme master
This line is what tells the NUT server to monitor itself. The syntax is <ups name>@<ip of NUT server>. The 1 tells the monitor how many power supplies pfSense has. Mine only has one, but if you’re running pfSense on a fancy server with multiple power supplies, you should adjust the 1 accordingly. The “pfsense” and “changeme” is simply the username and password we just defined in the upsd.users
file. The master keyword signifies that it is a master.
Making pfSense shutdown last
I personally prefer to make pfSense shut down last. This can be done very easily. In the upsmon.conf
file, simply add the following
FINALDELAY 60
This will delay the shutdown by the time you specify in seconds. This has different behavior on apcupsd versus usbhid. On usbhid, it will wait to trigger the shut down until the UPS battery is low. On apcupsd, it will send the shutdown trigger immediately. The reason for this is because usbhid has actual metrics and can read the battery data. It knows when the battery is low. apcupsd does not, it thinks the UPS is dead as soon as power lost, thus sending the shutdown trigger immediately. If you’re using apcupsd, you may want to increase this to something higher like 5 minutes, since the battery isn’t actually low yet. On usbhid, I would do a minute, since the battery will be almost fully depleted. Note that the default time is 5 seconds, and I would recommend that being the case for your clients. The 5 second delay is a delay after the shutdown trigger is sent.
Adding other Linux clients
I will now add my Raspberry Pi as a client. This will require me to add a new user to the upsd.users
file on pfSense, and install the nut package on my Raspberry Pi.
In upsd.users
, you can add a new user that is a slave by adding the following:
[pi]
password = changeme
upsmon slave
You can now save and restart the UPS service on pfSense. The rest will now be on the Raspberry Pi. First, install the nut package:
sudo apt install nut
In /etc/nut/nut.conf
, change the MODE to netclient:
MODE=netclient
In /etc/nut/upsmon.conf
, you should add this to the end of your file:
MONITOR [email protected] 1 pi changeme slave
Replace the 192.168.2.1 with your pfSense IP address. The syntax is the same as mentioned above. We are connecting to a UPS with the name ups on 192.168.2.1. The Raspberry Pi has one power supply. The username is pi and the password is changeme. It is marked as a slave because it should shut down before the router. You can modify any of the other settings such as the shutdown command and how long it should wait before actually shutting down. By default, it is 5 seconds.
You should now be able to enable and start the services:
systemctl enable --now nut-monitor
systemctl start nut-client
You can also verify you have a working connection with the upsc
command. For me, it would look like
upsc [email protected]
Testing everything
You should now be able to test everything. I personally have an SSH connection to the Raspberry Pi open, and have a constant ping going to my Synology, pfSense, and Raspberry Pi. This should help you track if everything is shutting down. This is also why I let my pfSense router run for longer. It allows my computer to ping the devices and watch them shut down for easy debugging. You can also look at the physical devices to see if they shut down. Are there any lights blinking on the Ethernet port? Are there any power lights on? The Synology status light will blink to indicate that it has unmounted the disks because it detected the UPS was on battery mode. Once everything has shut down, you can press the power button on your UPS to completely kill the power. Press it again and everything should spin back up to life from a graceful shutdown.
You should do a full test of every VM / device you have and see how it all works after botting up from cold all at once. One issue I noticed was my Emby VM started up before my NAS booted. The media drives on my NAS weren’t available yet so the Emby VM wasn’t able to mount them. It’s important to test everything after a power outage. Finding edge cases like this will help you prepare for what to anticipate. It also will cut down on debugging time. Imagine if I tried to use Emby weeks after doing the power test and tried a bunch of other debugging when it was simply due to Emby booting before the NAS.
Issues with apcupsd
Unfortunately, there is one issue I encountered with apcupsd. pfSense has an issue where you need to restart the NUT server after the pfSense router has rebooted. It seems like it can’t establish a connection on boot and it gives up. You need to manually restart the service if you’re using apcupsd. Again, I do not recommend using apcupsd if you can help it. It is an old an unreliable package. It requires more complex configuration than needed. I did not have this problem with the usbhid driver.
A way you can avoid using the apcupsd package is by plugging the UPS into the Synology and adding the pfSense router as an allowed Synology device. Then set the UPS type to “Remote NUT server”. You can then put the Synology IP address and set the username to monuser and the password to secret. This will establish a connection to pfSense. The downside is that every client must use the monuser/secret username and password. There have also been reported issues of devices preemptively shutting down when there is a blip in power, rather than when the battery is low.
If you cannot get the NUT server working with usbhid over Local USB, you will have to decide which option works better for you and what tradeoffs you’re willing to make. The world of UPS’s and getting them to reliably communicate with devices can be a challenge. There are many different brands that offer different levels of support with NUT, and every brand and model can behave differently. All of this was written for the APC Back-UPS 600VA, but your UPS may behave completely differently.