Remote power cycling a UPS with HomeAssistant and NUT 🥜 (manually or with an SMS)
I have a couple of RPI’s running all over the European continent with Home Assistant but most recently I had a couple of devices that became non-responsive.
Normally I use POE switches to power cycle the PoE line and this reboots the device, however in this specific situation, I was out of luck since I’m using a PoE injector after my switch leading to a Pi mounted high on top of a roof for my ADS-B feeder.
my setup is as follows:
so the only option I had left to reboot my roof-mounted RPI3 was either: get a local to power-cycle the PoE injector leading to the roof CAT6 cable.
but then I realized, wait, I have a UPS powering it all, and that UPS is connected (over USB) to an RPI4 in the server rack, why don’t see if I can instruct the RPI4 to power cycle the UPS, and thus would power cycle the RPI3 that’s not responding on the roof.
In my case, I have an APC1500 wired up over a USB
On this page
NUT to the rescue!
The NUT Addon
On the RPI4 I have HomeAssistant running with the Network UPS Tools addon
I’ve configured it as such:
devices: - name: APC driver: usbhid-ups port: auto config: - vendorid = 051d mode: netserver shutdown_host: "false" users: - username: nut password: 308KNiwI8zlZgQvx instcmds: - all actions: [] list_usb_devices: true i_like_to_be_pwned: true
I suggest visiting other sources on how to set up the NUT addon, but long story short: just configure it to the way your UPS is connected to your PI (this can even be a network card)
Identifying the UPS to send the command to
Before we can send commands to reboot the UPS, we need to figure out what UPS NUT can communicate to, We can do this in 4 ways (for completionist sake I provide other ways) but as we configured the name ourselves, we know the name from the config
The addon config
Check the add-ons config in HA
Checking the NUT addon logs
When checking the NUT addon logs we can see the name of our UPS is APC
Asking the docker container on the list of available UPS’es with the upsc command
by far the easiest way to know what UPS the daemon is configured with/for is by asking it for a list of UPS’es by using upsc
docker exec addon_a0d7b954_nut upsc -l
Checking the /etc/nut/ups.conf
we can request the config of the docker, to figure out the name of the UPS
docker exec addon_a0d7b954_nut tail /etc/nut/ups.conf
Getting all available commands we can send to our UPS
Now that we know our name, we can query what commands we can send to our UPS
docker exec addon_a0d7b954_nut upscmd -l APC
and there it is, our reboot command
Rebooting a UPS remotely
now knowing our command we can issue our reboot command
NOTE: I have configured a password, so I use it here
docker exec addon_a0d7b954_nut upscmd -u nut -p 308KNiwI8zlZgQvx APC shutdown.reboot
that’s it! you will lose your connection within a few seconds 🤭 whilst the UPS is power-cycling.
Putting the line into a Shell Command (so we can reboot the system much easier)
https://www.home-assistant.io/integrations/shell_command/
# have it as a command shell_command: powercyle_ups: docker exec addon_a0d7b954_nut upscmd -u nut -p 308KNiwI8zlZgQvx APC shutdown.reboot
Rebooting home assistant by SMS/text message
I’ve had cases before where there French Orange router just freezes up, or something is going on that knocks my entire setup offline, so I’ve recently added a GSM modem (~10€) to my setup (official documentation over here)
The modem itself is a USB-a SIM800C
As a last resort, I’ve added the ability to send a text message (send an SMS) to a prepaid number (prepaid sim was ~2.5€ one time fee)
By combining my phone number and the text “reboot” will trigger a UPS power cycle, which will cut the power to all my devices (switches, routers, point-to-point links, etc…)
alias: reboot UPS on sms received 'reboot' description: Modem received an SMS trigger: - platform: event event_type: sms.incoming_sms condition: - condition: template value_template: "{{ trigger.event.data.phone == \"+32123456789\" }}" alias: my phone number - condition: template value_template: "{{trigger.event.data.text == \"reboot\" }}" action: - service: shell_command.powercyle_ups data: {} mode: single