NUT (Network UPS Tools) Setup

I purchased my current main UPS the Powershield Commander RT PSCRT1100 / Voltronic Power Otima II 1.1K in 2014 and setup NUT about this time, including early conversion to systemd scripts. I notice the Techno Tim Network UPS Tools (NUT) Ultimate Guide late 2022 has a perhaps more modern take on this.

By the way a couple years ago the UPS battery fail alarm went off. It would seem the UPS batteries failed after about 5-6 years of operation. These battery seems to be common lead-acid gel type 12 VDC at 9 AMP-hr (although they look to be the same as 7.2 AMP batteries….) I basically set and forgot them. I understand 5-6 year life is not unreasonably. In any case I purchased some new batteries and replaced and the UPS has continued to function well. The batteries failed again after less than 3 years. The batteries are 12VDC 9AHr SLA with F@ tabs, the power tab width must be 6.3mm not 4.8mm. Two batteries are required, they are wired in series.

NUT is an open source network monitoring and control system. I use a Powershield Commander RT PSCRT1100 a 1100VA/880W, line interactive sinewave UPS. It turns out that this is a slightly modified version of the Voltronic Power Otima II 1.1K. Presumably the unit has been slightly modified for Powershield for the Australian market, mainly hardware plugs and presumably some firmware/software setup. In fact Voltronic Power, headquartered in Taiwan, even states they are a leading OEM/ODM manufacturer of UPSs, AVRs and inverters. The software provided with the UPS is both propriety and bloated. I want a simple efficient command line / daemon based utility that can monitor performance, control as necessary and report on abnormal operation. Unfortunately the NUT project documentation is not simple to follow. I set this up quite some time ago, so this will not necessarily be up to date.

It turns out the nutdrv_qx driver is usually better suited for Voltronic Power UPSs than the Blazer_usb one. See NUT Voltronic Power UPS Protocol, it is also list under the Voltronic Power section, (various)USB of the NUT Hardware compatibility list.

NUT can be installed by sudo apt install nut. The configuration files are located at /etc/nut :

        # driver = blazer_usb # works
        driver = nutdrv_qx # works with more info than blazer_usb
        port = auto
        desc = "KPTreeServer UPS"
        LISTEN 192.168.x.x #IP address of NUT server
        LISTEN 3493 #IPv4 NUT port
        LISTEN ::1 3493 # IPv6 NUT port 
        password = {password}
        actions = SET
        instcmds = ALL
        MONITOR KPBUPS@localhost 1 admin {password} master
        SHUTDOWNCMD "/sbin/shutdown -h +0"
        NOTIFYCMD /home/baumkp/Myscripts/nut-notify.sh
        POLLFREQ 5
        HOSTSYNC 15
        DEADTIME 15
        POWERDOWNFLAG /etc/killpower
        RBWARNTIME 43200
        FINALDELAY 5
        CMDSCRIPT /bin/upssched-cmd # default

Ensure ownership and permissions are as follows: sudo chown root:nut /etc/nut -R and sudo chmod 640 /etc/nut -R“\.

The output of /bin/upsc KPBUPS@localhost, (or simply upsc KPBUPS):

Init SSL without certificate database
battery.charge: 100                  #calculated value
battery.charge.low: 25               #Set value LB (Low Battery Alarm)
battery.charge.restart: 30           #Set value
battery.charge.warning: 60           #Set value
battery.energysave: no
battery.packs: 1                     #Fix value
battery.protection: yes
battery.runtime: 1680                #calculated value
battery.runtime.low: 420             #Set value
battery.runtime.restart: 180         #Set value
battery.voltage: 27.30
battery.voltage.high: 26.9           #Set value for calculation
battery.voltage.low: 21.5            #Set value for calculation
battery.voltage.nominal: 24.0        #nominal/design value
device.model: LIHVX1K1               #Fix value
device.type: ups                     #Fix value
driver.name: nutdrv_qx
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.version: 2.7.2                #Fix value
driver.version.data: Voltronic 0.01  #Fix value
driver.version.internal: 0.06        #Fix value
input.current.nominal: 4.0           #nominal/design value
input.frequency: 50.0
input.frequency.nominal: 50.0        #nominal/design value
input.phases: 1                      #nominal/design value
input.voltage: 241.7
input.voltage.nominal: 230.0         #nominal/set value
outlet.0.switchable: no
output.current: 0.9
output.current.nominal: 4            #nominal/design value
output.frequency: 50.0
output.frequency.nominal: 50.0       #nominal/design value
output.phases: 1                     #nominal/design value
output.power.maximum.percent: 22
output.power.minimum.percent: 21
output.powerfactor: 0.8              #nominal/design value
output.voltage: 241.6
output.voltage.nominal: 230.0        #nominal/set value
ups.beeper.status: enabled
ups.delay.shutdown: 30
ups.delay.start: 180
ups.firmware: 00303.05               #Fix value
ups.firmware.aux: P00                #Fix value
ups.load: 21
ups.power.nominal: 1100              #nominal/design value
ups.productid: 5161                  #Fix value
ups.start.auto: yes
ups.start.battery: yes
ups.status: OL
ups.temperature: 19.4
ups.type: line-interactive           #nominal/design value
ups.vendorid: 0665                   #Fix value

