Once you have NUT-tools configured on your Raspberry to monitor your UPS, the next step is configuring the slaves. The slaves are your servers and other computers that are plugged into the UPS. Looking at my UPS stats on the NUT web server pages, it looks like I’ve got about 16 minutes of runtime under the current load. This post will lead you through configuring your server to shutdown after 10 minutes. Honestly, this whole place is on standby generator power, so the lights might go out for 15-20 seconds during the switchover. The UPS will handle that, easy! But if the generator fails, I’ve got to make sure that someone does a “shutdown -h now” on my LINUX servers. And that someone? NUT!
The Story So Far…
So far, we’ve got nut-tools running on a Raspberry Pi 3. It’s got a USB connection to the UPS and my webserver is plugged in to that UPS. IF the power is out for 10 minutes or more, it’s not coming back on anytime soon, so I need NUT to send a command to shutdown the server.
The last Raspberry we configured was the “master”. It’s got a USB connection to the UPS and watches for the UPS switching between mains and battery power. Now, it’s time to configure the “slaves” or the computers that hear that Raspberry screaming that the lights are out!
How to Install a NUT client
First, install the nut client:
sudo apt install nut-client
To get the slave talking to the master, you’ll have to edit two files: nut.conf and upsmon.conf. The nut.conf file is used to put the software into slave mode. Edit / add the following line to nut.conf. (I just put it right at the end so it’s easy to find.):
MODE=none change to MODE=netclient
Next, we’re going to add a line to upsmon.conf. You’ll need the name of the UPS, the username, and the password that we configured on the master.
MONITOR <system> <powervalue> <username> <password> ("master"|"slave") change to MONITOR servers@192.168.1.193 1 monuser secret slave
This time the MONITOR is a little different. It’s watching the Raspberry that’s running NUT, not the UPS directly. ups is the name of the UPS that my servers are plugged into. The IP address is that of the Raspberry. 1 is the powermode. Just leave this at 1. monuser is the user that I configured. secret is the password. slave is the mode. Restart:
systemctl restart nut-monitor.service
Now, check your connection to the master. If you’re copying my config, the test looks like this. upsc is the command. “servers” is the name of the UPS. “ups” is the name of the raspberry that has the USB connection to the actual UPS:
root@server1:~# upsc servers@ups Init SSL without certificate database battery.charge: 100 battery.charge.low: 10 battery.charge.warning: 20 battery.mfr.date: CPS battery.runtime: 1008 battery.runtime.low: 300 battery.type: PbAcid battery.voltage: 27.2 battery.voltage.nominal: 24 device.mfr: CPS device.model: CP1350AVRLCDa device.serial: CTJJY2003442 device.type: ups driver.name: usbhid-ups driver.parameter.pollfreq: 30 driver.parameter.pollinterval: 15 driver.parameter.port: auto driver.parameter.product: .50A. driver.parameter.synchronous: no driver.version: 2.7.4 driver.version.data: CyberPower HID 0.4 driver.version.internal: 0.41 input.voltage: 124.0 input.voltage.nominal: 120 output.voltage: 140.0 ups.beeper.status: enabled ups.delay.shutdown: 20 ups.delay.start: 30 ups.load: 35 ups.mfr: CPS ups.model: CP1350AVRLCDa ups.productid: 0501 ups.realpower.nominal: 815 ups.serial: CTJJY2003442 ups.status: OL ups.test.result: No test initiated ups.timer.shutdown: -60 ups.timer.start: -60 ups.vendorid: 0764 root@server1:~#
What to Do When the Lights Go Out
Now, we need to instruct nut what to do when it hears from the master that the UPS battery is draining! Edit upsmon.conf and search for SHUTDOWNCMD. That should lead you to the definition of how to run the shutdown command. Run “which shutdown” on your server to see where the command is. On my system it’s in: /usr/sbin/shutdown so I need to edit the line in upsmon.conf to look like this:
SHUTDOWNCMD "/usr/sbin/shutdown -h now"
Next, we’ll edit upssched.conf. This is where you can configure the UPS statuses and what nut should do about them. The format for each line is: AT notifytype upsname command The commands themselves are configured in /usr/bin/upssched-cmd The timers take an argument that is the number of seconds. After that number of seconds, the command is sent to upssched-cmd for immediate execution. The CMDSCRIPT line must be first! PIPEFN and LOCKFN are files that get created by the system. You just have to specify their names and locations. PIPEFN is the pipe facility that allows upssched to talk to the script. Next, you have all of your messages coming from the monitor (named “*”) and what to do about them. The lower case word is the argument that gets sent to the command processor, upssched-cmd.
CMDSCRIPT /usr/bin/upssched-cmd PIPEFN /etc/nut/upssched/nut.pipe LOCKFN /etc/nut/upssched/nut.lock AT ONBATT * START-TIMER onbatt 20 AT ONLINE * CANCEL-TIMER onbatt AT ONBATT * START-TIMER earlyshutdown 300 AT ONLINE * CANCEL-TIMER earlyshutdown AT LOWBATT * START-TIMER shutdowncritical 30 AT ONLINE * CANCEL-TIMER shutdowncritical AT COMMBAD * START-TIMER upsgone 30 AT COMMOK * CANCEL-TIMER upsgone
Note the change to the path for upssched-cmd. Don’t get tripped up by the similarity of the names /usr/bin/upssched-cmd and /etc/nut/upssched.conf!
Here’s my /usr/bin/upssched-cmd:
#!/bin/sh case $1 in onbatt) logger -t upssched-cmd "The UPS has been on battery for awhile ;; earlyshutdown) logger -t upssched-cmd "UPS on battery too long, forced shutdown" /usr/sbin/upsmon -c fsd ;; shutdowncritical) logger -t upssched-cmd "UPS on battery critical, forced shutdown" /usr/sbin/upsmon -c fsd ;; upsgone) logger -t upssched-cmd "The UPS has been gone for awhile" ;; *) logger -t upssched-cmd "Unrecognized command: $1" ;; esac
Check what’s happening here. Most of these commands call upsmon. upsmon is the client process that is responsible for the most important part of UPS monitoring—shutting down the system when the power goes out. Once again, you’ll want to check the path (with “which”) of the location of this all too important player. Otherwise you can put whatever you like in here: commands to email you, run other processes, or whatever you need.
upsmon.conf is extensively documented within. You can read what needs to be configured. Here’s what I ended up using after tinkering with it for a couple of hours…
MONITOR printer@192.168.1.193 1 monuser secret slave MINSUPPLIES 1 SHUTDOWNCMD "/usr/sbin/shutdown -h now" NOTIFYCMD /usr/sbin/upssched POLLFREQ 5 POLLFREQALERT 5 HOSTSYNC 15 DEADTIME 15 POWERDOWNFLAG /etc/killpower 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 RBWARNTIME 43200 NOCOMMWARNTIME 300 FINALDELAY 5
Feeling Brave?
OK. Time for the big test. Restart upsmon and pull the plug on the UPS! You should see a couple of wall messages. The UPS should be beeping. Depending on how you sent the timers in upsmon, your server should shut down any minute now!
Hi, can I install both the master and the slave instance on the rpi if the rpi is the server i’d like to be shut down in a properly manner?
Absolutely!
How can nut be configured in nut.conf and upsmon.conf as master and slave at the same time?
Following your HowTo, my nut is now configured as master and works fine including cgi, but I’m curious how to use the “shutdown mechanics” for the *same* rpi …
Great article once again. I am interested in possibly sending an sms text to my phone when any of my UPSs go on battery, and possibly when they return to line power. Just curious what your approach might be? I found some good ideas in this forum Q: https://unix.stackexchange.com/questions/82895/possible-to-get-sms-text-message-notification-when-process-ends-or-is-killed
Also, just an idea for you (would love your opinion). To separate some of the NUT log msgs out from syslog, I added the following script file to /etc/rsyslog.d/0-nut.conf… part of me wonders if this might be another way to filter for the powers alerts and send an SMS msg but, I think your NUT-specific approach documented here is ideal.
#
# NUT logging
#
# Include USB msgs since montoring UPS via only USB
if $msg contains “USB” or $msg contains “nut-” or $msg contains “UPS” then {
action(type=”omfile” file=”/var/log/nut.log”)
} else {
if $syslogtag contains “ups” or $syslogtag contains “nut” then
action(type=”omfile” file=”/var/log/nut.log”)
}
Thx again for the great article.
Just curious… let’s say I’m in an area that suffers from short power interruptions here and there, and I just want to page myself immediately when the UPS goes on battery, and immediately when it goes back on line power. Would my /etc/nut/upssched.conf look something like… ?
AT ONBATT * START-TIMER onbatterypower 0
AT ONLINE * CANCEL-TIMER onlinepower
…or would you use some different NUT commands?
OK, I am a bit confused here. Sorry, I am a bit new to Linux.
Does the upsmon -c fsd command shut down the UPS, or does it shutdown upsmon?
When does the Shutdown command for the RPi get executed?
My desire would be to send a shutdown command to the ups with a delay on it, then send a push shutdown message to hub controller, and then shut down the RPI before the UPS shuts down. It looks like your script in upssched shuts down the ups at 300 seconds. when does the RPi Shutdown? It has to happen befor the UPS shuts down.
What am I missing here?
upsmon -c FSD does a forced shutdown by calling the command specified by SHUTDOWNCMD. It also tells slave upsmon instances that the final shutdown is underway and they shutdown the systems that they are configured to control.
Thanks for the reply. OK So I can forget about shutting down the UPS. But to send shutdown commands to other devices attached to the same UPS before shutting down the RPi I would have to write some sort of script or shell file to send the two or three different commands to the other home automation controllers, and then the shutdown to the RPi? Does SHUTDOWNCMD allow you to execute a script or .sh file?
I have followed the instructions here and in the manual, but the timer part of the NUT setup does not work. I am running on Raspberry Pi.. In /etc/nut/upsmon.conf, I put this:
NOTIFYCMD /usr/sbin/upssched
I have set “SYSLOG+WALL+EXEC” for all notifyfflag options. EG:
NOTIFYFLAG ONLINE SYSLOG+WALL+EXEC
It is an exact replica of the one on this site.
I did confirm that “/usr/sbin/upssched” exists and has execute flag
In /etc/nut/upssched.conf
I have placed a lot of timers in ‘/etc/nut/upssched.conf’ trying to get one of them to work.
AT ONBATT * START-TIMER onbatt 20
AT ONLINE * CANCEL-TIMER onbatt
AT ONBATT * START-TIMER earlyshutdown 600
AT ONLINE * CANCEL-TIMER earlyshutdown
AT ONBATT * START-TIMER nineminstoearlyshutdown 570
AT ONLINE * CANCEL-TIMER nineminstoearlyshutdown
AT ONBATT * START-TIMER eightminstoearlyshutdown 480
AT ONLINE * CANCEL-TIMER eightminstoearlyshutdown
AT ONBATT * START-TIMER sixminstoearlyshutdown 360
AT ONLINE * CANCEL-TIMER sixminstoearlyshutdown
AT ONBATT * START-TIMER fourminstoearlyshutdown 240
AT ONLINE * CANCEL-TIMER fourminstoearlyshutdown
AT ONBATT * START-TIMER twominstoearlyshutdown 120
AT ONLINE * CANCEL-TIMER twominstoearlyshutdown
AT LOWBATT * START-TIMER shutdowncritical 30
AT ONLINE * CANCEL-TIMER shutdowncritical
AT COMMBAD * START-TIMER upsgone 30
AT COMMOK * CANCEL-TIMER upsgone
I then placed if conditions as below into the ‘/usr/bin/upssched-cmd’
#! /bin/sh
case $1 in
onbatt)
logger -t upssched-cmd “The UPS has been on battery for awhile
;;
earlyshutdown)
logger -t upssched-cmd “UPS on battery too long, early shutdown”
wall ” UPS on battery too long, early shutdown ”
/usr/sbin/upsmon -c fsd
;;
nineminstoearlyshutdown)
logger -t upssched-cmd “UPS on battery 9.5 minutes till forced shutdown”
wall “UPS on battery, 9.5 minutes till forced shutdown”
;;
eightminstoearlyshutdown)
logger -t upssched-cmd “UPS on battery 8 minutes till forced shutdown”
wall “UPS on battery, 8 minutes till forced shutdown”
;;
sixminstoearlyshutdown)
logger -t upssched-cmd “UPS on battery, 6 minutes till forced shutdown”
wall “UPS on battery, 6 minutes till forced shutdown”
;;
fourminstoearlyshutdown)
logger -t upssched-cmd “UPS on battery, 4 minutes till forced shutdown”
wall “UPS on battery, 4 minutes till forced shutdown”
;;
twominstoearlyshutdown)
logger -t upssched-cmd “UPS on battery, 2 minutes till forced shutdown”
wall “UPS on battery, 2 minutes till forced shutdown”
;;
shutdowncritical)
logger -t upssched-cmd “UPS on battery critical, forced shutdown”
wall ” UPS on battery critical, forced shutdown ”
;;
upsgone)
logger -t upssched-cmd “The UPS has been gone for awhile”
wall ” The UPS has been gone for awhile ”
;;
*)
logger -t upssched-cmd “Unrecognized command: $1”
;;
esac
‘/usr/bin/upssched-cmd’ is executable according to thee file flags
OK, that comment was completely unreadable, so I will try again. I have folloed the steps on this site, and the only thing that does not work is the timers. There is zero evidence that a timer is initiated or elapsed and code triggered. Is there something in particular that I should look at? I know for sure that the SYSLOG+WALL are firing when a UPS event is triggered. I have specified +EXEC. NOTIIFYCOMD points to a file that exists, and has code, and is executable. It is an expanded version of the one on this site, trying to have multiple triggers that might work.
I have a lot of AT ONBATT that star timers, anywhere from 10 seconds to 10 minutes. The path with the .pipe and .lock files exists.
I do believe that I understand what is required for setup thanks to your post here, and also reading the documentation, but something is not quite right, and the timers do not work at all. Anything I should focus on?
Thanks
Hello. Thank you for the instructions. I have most of this working, with the exception of the timed events. I am watching “tail /var/log/syslog”, and I see that the timers appear to start, and I can see them triggering. But in syslog, I am seeing error code 2.
Sep 19 00:29:34 pihole1 upssched[13626]: exec_cmd(/usr/bin/upssched-cmd twominstoearlyshutdown) returned 2
What would I hav
e doone wrong to get erroor code 2, and how do I go about solving it? Thanks
Quick heads up that this line:
logger -t upssched-cmd “The UPS has been on battery for awhile
should have a double quote at the end. Thanks for the instructions, I have got the NUT server set up and doing what I need.
Good Catch! Thanks for the note.
I have one question. Above you use an asterisk (*) to denote “…messages coming from the monitor (named “*”)…”. So if I name my UPS as UPS1 do I than replace the asterisks where they occur with UPS1 or just leave it as an asterisk?
Attempting to generate an alert on battery power, and I see in syslog where upsmon recognizes the UPS is on battery power, but I don’t see my script get kicked off.
upssched.conf:
CMDSCRIPT /etc/nut/upsTeamsAlert.py
PIPEFN /etc/nut/upssched/nut.pipe
LOCKFN /etc/nut/upssched/nut.lock
AT ONBATT * START-TIMER onbatt 10
I know the script works on it’s own, but it’s not being called from upsmon. Any suggestions on what to look for?
I have followed all instructions to the tee.. changing the username and passwords as needed, but I keep getting an error preventing the slave from connecting to the master.
bhogg@network:~ $ sudo upsc servers@192.168.25.202
Error: Connection failure: Connection refused
the master is at 192.168.25.202
bhogg@network is the slave pi
any thoughts or suggestions?