So recently, we’ve been suffering with a fair few power cuts. Some of the houses near us are undergoing some pretty heavy renovations, and well, let’s just say the electricians aren’t always precise when it comes to pulling the plug. Having lost part of a docker configuration I lost a morning restoring and bringing the server back to life. This has pushed me into getting a UPS (Uninterruptible Power Supply). I opted for one from APC, and I bought the following (this is an Amazon affiliate link, so won’t cost you anything, but should you order, will help support the blog).
I wanted an APC with IEC female plugs, so that I could plug a variety of devices directly into it, and I didn’t have unnecessary household power plugs and extensions hanging out the back. It comes with ethernet passthrough (surge protection) and a USB output, so that you can hook it up to a NUT server. As far as UPS’s go, that’s about it. I felt this one was large enough to run my various small form factor pc’s as well as some other general items. Now in order to make this smart, we need to start connecting software up to it.
NUT stands for Network UPS Tools and is an open source software package that effectively monitors the output of the UPS. In the event of a power cut, the NUT server will essentially broadcast alert packets on the network. If you set your various devices to listen out for such packets, you can then trigger a safe shutdown. A couple of caveats… a) You’ll need to have whatever device you want to shut down safely connected to the UPS (this or a different one), otherwise it will have already lost its power and won’t be listening to anything and b) you need to make sure that the UPS is up long enough to ensure a full shutdown before lights out. I’ll expand:
As soon as the UPS goes on to battery (i.e. power cut), the battery will begin to deplete. Depending on the size of the UPS and the power draw attached to it, you could have seconds or minutes. You need to make sure you give your equipment enough time to complete the shutdown. If you wait until there’s only 5% of battery left, you might be cutting it too short. If you wait until there’s 90% of battery left, then you might be shutting down the equipment too early. Especially, if the power cut is only for a minute or so (i.e. someone is changing a light switch or wiring a plug socket). Thankfully the delays are configurable, but you’ll need to calculate this for yourself.
You can find details of NUT here. There are a wealth of tutorials already online about setting it all up. In this post, I want to show you how to configure it on Proxmox and set up monitoring in Docker and Home-Assistant. I’ll link at the end, a variety of tutorials and posts should you wish to explore the set ups in depth.
Setting up NUT on Proxmox
For this, we’re going to want to set it up directly on the machine itself (i.e. PVE) and not on a VM or LXC beneath it. We’ll need to identify the some details about the device and how it’s set up.
Go into the PVE node and open Shell. We’ll list the USB port.
Identify the bus and the device id.
lsusb -v -s [bus]:[device]
You can see from the example, mine was bus 1, device 3. Therefore:
lsusb -v -s 1:3
As long as the details are correct, we can now install NUT. If you’re having issues here, you can try and reinsert the USB or change the cable.
apt update && apt install nut -y
Now scan for the devices on your system:
Record the details as you’ll need these shortly.
We will need to create or edit a variety of configuration files now. If you wish to back up the example conf files, that’s up to you, for me, I just went with it. I figured I could always nuke /etc/nut/*.* if I got stuck and reinstall.
I’m using nano here, if you wish to clear a whole file of text with a few strokes, see more on that here. Once you’re done editing the files, it’s ctrl+o to save (+ enter) and then ctrl+x to get back to the cmd prompt.
Change Mode=none to Mode=netserver
Clear the file and replace with the information you received from nut-scanner _U above:
pollinterval = 15
maxretry = 3
offdelay = 120
ondelay = 240
driver = usbhid-ups
port = auto
desc = “insert.your.description.here”
vendorid = 051D
productid = 0002
serial = add.your.serial.here
To test, run the following command
You should get a similar output to below:
Clear the file and add this, it makes the server listen to any device on the network for the NUT packets.
LISTEN 0.0.0.0 3493
LISTEN :: 3493
Next create the users.
Clear the file and add this (set your own passwords):
password = insert.your.password.here
actions = SET
actions = FSD
instcmds = ALL
password = insert.your.password.here
Next we set up monitoring (insert your own upsadmin password):
MONITOR apc@localhost 1 upsadmin password.goes.here master
SHUTDOWNCMD “/sbin/shutdown -h”
NOTIFYMSG ONLINE “UPS %s on line power”
NOTIFYMSG ONBATT “UPS %s on battery”
NOTIFYMSG LOWBATT “UPS %s battary is low”
NOTIFYMSG FSD “UPS %s: forced shutdown in progress”
NOTIFYMSG COMMOK “Communications with UPS %s established”
NOTIFYMSG COMMBAD “Communications with UPS %s lost”
NOTIFYMSG SHUTDOWN “Auto logout and shutdown proceeding”
NOTIFYMSG REPLBATT “UPS %s battery needs to be replaced”
NOTIFYMSG NOCOMM “UPS %s is unavailable”
NOTIFYMSG NOPARENT “upsmon parent process died – shutdown impossible”
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
NOTIFYFLAG NOCOMM SYSLOG+WALL+EXEC
NOTIFYFLAG NOPARENT SYSLOG+WALL
Next we set up the scheduling:
Clear the file and add this:
AT ONBATT * START-TIMER onbatt 30
AT ONLINE * CANCEL-TIMER onbatt online
AT ONBATT * START-TIMER earlyshutdown 30
AT LOWBATT * EXECUTE onbatt
AT COMMBAD * START-TIMER commbad 30
AT COMMOK * CANCEL-TIMER commbad commok
AT NOCOMM * EXECUTE commbad
AT SHUTDOWN * EXECUTE powerdown
AT SHUTDOWN * EXECUTE powerdown
Next we set up the scheduling commands:
paste this in:
case $1 in
logger -t upssched-cmd "UPS running on battery"
logger -t upssched-cmd "UPS on battery too long, early shutdown"
/usr/sbin/upsmon -c fsd
logger -t upssched-cmd "UPS on battery critical, forced shutdown"
/usr/sbin/upsmon -c fsd
logger -t upssched-cmd "UPS has been gone too long, can't reach"
logger -t upssched-cmd "Unrecognized command: $1"
And finally make it executable:
chmod +x /etc/nut/upssched-cmd
That’s it. Now you can either reboot the system, or run through the following commands (pause after each upsdrvctl command, they take a moment).
service nut-server restart
service nut-client restart
systemctl restart nut-monitor
You can test if it’s working with the following command:
In order to amend the minimum runtime to 10 minutes and minimum charge to 50% you can run the following commands. You’ll need the upsadmin login and password to action each line.
upsrw -s battery.runtime.low=600 apc@localhost
upsrw -s battery.charge.low=50 apc@localhost
That’s it. You’re done. Everything should be nicely configured in Proxmox and waiting for your next power cut. To test, literally pull the power out of the UPS, and hopefully watch your server remain online until the parameters above and then see it shutdown gracefully.
If you wish to learn more about the software, I suggest you look at the following resources:
Now we want to set up monitoring.
Monitoring in Docker
I chose to install two ways to monitor. One in Home-Assistant and the other in docker. I wanted more than one option as they’re both on different machines. Let’s deal with Docker/Portainer first. I wrote a post here about running a docker stack in Portainer on Proxmox here if you’re interested.
Portainer> Stacks > Add Stack (or via docker compose if more comfortable)
Deploy the container and within moments, you’re looking at something like this (serverip:6543):
Click through to see all the metrics.
Monitoring in Home-Assistant
Next, let’s set up monitoring in Home-Assistant. Integrations > Add NUT
Configure as necessary and submit.
Out of the box, you’ll be able to add 5 sensors. Initially for some reason, only 4 were added to Lovelace, but I just added the additional Apc Battery Charge manually. Also for some reason 17 “Diagnostic” entities were disabled by default. Should you wish to enable these, you can highlight them in the entities panel with a check box and hit enable. Within moments they were online.
One thing you need to be mindful of with this set up, is once the UPS has initiated a power down of the server (in my case, Proxmox). The NUT server will also go “unavailable” until that server is brought back up. Depending on how you configure your automatic shutdown parameters this could affect the “slaves” down stream.
Now that we have the UPS in Home-Assistant, it’s easy to set up our own alerts using Node-red and whatever output module you’re interested in (email, telegram, etc.).
I am currently waiting for some more items to be delivered to go alongside the UPS. Out of the box it comes with one IEC c13-c14 connector and the USB lead. It didn’t even come with it’s own power lead, but that’s fine, I have plenty of them.
These are what I’ve ordered:
a C13 to c14 extention lead (this will power my pfSense brick directly)
a C14 to EU socket (this will power my Home-Assistant NUC)
Once everything arrives, I’ll start plugging it all in and configuring everything else to speak to the NUT server!
If there’s anything else out there that people are looking at or you think I should be looking at, let me know in the comments or come and chat over in our facebook group!
If you’re considering a renovation and looking at the structured wiring side of things, or maybe you just want to support the blog, have a look below at my smarthome book, it’s available in all the usual places (including paperback)!