I have been using NUT on my server and UPS now for about 7 years. In all that time I never got the upsmon part of it operational. This monitors the UPS and sends out messages and shutdown the server on UPS low battery.

It would seem that the current NUT package for Ubuntu 18.04 has been correctly configured to operate with systemd. After updating the configuration file restart the computer and confirm if working. So the following instructions are no longer relevant. Interestingly the NUT systemd configuration is still based upon similar systemd scripts and configuration.

The Ubuntu 16.04 NUT scripts seem to be based upon init.d (located in /etc/init.d), in particular /etc/init.d/nut-server and /etc/init.d/nut-client, (with /etc/init.d/nut-monitor being a link to /etc/init.d/nut-client). Systemd seems to have a method for legacy init.d scripts and creates scripts in /run/systemd/generator.late, in particular, ups-monitor.service.

To see running processes use: sudo ps -e | grep nut and sudo ps -e | grep ups*.

Turn off the existing legacy scripts and systemd handlers, as noted above; sudo update-rc.d nut-client disable, sudo update-rc.d nut-server disable and sudo systemctl disable ups-monitor.service. You may also need to disable the following systemd services: nut-client.service, nut-monitor.service and nut-server.service.

The Kepstin blog gives a good NUT and Systemd discussion Network UPS Tools (nut) and systemd. However it is written for Fedora and there are some nuances required to work with Debian/Ubuntu. For a general understanding of Systemd see DigitalOcean references: Understanding Systemd Units and Unit Files, How To Use Systemctl to Manage Systemd Services and Units, and Systemd Essentials: Working with Services, Units, and the Journal.

First we need to get the NUT driver running, “sudo vim /etc/systemd/system/nut-driver.service”

Description=Network UPS Tools - power device driver controller

ExecStart=/sbin/upsdrvctl start
ExecStop=/sbin/upsdrvctl stop


My system takes a bit of time for the network system to fire up, so I delay the NUT driver startup until after the network is up, by adding the directive “After=network-online.target”.

Unfortunately when this script is run, “sudo systemctl start nut-driver.service” it reports failure as it is unable to access the directory ”/var/run/nut“. So we can create the directory with: “sudo mkdir /var/run/nut sudo chown root:nut /var/run/nut sudo chmod 770 /var/run/nut”. This allows nut-driver.service to run, but fails after a reboot. Further investigation shows that ”/var/run“ is a symlink to ”/run“ and the command “df -T” shows that /run is a temporary file system mounted in RAM that must be recreated every boot. Inspection of the init.d NUT files show they include creation of the /var/run/nut directory. In systemd .conf files must be created in the /usr/lib/tmpfiles.d that create these emphemeral directories, see “man tmpfiles.d”. So we need to create the file: “sudo vim /usr/lib/tmpfiles.d/nut-driver.conf” and populate so:

#Type Path        Mode UID  GID  Age Argument
 d    /run/nut    0770 root nut  -   -

Next in order to ensure correct handling of emergency poweroffs and test reboots correctly, check the /lib/systemd/system-shutdown/nutshutdown file exists; “sudo vim /lib/systemd/system-shutdown/nutshutdown” and populate so:

/sbin/upsmon -K >/dev/null 2>&1 && /sbin/upsdrvctl shutdown

Next create the systemd nut server service for /sbin/upsd, configuration file, “sudo vim /etc/systemd/system/nut-server.service

Description=Network UPS Tools - power devices information server



Next create the systemd nut monitor service, /sbin/upsmon, configuration file, “sudo vim /etc/systemd/system/nut-monitor.service

