At our school there are always power outages. Sometimes they last only a few seconds, sometimes several hours. To ensure that our IT infrastructure does not suffer from this, we have installed a UPS for our servers and network devices. These help to bridge short power outages (up to 1 hour) or fluctuations in current. For any lengthy outages, we automatically shut down our servers when the UPS reaches critical battery level. For this we use NUT (Network UPS Tools).
Our setup consists of the following components:
Set up UPS in NUT on the Raspberry Pi
For the Raspberry Pi we use the standard Raspian Stretch Lite Image. Note that SSH has not been enabled by default since 2016. The different ways to reactivate SSH are documented here. After reactivating SSH, you can now log on to the Raspberry Pi (the IP of the Raspberry Pi can be found out from a computer in the same network with avahi-browse -ar or you can connect a monitor and keyboard). We will need the IP later, so it makes sense to give the Raspberry Pi a static IP.
Next we install the NUT server with
sudo apt-get install nut-client nut-server usbutils
If the UPS is connected via USB (as in our case), you can check with lsusb if it was detected. This is what the output on the Raspberry Pi looks like:
Bus 001 Device 004: ID 10af: 0000 Liebert Corp. 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.
Bus 001 Device 001: ID 1d6b: 0002 Linux Foundation 2.0 root hub
In the first line you can see that our Liebert UPS has been recognized.
Now we have to configure our UPS in the file /etc/nut/ups.conf. For our UPS, the entry looks like this:
driver = usbhid-ups
port = car
productid = 0000
desc = “Emerson Liebert GXT 4”
On the Network UPS Tools website, you will find a list of all supported UPS and which driver works best.
Next, we want to test whether the settings are correct, the UPS Daemon can communicate with the UPS. For this purpose we start upsd with
sudo upsdrvctl start
A successful output should look something like this:
Network UPS Tools — UPS driver controller 2.7.2
Network UPS Tools — Generic HID driver 0.38 (2.7.2)
USB communication driver 0.32
Using subdriver: Belkin HID 0.16
NUT contains a small program to test the communication with UPS. It is called upsc and outputs all readable UPS parameters.
$ upsc gxt4
Init SSL without certificate database
battery.charge. low: 20
battery.charge. warning: 0
battery.voltage. nominal: 0.0
device.mfr: Emerson Network Power
device.model: Liebert GXT4
driver.parameter. pollfreq: 30
driver.parameter. pollinterval: 2
driver.parameter. port: auto
driver.parameter. productid: 0000
driver.version. data: Belkin HID 0.16
driver.version. internal: 0.38
ups.mfr: Emerson Network Power
ups.model: Liebert GXT4
ups.status: OL CHRG
Now our UPS is successfully installed. Next we set up the NUT server, the UPS monitor upsmon and two more users for the master and the slaves.
Configuring the NUT Server
In /etc/nut/nut/nut.conf we specify that the Raspberry Pi is our master:
The UPS Daemon (upsd) is running on the NUT server. It is responsible for the (physical) connection to UPS. The individual clients/slaves use the upsmon to access the status of the UPS. In this way, multiple clients can always know the status of the UPS and, if necessary, initiate shutdown when UPS delivers the status “On Low Battery”.
In order for our NUT server to be accessible from the net, the following lines have to be added to /etc/nut/upsd.conf (adjust IP please):
LISTEN 192.168.1.2 #IP of the Raspberry Pis
Next, we define the users that a client can use to log on to the master (in the file /etc/nut/upsd.user):
password = secret
password = secret
In order for upsmon to monitor the UPS, we now need to add a final entry in /etc/nut/upsmon.conf:
MONITOR gxt4@localhost 1 upsmaster secret master
In order to know if all services are running correctly, you can check the status of the server and the local clients on the Raspberry Pi (because it should be shut down when there is no more power) with the following commands:
$ sudo systemctl status nut-server
$ sudo systemctl status user-client
Now our master is set up and the clients or slaves can be configured.
Set up clients/slaves (e. g. server, other computers)
First, the necessary packages must be installed on a client:
sudo apt-get install nut-client
This time we only have to edit two files. In /etc/nut/nut/nut.conf we set the mode:
Then we need to tell upsmon which UPS to monitor (in /etc/nut/upsmon.conf):
MONITOR firstname.lastname@example.org upsremote secret slave
The IP and password have to be adjusted. Please also note the slave at the end! Finally, restart the corresponding service and check that everything is running:
$ sudo systemctl restart user-client
$ sudo systemctl status user-client
Congratulations! Now everything should be set up, but how can you test that it really works?
The following command triggers the shutdown signal (as it would be in the event of a power failure):
$ sudo upsmon -c fsd
NUT is another great open source project that allows very flexible customizations. This PDF contains many more (complex) application scenarios. While I’m writing this article, we’re out of power again and all our servers have been shut down :)