Raspberry Pi as UPS server via the NUT

I bought a CyberPower CP1500PFCLCD UPS for my new built NAS. I didn’t get the optional RMCARD205 card which is at the time of this writing cost $160 on Amazon. I could get a new UPS with that price, so I opted out and sticking with the USB option.

Now, as the title says, I am going to be using the Network UPS Tool (NUT) to keep tabs of my UPS and notify me via email when an event occurred. I have a Raspberry 3B that is laying around and want to make good use out of it.

This post assumes that you already have the following:

  • A spare Raspberry Pi 3B(+) or 4B
  • A UPS with a USB
  • MSMTP installed (for notification)

In Figure 1, I am only going to be working on the NAS Nut Client and the RPi NUT Server. The drawing shows the physical layout. The servers are connected to the UPSes and they are connected the NUT server via the network LAN. If there is a firewall between the NUT server and NUT clients, make sure to allow the port 3493/tcp.

Figure 1

Installing the NUT software will complain that the service failed to start. This is normal. The NUT needs to be configured first before we can start the service. The error that I am talking about is below.

nut-monitor.service: Can't open PID file /run/nut/upsmon.pid (yet?) after start: No such file or directory
nut-monitor.service: Failed with result 'protocol'.
Failed to start Network UPS Tools - power device monitor and shutdown controller.

Install the NUT software via the apt.

sudo apt install nut nut-server nut-client

Plug the USB cable from the UPS to the Raspberry Pi. Make sure that the RPi can see the UPS. In my case it is the USB with an ID of 0764:0601. The value 0764 is the vendor ID and the 0601 is the product ID.

pi@nut-server:~ $ lsusb 
Bus 001 Device 004: ID 0764:0601 Cyber Power System, Inc. PR1500LCDRT2U UPS
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

At this point, we will be editing several files usp.conf, uspd.users, uspd.conf, upsmon.conf, and nut.conf. These files are all located in /etc/nut/ directory.

  • usp.conf – this is where to specify the driver to use per UPS
  • uspd.conf – this file where we instruct nut what IP and port to listen to
  • uspd.users – this file contains the nut user credentials and their access level
  • upsmon.conf – this contains information about monitoring
  • nut.conf – this file is where we set the mode of the RPi

To locate the driver to use, you can find them here https://networkupstools.org/stable-hcl.html

If you have multiple UPS’es, in the file ups.conf, each UPS must have its name block defined. To distinguish a UPS from the other UPS, the options serial, vendorid or procductid options is needed . The port for the driver usbhid-ups will always be set to auto. Check man usbhid-ups for more info.

Make sure that every parameter is correctly entered otherwise, you might get the error. The safest way is to add the driver and port first as shown in [ups2]. In addition, if you are using Cyberpower UPS like I do, you will need to add the pollinterval. The reason being, after a few minutes you will get a Data stale error. Here is the discussion about it.

# Error for having a wrong value in the serial number.
Poll UPS [ups1@localhost] failed - Driver not connected
[ups1]
        driver = usbhid-ups
        port = auto
        desc = "CyberPowerPC PR1500LCDRT2U"
        serial = CXXKU1234567
        vendorid = 0764
        productid = 0601
        pollinterval = 15

[ups2]
        driver = usbhid-ups
        port = auto

Let’s configure the upsd.conf file. We have to specify the listening addresses and port(s). If you have a firewall installed, make sure to allowed inbound to port 3493/tcp.

echo "LISTEN 127.0.0.1 3493" >> /etc/nut/upsd.conf
echo "LISTEN 10.0.7.42 3493" >> /etc/nut/upsd.conf

Let’s create the nut credentials on the uspd.users file. These credentials will be used to access the daemon. The nut clients will be using the user upsmon_remote credentials. The difference between the upsmon master and slave is that the master is the last one will get shutdown when power failed. This is the reason why I didn’t use a VM to be a NUT server.

sudo cat >> /etc/nut/upsd.users << EOF
[upsmon_master]
        password  = s3cR3tpa$5w0rd
        actions = SET
        instcmds = ALL
        upsmon master
