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 Configuration Files
NUT can be installed by sudo apt install nut
. The configuration files are located at /etc/nut
:
nut.conf MODE=standalone
ups.conf [KPBUPS] # driver = blazer_usb # works driver = nutdrv_qx # works with more info than blazer_usb port = auto desc = "KPTreeServer UPS" default.battery.voltage.high=26.9 default.battery.voltage.low=21.5 default.battery.charge.low=25 default.battery.charge.warning=60 default.battery.charge.restart=30 default.battery.runtime.low=420 default.battery.runtime.restart=180
upsd.conf LISTEN 192.168.x.x #IP address of NUT server LISTEN 127.0.0.1 3493 #IPv4 NUT port LISTEN ::1 3493 # IPv6 NUT port
upsd.users [admin] password = {password} actions = SET instcmds = ALL
upsmon.conf MONITOR KPBUPS@localhost 1 admin {password} master MINSUPPLIES 1 SHUTDOWNCMD "/sbin/shutdown -h +0" NOTIFYCMD /home/baumkp/Myscripts/nut-notify.sh 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 RBWARNTIME 43200 NOCOMMWARNTIME 300 FINALDELAY 5
upssched.conf 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“\
.
NUT Output
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
NUT & Systemd
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”
[Unit] Description=Network UPS Tools - power device driver controller After=network-online.target [Service] ExecStart=/sbin/upsdrvctl start ExecStop=/sbin/upsdrvctl stop Type=forking [Install] WantedBy=multi-user.target
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:
#!/bin/sh
/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
[Unit] Description=Network UPS Tools - power devices information server After=nut-driver.service [Service] ExecStart=/sbin/upsd Type=forking [Install] WantedBy=multi-user.target
Next create the systemd nut monitor service, /sbin/upsmon, configuration file, “sudo vim /etc/systemd/system/nut-monitor.service
[Unit] Description=Network UPS Tools - power device monitor and shutdown controller After=nut-server.service [Service] ExecStart=/sbin/upsmon PIDFile=/run/nut/upsmon.pid Type=forking [Install] WantedBy=multi-user.target
NUT Key commands and scripts
- 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
,#!/bin/bash # Logging output for NUT UPS Monitor output strf='/var/log/UPSLog.Log' str0='/bin/upsc KPBUPS@localhost' str1=$($str0) 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.#!/bin/bash logfile=$1 if [ ! -f $logfile ]; then echo "log file not found $logfile" exit 1 fi timestamp=`date +%Y%m%d` newlogfile=$logfile.$timestamp 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)
#!/bin/sh #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
The following is a list of related commonly used commands and scripts:
- 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