Description=Network UPS Tools - power device monitor and shutdown controller


  • List all the UPS device profile variable /bin/upsc KPBUPS@localhost 2>/dev/null.
  • A script file to succinctly log the UPS data, using cron to run script every 10 minutes sudo Myscripts/UPSScan.sh 2>/dev/null,
    # Logging output for NUT UPS Monitor output
    str0='/bin/upsc KPBUPS@localhost'
    str2=$(echo "$str1" | grep "ups.status:")
    echo $(date +"%Y-%m-%d %H:%M:%S") | awk '{printf "%s  ", $0}'           >>"$strf"
    echo "$str1" | grep "ups.temperature:" | awk '{printf "%s ", $2}'       >>"$strf"
    echo "$str1" | grep "ups.load:" | awk '{printf "%s ", $2}'              >>"$strf"
    echo "$str1" | grep "input.voltage:" | awk '{printf "%s ", $2}'         >>"$strf"
    echo "$str1" | grep "output.voltage:" | awk '{printf "%s ", $2}'        >>"$strf"
    #echo "$str1" | grep "input.voltage.nominal:" | awk '{printf "%s ", $2}'        >>"$strf"
    echo "$str1" | grep "battery.voltage:" | awk '{printf "%s ", $2}'       >>"$strf"
    echo "$str1" | grep "battery.charge:" | awk '{printf "%s ", $2}'        >>"$strf"
    echo "$str1" | grep "battery.runtime:" | awk '{printf "%s ", $2}'       >>"$strf"
    #echo "$str1" | grep "input.frequency:" | awk '{print $2}'              >>"$strf"
    echo "$str1" | grep "input.frequency:" | awk '{printf "%s ", $2}'       >>"$strf"
    echo "$str2" | awk '{                   \
            for (i=2; i<=NF; i++) {         \
                    printf("%s ", $i);      \
            }                               \
            printf("\n") }'                                                 >>"$strf"
  • A script file to rotate a log file out to a dated gzip log file, with a new empty log file, the log file with path is the script input sudo rotatelog.sh /var/log/UPSLog.Log, again can be use with cron monthly to rotate a log file.
    if [ ! -f $logfile ]; then
      echo "log file not found $logfile"
      exit 1
    timestamp=`date +%Y%m%d`
    cp $logfile $newlogfile
    cat /dev/null > $logfile
    gzip -f -9 $newlogfile
  • The NUT service (start / stop / status / restart) command:“sudo systemctl status nut-server.service”
  • To list the available UPS commands: “upscmd -l KPBUPS”
  • Some other scripts:
    • To email notifications from nut: nut-notify.sh (not tested)
      #echo "$*" | mailx -s "UPS Notice" baumkp@gmail.com

The NUT binaries issue a SSL error to STDERR, so the addition of 2>/dev/null suppresses this.

The parameters set in ups.conf; default.battery.voltage.high and default.battery.voltage.low are used to calculate battery runtime and battery charge level and for low battery alarming. These values can be configured to account for varying battery performance, due mainly to type, age.

List the available NUT UPS commands: upscmd -l KPBUPS

Instant commands supported on UPS [KPBUPS]:

beeper.disable - Disable the UPS beeper
beeper.enable - Enable the UPS beeper
beeper.toggle - Toggle the UPS beeper
load.off - Turn off the load immediately
load.on - Turn on the load immediately
shutdown.return - Turn off the load and return when power is back
shutdown.stayoff - Turn off the load and remain off
shutdown.stop - Stop a shutdown in progress
test.battery.start - Start a battery test
test.battery.start.deep - Start a deep battery test
test.battery.start.quick - Start a quick battery test
test.battery.stop - Stop the battery test

Example to disable the UPS beeper: upscmd KPBUPS@localhost beeper.disable it will then prompt for NUT user and password.

The command will prompt for a user then password. This is a valid user and password define for the NUT installation as defined in the file /etc/nut/upsd.users as noted above.

                      T         Voltage      Battery                S
                      e     L                V     C    R t   f     t
                      m     o                o     h r  u i   r     a c
                      p     a                l     a g  n m   e     t o
                            d   in    out    t       e    e   q     u d
                      o                                             s e
YYYY-MM-DD  HH:MM:SS  C     %   VAC   VAC    VDC   %    Sec   Hz    
2020-12-01  00:20:01  20.3  11  244.7 243.9  27.30 100  3660  50.0  OL

Some known Status Code:

  • OL = On Line (running from main power supply, no adjustments)
  • OB = On Battery
  • ALARM OL RB = Alarm, On Line, Replace Battery
  • OL CAL = On Line Calibrating
  • Systemctl related commands:
    • Systemd common commands (start / stop / restart / status) (enable / disable for boot control)
    • List current Systemd operating units: sudo systemctl list-units | grep '*. Change or remove the grep statement as required.
    • Check the boot journal: journalctl -xe
  • To check running process with open for openvpn(/del, for deluge) ps -A | grep open

  • /app/www/public/data/pages/home_server/home_server_setup/other_services/nut.txt
  • Last modified: 2023-05-13 Sat wk19 10:20
  • by baumkp