[upsmon_remote]
        password  = s3cR3tpa$5w0rd
        upsmon slave
EOF

We need to configure the upsmon.conf. We need to add at the bottom of the upsmon.conf the user. For multiple UPS, make sure to add another line for the other MONITOR.

echo "MONITOR ups1@localhost 1 upsmon_master s3cR3tpa$5w0rd master" >> /etc/nut/upsmon.conf

The last part is to change the mode from none to netserver in the nut.conf file.

sed -i 's/MODE=none/MODE=netserver/' /etc/nut/nut.conf

To check the status of the UPS you can use the command upsc <ups-name-in-ups.conf>. From here you can grab the serial number and add it to the ups.conf block.

For the UPS that is not the first one, if you run the sudo upsc ups2, you will get an error. This fix this issue reboot the RPi.

pi@nut-server:/etc/nut $ sudo upsc ups1
sudo: unable to resolve host nut-server: Name or service not known
Init SSL without certificate database
battery.charge: 100
battery.charge.low: 10
battery.charge.warning: 20
battery.mfr.date: CPS
battery.runtime: 3825
battery.runtime.low: 300
battery.type: PbAcid
battery.voltage: 27.5
battery.voltage.nominal: 24
device.mfr: CPS
device.model: CP1500PFCLCDa
device.serial: CXXKU2004605
device.type: ups
driver.name: usbhid-ups
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.productid: 0601
driver.parameter.serial: CXXKU2004605
driver.parameter.synchronous: no
driver.parameter.vendorid: 0764
driver.version: 2.7.4
driver.version.data: CyberPower HID 0.4
driver.version.internal: 0.41
input.voltage: 120.0
input.voltage.nominal: 120
output.voltage: 136.0
ups.beeper.status: enabled
ups.delay.shutdown: 20
ups.delay.start: 30
ups.load: 10
ups.mfr: CPS
ups.model: CP1500PFCLCDa
ups.productid: 0601
ups.realpower.nominal: 1000
ups.serial: CXXKU2004605
ups.status: OL
ups.test.result: No test initiated
ups.timer.shutdown: -60
ups.timer.start: -60
ups.vendorid: 0764
pi@nut-server:/etc/nut 

Clients

As the clients, there are only two files we need to configure. The files are nut.conf and upsmon.conf and they are located in /etc/nut/. First, we need to install nut-client to the client nodes. Technically, the only thing is needed is nut-client; however, I could not get the nut-client.service to start. Installing the nut package worked.

apt install nut

Once the nut-client has been installed, we need change the mode from none to netclient.

sed -i 's/MODE=none/MODE=netclient/' /etc/nut/nut.conf

We need to configure the uspmon.conf similar to what what we did to the RPi NUT server. However, we are going to be using the remote user.

echo "MONITOR [email protected] 1 upsmon_remote s3cR3tpa$5w0rd slave" >> /etc/nut/upsmon.conf

Once the files has been updated, we need to enable and start the nut-monitor and nut-server services.

systemctl enable --now nut-server
systemctl enable --now nut-monitor

You can run the command upsc [email protected] and get the UPS’ info.

Now, back to the RPi NUT server, you should see a log stating that the remote nut has logged in as shown below.

# Run tail -f /var/log/syslog on the nut server
Jan 29 11:47:50 nut-server upsd[537]: User [email protected] logged into UPS [ups1]
Subscribe
Notify of
guest

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Chris
Chris
2 years ago

I’ve had this working so many times but always fails. Your guidence has fixed my “Seat to keyboard Connection” issue!!

Last edited 2 years ago by Chris
Alex
Alex
1 year ago
echo "LISTEN 127.0.0.1 3493" >> /etc/nut/upsd.conf
echo "LISTEN 0.0.0.0 3493" >> /etc/nut/upsd.conf

It work!!!

if one UPS is used, then it is not specified in /etc/nut/ups.conf

serial=CXXKU1234567
Last edited 1 year ago by Alex
2
0
Would love your thoughts, please comment.x
()
x