Raspberry pi + Network UPS tools + mqtt
Every server should have a UPS to protect the system from power outage or over voltage situations and enable controlled shutdown. So do my systems as well. I have one Eaton 5P1500R and two Eaton 5P850R 1U Rack UPS systems running. I do like to monitor them and send out some notifications if any state changes on any UPS. Luckily the UPS provide an USB port to connect to and get the status from it. There is an option for a LAN card but this is more expensive. Such a price might be ok for an company but not really needed for my homelab.
The final solution involves more than just NUT and mosquitto. This part shows how to set up Network Ups Tools on a raspberry pi to monitor a ups and send a notification to a MQTT broker. In part two I show you the second part of my setup and how I use mqtt, node-red and a telegram bot to keep me up to date.
Using a Raspberry PI as NUT server
I do not cover the basic setup of the raspbian OS here. The image of the debian based raspbian distribution is located at raspberrypi.org . I recommend using the “Raspbian Buster Lite” or if you like to have a GUI the “Raspbian Buster with desktop” versions. In fact you do not need any GUI to make this work.
sudo apt-get install nut
This should install the meta package which contains at least
nut-server. If you like to have a cgi-script to access all the UPS details, you also should make sure that
nut-cgi and apache2 is installed as well. The nut-cgi gives you a nice overview like the one below.
Configure UPS utils
Below you find the configuration files for NUT I use for my setup. The passwords are not the real ones ;-)
I use the nut installation on the raspberry pi as a network server version. Setting it up that way enables all my servers to get the state of the connected UPS for that particular server. To configure the instance as a server, just set the mode to
Next you have to configure your attached UPS devices. This also ensures that they are not assigned to a different name depending on the usb enumeration. I use the serial to make sure UPS1 is always UPS1. I also set the option
sdorder which ensures that the UPS where the Pi is attached to, gets turned off as the last UPS and all others are turned off before. The shutdown starts with 0 and the last one here is 2.
[ups1] driver = usbhid-ups port = auto serial = G115F????? desc = "Eaton 5P 850VA UPS1" sdorder = 2 [ups2] driver = usbhid-ups port = auto serial = G115F????? desc = "Eaton 5P 850VA UPS2" sdorder = 0 [ups3] driver = usbhid-ups port = auto serial = G117F????? desc = "Eaton 5P 1500VA UPS3" sdorder = 1
upsd.conf and upsd.users
These files are documented well and it should not be difficult to adjust these for your needs. The
upsd.conf does set the port and listing address including certificates and the
upsd.users defines the users and their access rights. Adjust it to your personal needs.
In this configuration file I configure which UPS devices the monitoring daemon should check. As I like to get a notification for all changes on all my UPS boxes, I just enter them all. The line with the parameter
NOTIFYCMD is the real interesting one. The script you configure there is the one that gets executed when a notification should be sent. But setting this alone will not be sufficient. To make upsmon call your script, you need to change the
NOTIFYFLAG values and add a
+EXEC to the end of the line. Also make sure that these lines are no longer comments but real assignments.
MONITOR ups1@localhost 1 upsmon yourpasswd master MONITOR ups2@localhost 1 upsmon yourpasswd master MONITOR ups3@localhost 1 upsmon yourpasswd master NOTIFYCMD /etc/nut/mqttnotify/nutnotify.sh NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC NOTIFYFLAG ONBATT SYSLOG+WALL+EXEC NOTIFYFLAG LOWBATT SYSLOG+WALL+EXEC NOTIFYFLAG FSD SYSLOG+WALL+EXEC NOTIFYFLAG COMMOK SYSLOG+WALL+EXEC NOTIFYFLAG COMMBAD SYSLOG+WALL+EXEC NOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXEC NOTIFYFLAG REPLBATT SYSLOG+WALL+EXEC NOTIFYFLAG NOCOMM SYSLOG+WALL+EXEC NOTIFYFLAG NOPARENT SYSLOG+WALL+EXEC
nutnotify.sh and mosquitto_pub
Finally you need the script to publish a message to your mqtt broker. Before running the script the package
mosquitto-clients needs to be installed. Just run
sudo apt-get install mosquitto-clients to do this.
After successfully installing the needed clients, you can edit the script using
sudo nano /etc/nut/mqttnotify/nutnotify.sh and use the following example as starting point.
#!/bin/bash mosquitto_pub -h mqtt.example.com -t "/power/$UPSNAME/notify/$NOTIFYTYPE" -m "$1" -u mqttuser -P mqttpasswd --tls-version tlsv1.1 --cafile /etc/nut/mqttnotify/haefelfinger-ca.crt
As you see, there is a ssl certificate authority file defined. This is because I use a TLS connection to my broker. To make the client trust the host certificate, you may install your own ca certificate or pass it as file here.
NUT defines two environment variables you can use in your script.
$UPSNAME contains the name of the UPS that triggers the notification.
$NOTIFYTYPE contains the type name of the notification like
ONBATT when the plug gets pulled. In
$1 you find the message generated by upsmon. These messages can be customized in
upsmon.conf as well. So the mqtt topic is based on the UPS name and the notification and the message content is the message generated by upsmon. This offers quite some flexibility on the consumer side.
In this example I also use a username and password to connect to the mosquitto server. Make sure that you restrict the rights on the script as well. To do this use the following commands.
sudo chown root.nut /etc/nut/mqttnotify/nutnotify.sh sudo chmod 750 /etc/nut/mqttnotify/nutnotify.sh
This way only root and the nut group users ar able to read or execute this file.
You can test your script by running it using the following example as root or nut user.
UPSNAME=UPS1 NOTIFYTYPE=ONLINE /etc/nut/mqttnotify/nutnotify.sh "Testmessage"
This should publish a message with the content
Testmessage using the topic
/power/UPS1/notify/ONLINE on your mqtt broker.
At this point you have a NUT installation monitoring your ups devices and sending out some mqtt messages if any of the states change. You may continue on your own way from here on or wait for my second article where I show how to use node-red to get these notifications and pass them over to my telegram bot .