Nut-ups
This wiki page shows how to install and configure the Network UPS Tools (NUT) package to monitor and report the statistics for a USB attached Uninterruptible Power Supply (UPS). The UPS model used in the examples is an APC SmartUPS 1000, but any UPS on the list of compatible models should work.
The end goal is to make the UPS status available over the network so it can be monitored and used to trigger actions in a home automation system like Home Assistant.
Determine UPS USB parameters
The first step is to plug in the USB cable between your UPS and your Alpine host to see how it appears to the system. Information about the UPS can be seen with the dmesg
command. See the example below.
# dmesg [400269.428612] usb 1-3: new low-speed USB device number 3 using xhci_hcd [400269.580728] usb 1-3: New USB device found, idVendor=051d, idProduct=0002, bcdDevice= 0.06 [400269.580751] usb 1-3: New USB device strings: Mfr=3, Product=1, SerialNumber=2 [400269.580759] usb 1-3: Product: Smart-UPS 1000 FW:600.3.D USB FW:1.4 [400269.580765] usb 1-3: Manufacturer: American Power Conversion [400269.580771] usb 1-3: SerialNumber: AS0123456789 [400269.687883] usbcore: registered new interface driver usbhid [400269.687894] usbhid: USB HID core driver [400269.698356] hid-generic 0003:051D:0002.0001: hiddev96,hidraw0: USB HID v1.10 Device [American Power Conversion Smart-UPS 1000 FW:600.3.D USB FW:1.4] on usb-0000:00:15.0-3/input0
From this output, we can see a Smart-UPS 1000 has been detected. We can also see two important parameters: idVendor=051d and idProduct=0002. These will be used later in the udev rules, so keep them handy.
Installation
Install the nut package:
# apk add nut
Configuration
All of the configuration files delivered with the package will be in the /etc/nut subdirectory. The following commands rename the original configuration file and then write a new file with only the configuration parameters needed. Proceed to rename three default configuration files and replace them with the parameters needed for our example USB attached APC Smart-UPS.
# mv /etc/nut/nut.conf /etc/nut/nut.bak # mv /etc/nut/ups.conf /etc/nut/ups.bak # mv /etc/nut/upsd.conf /etc/nut/upsd.bak
To instruct NUT to make the UPS status available on the network, the content of /etc/nut/nut.conf should be as follows:
Contents of /etc/nut/nut.conf
The content of /etc/nut/ups.conf define the name (in square brackets), the driver used to communicate with the UPS, and the port. For USB attached UPSs, it's almost always going to be a driver of usbhid-ups and a port of auto. Make and model should not make any difference here provided it is a USB attached UPS. It should be as follows:
Contents of /etc/nut/nut.conf
To tell NUT to make the UPS info available on all network interfaces instead of the default i.e localhost only, which is not very useful, the content of /etc/nut/upsd.conf should be as follows:
Contents of /etc/nut/upsd.conf
Configure udev rules
To avoid permission errors configure udev for giving NUT access to the USB attached Smart-UPS 1000. Create the file /etc/udev/rules.d/62-nut-usbups.rules as follows:
Contents of /etc/udev/rules.d/62-nut-usbups.rules
The idVendor and idProduct in first part i.e ATTR{idVendor}=="051d", ATTR{idProduct}=="0002" are unique to your UPS. They were found earlier in the Determining UPS USB parameters section. The rest of the line tells udev what permissions and group ownership to use and should be the same regardless of the UPS make and model.
Use the udevadm
command to tell udev to read in the changes:
# udevadm control --reload-rules
Service configuration
The service is called nut-upsd
and can be managed using the standard start|stop|restart commands using standard OpenRC commands.
Proceed to start the service as follows:
# rc-service nut-upsd start * /run/nut: creating directory * /run/nut: correcting owner Using subdriver: APC HID 0.100 * Starting UPS Server ...
Notice that the directory /run/nut is created automatically the first time.
Verify the running state before proceeding to configure the automatic startup of the nut-upsd
. If everything looks good, go ahead and set the service to auto-start when the system is booted:
# rc-update add nut-upsd * service nut-upsd added to runlevel default
Using NUT
Now the upsc
command can be run against the name added in /etc/nut/ups.conf to gather all status information about your UPS. Based on the example used on this wiki page:
$ upsc SmartUPS_1000
One can also gather specific status information by passing them as an argument:
$ upsc SmartUPS_1000 battery.charge
This is useful to monitor specific values and/or initiate actions (e.g. from a script) when specific thresholds are reached.
NUT itself can also be configured to do useful things like send an email or initiate a graceful shutdown when the main power is lost. The NUT home page is your source for documentation on how to do this.
There is also a NUT integration for Home Assistant that can be installed to keep tabs on your UPS.
Troubleshooting
Testing the configuration
Unplug the UPS USB cable from the host, wait a moment, and then reinsert it. Check dmesg again to make sure it was detected and the idVendor and idProduct are correct.
Check the permissions on the files in the /dev/bus/usb subdirectories. One of these represents your UPS. If the udev rules work correctly, it should be the file with a group owner of nut and permissions of 0664. An example is shown below.
# ls -l /dev/bus/usb/001/003 crw-rw-r-- 1 root nut 189, 2 Oct 10 00:53 /dev/bus/usb/001/003
Your directory and file names may be different, but at least one of the files should have the group ownership and permissions as shown in the example.
The output from dmesg
should tip you off as to which directory and file it is. Look at the line below from dmesg
and compare the usb 1-3 to the directory entry of the /dev/bus/usb/001/003file.
Contents of /dev/bus/usb/001/003
Verifying running state
A couple quick commands will ensure the NUT service is actually running as expected. These are shown in the example below.
alpine:/# rc-service nut-upsd status * status: started alpine:/# netstat -tln | grep 3493 tcp 0 0 0.0.0.0:3493 0.0.0.0:* LISTEN
This shows the service running and making the UPS status available on all network interfaces (0.0.0.0) over the default TCP port for NUT (3493).
Insufficient permissions on everything
libusb1: Could not open any HID devices: insufficient permissions on everything No matching HID UPS found upsnotify: failed to notify about state 4: no notification tech defined, will not spam more about it Driver failed to start (exit status=1)
The above error message is due to the USB device having the wrong ownership and permissions. Configure udev rules and restart the service.