Weekend Raspberry PI W Project
— Comments — tech, tips, tricks, tinker — 5 min read
Weekend tinker project success: @Raspberry_Pi Zero W to monitor my UPS guarding my network gear (alerts w/ @PushoverApp) and safely shutdown my @Ubiquiti controller in the event of low battery😎
— Jonathan Grimes (@jsg2021) July 26, 2021
For the last ten years or so, I've been using Ubiquiti gear for my home network. I've grown from the Edge Router Lite, to the UniFi Security Gateway Pro + Cloud Key, and then most recently a UniFi Dream Machine Pro... each one of these devices need graceful shutdowns and do not like having the power dropped on them. I've been mitigating this with a fairly large UPS so the runtime is long enough I can shut them down in the event of a prolonged outage.
This year has had its fair share of electrical issues. Thankfully, like I said before, I put battery backups on all my important gear so they can weather the brownout, or gracefully shut down. This past week there were a few brownouts and the home network dropped each time. Which, was odd. After a short inspection, I found that the UPS protecting my network gear had failed and was no longer switching to battery... performing the self test instantly tripped it off. So, time to replace!
With the replacement in hand, I was reminded that none of my ubiquiti gear supported USB - HID UPS
interfaces... (and now that Ubiquiti has their own redundant power supply product, its not likely to gain that feature) ...then it hit me: A raspberry pi could monitor and ssh
into devices to shut them down. And so, this adventure begins.
I ordered a Raspberry PI Zero W kit and began researching the necessary information to get this off the ground.
Setup PI
The microSD card from the kit is pre-setup, but I don't want a desktop environment, so I re-imaged the sd card. The easiest way to do this is to simply use their Imager. You can download it from the link, or if you are on linux, check the system package manager for rpi-imager
(or snap).
With the Imager in hand, insert the microSD card from the kit into an SD card adapter and run.
- Choose OS -> Raspberry Pi OS (other) -> Raspberry Pi OS Lite
- Select your SD card
- Write!
Once the imaging is complete, the sd card should have a boot partition. Create an empty file named ssh
there and then create a text file named wpa_supplicant.conf
with these contents:
country=USctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdevupdate_config=1
network={ssid="WIFI_SSID"scan_ssid=1psk="WIFI_PASSWORD"key_mgmt=WPA-PSK}
Update the SSID and password for your network. Save, and eject the sd card. Its now ready to insert into the Raspberry Pi.
Once the pi is all assembled, plugin the USB dongle into pi with the UPS' USB data cable inserted. Plugin power and return to you main computer. It will take 30-90 seconds to come up.
Changing the defaults
The default hostname will be raspberrypi.local
. SSH into the device vi: ssh pi@raspberrypi.local
(default password: raspberry
)
Install all updates & patches
sudo apt-get update && sudo apt-get upgrade -y
Change hostname, default password, etc...
sudo raspi-config #menu app
Reboot: sudo reboot
Getting into the NUTs and bolts
I basically followed this blog post to get NUTs up and running, but I will summarize my steps here for a quick reference :)
sudo apt-get install nut
Set the driver NUT will use to communicate with the UPS:
sudo cat << EOF >> /etc/nut/ups.conf
# NOTE: This is for a UPS that connects via USB[myups] driver = usbhid-ups port = auto desc = "My UPS"
EOF
Edit /etc/nut/nut.conf
and make the MODE=standalone
:
sudo sed -i 's/^MODE=.*/MODE=standalone/g' /etc/nut/nut.conf
Start the server:
sudo upsdrvctl startsudo service nut-server status
Verify what we've done so far works...
upsc myups
The above should spit out lots of info, if it doesn't, you may need to reboot the pi.
Add users to the NUT client
sudo cat << EOF >> /etc/nut/upsd.users[admin] password = mypasswd actions = SET instcmds = ALL
[upsmon] password = mypasswd upsmon masterEOF
Updating upsmon.conf
sudo nano /etc/nut/upsmon.conf
Jump to the section with # MONITOR ...
. Add the line:
MONITOR myups@localhost 1 upsmon mypasswd master
Jump to the section with # NOTIFYCMD ...
. Add the line:
NOTIFYCMD /etc/nut/upssched-cmd.sh
Jump to the section with # NOTIFYFLAG
, uncomment lines with the events you care about. At minimum, NOTIFYFLAG LOWBATT
. Add +EXEC
at the end of the lines (that flag tells it to execute the script we added with NOTIFYCMD
) Here's how my section looks:
# --------------------------------------------------------------------------# NOTIFYFLAG - change behavior of upsmon when NOTIFY events occur## By default, upsmon sends walls (global messages to all logged in users)# and writes to the syslog when things happen. You can change this.## NOTIFYFLAG <notify type> <flag>[+<flag>][+<flag>] ...#NOTIFYFLAG ONLINE SYSLOG+WALL+EXECNOTIFYFLAG ONBATT SYSLOG+WALL+EXECNOTIFYFLAG LOWBATT SYSLOG+WALL+EXEC# NOTIFYFLAG FSD SYSLOG+WALL# NOTIFYFLAG COMMOK SYSLOG+WALL# NOTIFYFLAG COMMBAD SYSLOG+WALLNOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXECNOTIFYFLAG REPLBATT SYSLOG+WALL+EXEC# NOTIFYFLAG NOCOMM SYSLOG+WALL# NOTIFYFLAG NOPARENT SYSLOG+WALL#
Save & Exit. (ctrl+x y cnter)
Create upssched-cmd.sh
:
sudo cat << "EOF" >> /etc/nut/upssched-cmd.sh#!/bin/bash#curl -k -X POST \# -F token=<token> \# -F user=<user> \# -F "title=PSU Event" \# -F "message=$*" \# https://api.pushover.net/1/messages.json &> /dev/null &
if [[ "$*" == *"battery is low"* ]]; then ssh root@gateway-name-or-ip powerofffiEOF
Update config file owners and permissions:
sudo chown nut:nut /etc/nut/*sudo chmod 640 /etc/nut/upsd.users /etc/nut/upsmon.conf
sudo service nut-server restartsudo service nut-client restart
Push Notifications
Open a pushover.net account and setup an application. Get the user key and application token values and put them in the upssched-cmd.sh
and uncomment those lines (curl through https...)
Test it by just running your script from the command line:
sudo -u nut /etc/nut/upssched-cmd.sh "hi"
Generate an ID for nut
sudo -u nut ssh-keygen
Now that the user has an id, we can make it so that its able to connect without a password to the thing needing shut down by uploading the key:
sudo -u nut ssh-copy-id root@gateway-name-or-ip
NOTE: The Dream Machine/CloudKey/USG do not enable ssh by default. Enable it from the admin web interfaces.