Skip to content

This document is a WORK IN PROGRESS.
This is just a quick personal cheat sheet: treat its contents with caution!


Nut

Nut is an UPS manager, it can gracefully shutdown the system in case of a power outage.

Warning

The content of this cheat sheet is probably deprecated and needs to be updated!

Reference(s)

Table of contents


TODO

Please note that NUT now runs under the 'nut' user.
NUT is in the uucp group for access to RS-232 UPS.
However if you use a USB UPS you may need to look at the udev or
hotplug rules that are installed, and alter them suitably.

You are strongly advised to read the UPGRADING file provided by upstream.

Please note that upsdrv is NOT automatically started by upsd anymore.
If you have multiple UPS units, you can use their NUT names to
have a service per UPS:
ln -s /etc/init.d/upsdrv /etc/init.d/upsdrv.$UPSNAME

If you want apcupsd to power off your UPS when it
shuts down your system in a power failure, you must
add nut.powerfail to your shutdown runlevel:

rc-update add nut.powerfail shutdown

Please note that NUT now runs under the 'nut' user.
NUT is in the uucp group for access to RS-232 UPS.
However if you use a USB UPS you may need to look at the udev or
hotplug rules that are installed, and alter them suitably.

You are strongly advised to read the UPGRADING file provided by upstream.

Please note that upsdrv is NOT automatically started by upsd anymore.
If you have multiple UPS units, you can use their NUT names to
have a service per UPS:
ln -s /etc/init.d/upsdrv /etc/init.d/upsdrv.$UPSNAME

If you want apcupsd to power off your UPS when it
shuts down your system in a power failure, you must
add nut.powerfail to your shutdown runlevel:

rc-update add nut.powerfail shutdown

Install

# emerge --a sys-power/nut
# pacman -S nut
# apt install nut
# yum install nut
# dnf install nut

Config

TODO

Check last update message:

Messages for package sys-power/nut-2.7.4-r4:

Please note that NUT now runs under the 'nut' user.
NUT is in the uucp group for access to RS-232 UPS.
However if you use a USB UPS you may need to look at the udev or
hotplug rules that are installed, and alter them suitably.

You are strongly advised to read the UPGRADING file provided by upstream.

Please note that upsdrv is NOT automatically started by upsd anymore.
If you have multiple UPS units, you can use their NUT names to
have a service per UPS:
ln -s /etc/init.d/upsdrv /etc/init.d/upsdrv.$UPSNAME

If you want apcupsd to power off your UPS when it
shuts down your system in a power failure, you must
add nut.powerfail to your shutdown runlevel:

rc-update add nut.powerfail shutdown
TODO

If UPS is connected via USB port, add nut user to the usb group:

usermod -a -G usb nut

Now run a scanner to detect the equipment:

# nut-scanner # it should something like the following:
    > Scanning USB bus.
    > Scanning XML/HTTP bus.
    > No start IP, skipping NUT bus (old connect method)
    > [nutdev1]
    >     driver = "usbhid-ups"
    >     port = "auto"
    >     vendorid = "0463"
    >     productid = "FFFF"
    >     product = "Protection Station"
    >     vendor = "EATON"
    >     bus = "003"

Set "MODE" to "standalone" if the machine is connected to the UPS directly and run NUT locally:

# vi /etc/nut/nut.conf
    > ...
    > MODE=standalone
    > ...

Edit the main UPS configuration file:

# vi /etc/nut/ups.conf
    > ...
    > [EATON800] # whatever name
    >     driver = usbhid-ups # the driver name indicated in nut-scanner
    >     port = auto
    >     desc = "Eaton protection station 800" # whatever desccription
    > ...

Configure at least one user so that upsmon can be launched later:

# vi /etc/nut/upsd.users
    >...
    > [monmaster]
    >   password = masterpassword
    >   upsmon master
    >...

Create a monitor configuration:

