Run various shell commands when NUT reports a low UPS battery

12,260

Solution 1

You could try using upssched.conf(5) to run your own script on a timer after an event has fired.

A basic upssched.conf would be something like this:

CMDSCRIPT /bin/your-script.sh
AT ONBATT * EXECUTE emailonbatt
AT ONBATT * START-TIMER upsonbatt 300
AT ONLINE * EXECUTE emailonline
AT ONLINE * CANCEL-TIMER upsonbatt upsonline

With this, NUT will:

  • Immediately after the UPS goes on battery, run /bin/your-script.sh emailonbatt.
  • Five minutes after the UPS goes on battery, run /bin/your-script.sh upsonbatt.
  • Immediately after the UPS regains line power, run /bin/your-script.sh emailonline.
  • Immediately after the UPS regains line power, also cancel the upsonbatt timer if it is still active. Otherwise, run /bin/your-script.sh upsonline.

The script could be something like:

#!/bin/bash
case $1 in
        emailonbatt)
                  mail -s "UPS on battery power" [email protected]
                  ;;
        emailonline)
                  mail -s "UPS on line power" [email protected]
                  ;;
        upsonbatt)
                  ssh root@nas shutdown -h +0
                  ;;
        upsonline)
                  etherwake 01:23:45:AB:CD:EF
                  ;;
esac

The syntax for the AT statement can be found in the man page for upssched.conf(5), and the notify event types available can be found in the man page for upsmon(8).

Solution 2

what you are trying to do (use a pre-established hook) is the most elegant approach.

But when that is not possible because there is no hook or the ones do not suit your needs, a polling approach is also an option.

You could monitor the output of the NUT components at /var/log files.

Mine (Salicru UPS on Debian 7), for example logs this:

Oct 28 13:37:49 hostname upsmon[1766]: UPS salicru@caramon on battery

when the UPS switches to battery, and this

Oct 28 13:39:39 hostname upsmon[1766]: UPS salicru@caramon on line power

when power is back.

You could simulate a power failure, see the log messages and then write a cron job that runs every minute (or 5 mins), looks for those lines at the logs and takes the action that you want.

Share:
12,260

Related videos on Youtube

CDuv
Author by

CDuv

Updated on September 18, 2022

Comments

  • CDuv
    CDuv almost 2 years

    On a Debian server I've successfully installed the nut package so that my Ellipse PRO 1200 UPS's status can be fetched via USB (upsc my-ups returns battery level).

    Note: I haven't tested what will happens when a power outage occurs yet.

    This UPS serves power to other devices than this Debian server: some routers/switches and a NAS.

    In this case, considering how I think NUT works, I should install NUT on the NAS and declare it as a NUT slave, this way the Debian server (NUT master) would order the NAS to shutdown when battery are low and then shut itself down.

    The problem is that I cannot install NUT on the NAS (OS is not supported), but I can SSH to it an tell it to shutdown.

    How/where can I place my own script(s) alongside with what NUT would normally run to order it's slave to shutdown?

    The only place I could find is SHUTDOWNCMD in /etc/nut/upsmon.conf file:

    SHUTDOWNCMD "/sbin/shutdown -h +0"
    

    I'm guessing I could replace this command with a hand-made script that would run that SSH-shutdown-command and ends by shutdowning the Debian server too.

    Problem is SHUTDOWNCMD seems to be meant for last-time actions: when battery is very low. Contacting all the other devices in my own script could take more time than I have before running out of battery.

    Thanks