Connecting a UPS to an OpenWRT router and exposing it to a Synology NAS

A few months ago, I included an Uninterruptible Power Supply (UPS) to my setup at home. The intent was mainly that in case of a potential power loss, it should not only provide a better way to protect data stored on the Synology NAS, but also to prevent downtime as it is running some important services.

Even though power loss is not that frequent in my local area, I decided it would make sense after noticing some short interruptions in the middle of the nights. Sure, this should not prevent implementing a solid backup strategy (based on the well-known 3-2-1 rule), but can be seen as an additional protection measure.

Initially, the UPS was connected to the NAS directly over USB, and worked out-of-the-box. But due to a limited number of USB ports available on the NAS (where I also had other drives connected), I wondered if it was possible to leverage the OpenWRT router instead and expose the UPS information on the local network for any devices like the NAS that might need it. This is what led me to the nice Network UPS Tools (NUT) packages.

Topology

Below is a very quick overview of the topology I was aiming for:

┌───────────────┐                               
│    Internet   │                               
└───────┬───────┘                   Power Supply
        │ ▲                              │      
        ▼ │                              │      
┌─────────┴──────┐   USB    ┌─────┐      │      
│ OpenWRT Router ├──────────│ UPS ├──────┤      
└───┬───────────┬┘          └─────┘      │      
    │           │                        │      
    │           │                        │      
Ethernet        │                               
    │           │                               
    │      ┌────┴───────────┐                   
┌───┴───┐  │                │                   
│  NAS  │  │  Other devices                     
└───────┘  │                │                   
           └────────────────┘                   

OpenWRT

Connecting the UPS to the router

First of all, we need to make sure the UPS is recognized when connected to one of the router USB ports. After plugging it and connecting to the router (over SSH), we can leverage the dmesg command to quickly check this:

$ dmesg

[...]
[    3.674846] usb 2-1: new full-speed USB device number 2 using xhci-hc

To further verify the UPS device is properly detected, we can leverage the lsusb command from the usbutils package. Feel free to install this useful package (either with opkg or the new apk command, depending on your OpenWRT version):

$ opkg update
$ opkg install usbutils
$ lsusb

[...]
Bus 002 Device 002: ID 0463:ffff EATON Eaton 3S

As we can see from the output above, the Eaton UPS is properly detected on the router.

Installing the NUT packages

Network UPS Tools (NUT) is a set of packages that allow interacting with an UPS. We first need to install it, and if you have the LuCI admin web interface, there is a corresponding package which can be useful as well.

Note that it can either be run in server mode or in monitor mode. We will be running it in a server mode, since we want to expose the connected UPS to other devices in the local network.

We also need to install a NUT driver. There is a handful of drivers for specific UPS devices, but none for my Eaton 3S. So I simply installed the generic usbhid driver.

Here I am showing the command line, but feel free to install the packages using the LuCI admin web interface if you prefer.

$ opkg update
$ opkg install \
    nut nut-server \
    nut-upscmd \
    nut-avahi-service \
    nut-driver-usbhid-ups \
    nut-web-cgi \
    luci-app-nut

Configuring the NUT packages

Once install, you can reload the admin web interface and navigate to Services > Network UPS Tools.

From the NUT Server tab, here is what I had to do for the UPS to be recognized by the Synology NAS:

  1. Under the NUT Users section, I needed to hard-code the user to monuser, the password to secret and the role to Primary.
  2. The addresses the NUT Server should be listening on should include the router LAN address (10.10.10.254 in my case, but your mileage may vary), for the UPS to be accessible from the other devices on the LAN.
  3. The UPS in the configuration had to be named ups for it to be recognized in the Synology NAS

Below is an example of my working configuration (/etc/config/nut_server file):

# /etc/config/nut_server

config listen_address
        option address '127.0.0.1'

config listen_address
        option address '10.10.10.254'

config user
        option username 'monuser'
        option password 'secret'
        #list actions 'set'
        #list actions 'fsd'
        option upsmon 'master'

# config driver_global 'driver_global'

config driver 'ups'
        option driver usbhid-ups
        option port auto

config upsd 'upsd'

And a screenshot of what my settings look like from LuCI:

(Optional) NUT CGI

Optionally, if you installed the nut-web-cgi package, you would have an additional "NUT CGI" tab which you can configure and confirm that everything works as expected.

Here is my working configuration (/etc/config/nut_cgi file). Just make sure the UPS name provided matches the name provided in the NUT Server configuration (so ups in my case).

# /etc/config/nut_cgi

config upsset
        option enable '1'

config host
        # make sure the name here matches the UPS name set in
        # the 'config driver ...` in `/etc/config/nut_server`
        option upsname 'ups'
        option hostname 'localhost'
        option displayname 'Eaton 3S 700 FR'

And a screenshot of how the settings are reflected in the LuCI web interface:

To check that the connection with the UPS is correctly configured, you can click on the Go to NUT CGI link and login using your router admin credentials. You should be able to see the statistics of the UPS, like so:

Synology NAS

At this point, we are now ready to make the Synology NAS obtain the UPS information from the OpenWRT router running in the local network.

To do so, open the Control Panel from the Synology web interface, and head to Hardware & Power > UPS. Enable the UPS support and pick Synology UPS server as UPS type.

This type is documented like "another Synology product connected to a USB or SNMP UPS [...]", but it should not matter, since the NAS also appears to be using the NUT packages under the hood to communicate with the specified server. So the NAS will see the router as a Synology product.

To double-check, I edited the configuration file right on the NAS (over SSH):

# /etc/ups/upsmon.conf
MONITOR ups@10.10.10.254 1 monuser secret slave
  • ups is the UPS Name/ID defined in the router's nut_server file
  • 10.10.10.254 is the router IP address in the local network. I've not tested it, but this can reportedly be an IPv6 address too
  • The number 1 is a power value, i.e., the number of power supplies that this UPS feeds. Usually set to 1, unless you have a different UPS.
  • monuser is the username defined in the router's nut_server file
  • secret by the password defined in the router's nut_server file

You may want to restart your NAS after changing this file.

Back to the Control Panel, we can confirm that the settings are working by clicking on Device information.

Wrapping Up

This blog post walked through connecting an UPS device to an OpenWRT router and accessing the UPS information from a Synology NAS.

I always find it enjoyable when devices from different vendors can interoperate this way. In my opinion, this highlights the importance of using open-source tools for communication as a way to avoid vendor lock-in.

As usual, feel free to share your thoughts in the comments.