# vi /etc/nut/upsmon.conf
    > # If you want that NUT can shutdown the computer, you need root privileges
    > RUN_AS_USER root
    >
    > MONITOR EATON800@127.0.0.1 1 monmaster masterpassword master
    >
    > MINSUPPLIES 1
    > SHUTDOWNCMD "/sbin/shutdown -h +0"
    > NOTIFYCMD /usr/sbin/upssched
    > POLLFREQ 5
    > POLLFREQALERT 1
    > HOSTSYNC 15
    > DEADTIME 15
    > POWERDOWNFLAG /etc/killpower
    >
    > NOTIFYMSG ONLINE  "UPS %s on line power"
    > NOTIFYMSG ONBATT  "UPS %s on battery"
    > NOTIFYMSG LOWBATT "UPS %s battery 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
    > 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
    >
    > RBWARNTIME 43200
    >
    > NOCOMMWARNTIME 600
    >
    > FINALDELAY 5

Configure operations on that upsmon will check on the status of the UPS:

# vi /etc/nut/upssched.conf
    > ...
    > CMDSCRIPT /usr/bin/upssched-cmd
    > PIPEFN /var/lib/nut/upssched/upssched.pipe
    > LOCKFN /var/lib/nut/upssched/upssched.lock
    >
    > AT ONBATT * START-TIMER onbatt 300
    > AT ONLINE * CANCEL-TIMER onbatt online
    > 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 REPLBATT * EXECUTE replacebatt
    > ...

Create the script called by upssched:

# mkdir -p /var/lib/nut/upssched
# chown nut:nut /var/lib/nut/upssched
# vi /usr/bin/upssched-cmd
    > ! /bin/sh
    > #
    > # This script should be called by upssched via the CMDSCRIPT directive.
    > #
    > # Here is a quick example to show how to handle a bunch of possible
    > # timer names with the help of the case structure.
    > #
    > # This script may be replaced with another program without harm.
    > #
    > # The first argument passed to your CMDSCRIPT is the name of the timer
    > # from your AT lines.
    >
    > case $1 in
    >         onbatt)
    >                 logger -t upssched-cmd "The UPS is on battery"
    >                 mail -s "The UPS is on battery" admin@example.com
    >                 # For example, uncommenting, you can stop some power-hog services
    >                 #rc-service boinc stop
    >                 #rc-service xmr-stak stop
    >                 ;;
    >         online)
    >                 logger -t upssched-cmd "The UPS is back on power"
    >                 mail -s "The UPS is back on power" admin@example.com
    >                 # For example, uncommenting, you can restart useful power-hog services
    >                 #rc-service boinc start
    >                 #rc-service xmr-stak start
    >                 ;;
    >         commbad)
    >                 logger -t upssched-cmd "The server lost communication with UPS"
    >                 mail -s "The server lost communication with UPS" admin@example.com
    >                 ;;
    >         commok)
    >                 logger -t upssched-cmd "The server re-establish communication with UPS"
    >                 mail -s "The server re-establish communication with UPS" admin@example.com
    >                 ;;
    >         powerdown)
    >                 logger -t upssched-cmd "The UPS is shutting down the system"
    >                 mail -s "The UPS is shutting down the system" admin@example.com
    >                 ;;
    >         replacebatt)
    >                 logger -t upssched-cmd "The UPS needs new battery"
    >                 mail -s "The UPS needs new battery" admin@example.com
    >                 ;;
    >         *)
    >                 logger -t upssched-cmd "Unrecognized command: $1"
    >                 ;;
    > esac

Add nut daemons to OpenRC:

# rc-update add upsdrv default
# rc-update add upsd default
# rc-update add upsmon default


Use

Start the nut daemons if not already started:

# rc-service upsdrv start
# rc-service upsd start
# rc-service upsmon start

Check nut:

# upsc EATON800@127.0.0.1 ups.status


If this cheat sheet has been useful to you, then please consider leaving a star here.