I have PC Engines APU2 board runing OPNsense as my router and APC UPS device that previously was connected to my server. Now I have multiple devices connected to the UPS device and those devices don’t turn off when there is a power failure. So I decided to connect the UPS to my router and install Network UPS Tools (NUT) to solve this problem.


OPNsense NUT installation

Here I used Michael Schnerrings guide as reference Configure NUT for OPNsense and TrueNAS with the CyberPower PR750ERT2U UPS

  1. Install the os-nut plugin under System > Firmware > Plugins
  2. Wait for the plugin to start and refresh the browser, now there should Nut under the Services tab
  3. Set your UPS name on the Nut main settings page Name is used on client devices to read UPS status
  4. Under Services > Nut > Configuration > PS Type click the small down facing arrow next to UPS Type and choose USBHID-Driver
  5. Check Enable to enable the driver
  6. Reboot OPNsense and connect the UPS via USBHID
  7. Set the Monitor Password and Admin Password under Services > Nut > Configuration > click the small small down facing arrow next to General Settings and choose Nut Account Settings
  8. Set Admin Password and Monitor Password

Now there should be data about your UPS under Services > Nut > Diagnostic

It might take few seconds for the data to showup.


Port Forward

Under Firewall > NAT > Port Forward add new rule.

Interface LAN
Source Client(s) IP(s)
Destination LAN address
Destination port range from 3493 to 3493
Redirect target IP 127.0.0.1
Redirect target port 3493
Description Redirect NUT traffic to OPNsense

Install NUT client to a server

In my case I installed nut-client to my Raspberry Pi

Here I used Techno Tims guide as reference Network UPS Tools (NUT) Ultimate Guide

And he has great video about installing NUT:

Here I have the steps I made to install NUT-client to my Raspberry Pi.

sudo apt update

sudo apt install nut-client

Check your connection to OPNsense NUT server, use the UPS name you gave in NUT setup.

upsc [email protected]

You should get same output as in OPNsense > Services > NUT > Diagnostics

sudo nano /etc/nut/upsmon.conf

RUN_AS_USER root

MONITOR apc-modem@ip.address.of.nut.server 1 admin secret slave

MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h"
NOTIFYCMD /usr/sbin/upssched
POLLFREQ 2
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
NOTIFYFLAG NOCOMM   SYSLOG+WALL+EXEC
NOTIFYFLAG NOPARENT SYSLOG+WALL

RBWARNTIME 43200

NOCOMMWARNTIME 600

FINALDELAY 5

Set net client: sudo nano /etc/nut/nut.conf

MODE=netclient

Restart service: systemctl restart nut-client

Check status: systemctl status user-client

Scheduling on the remote system: sudo nano /etc/nut/upssched.conf

CMDSCRIPT /etc/nut/upssched-cmd
PIPEFN /etc/nut/upssched.pipe
LOCKFN /etc/nut/upssched.lock

AT ONBATT * START-TIMER onbatt 120
AT ONLINE * CANCEL-TIMER onbatt online
AT ONBATT * START-TIMER earlyshutdown 120
AT LOWBATT * EXECUTE onbatt
AT COMMBAD * START-TIMER commbad 120
AT COMMOK * CANCEL-TIMER commbad commok
AT NOCOMM * EXECUTE commbad
AT SHUTDOWN * EXECUTE powerdown
AT SHUTDOWN * EXECUTE powerdown

sudo nano /etc/nut/upssched-cmd

#!/bin/sh
 case $1 in
       onbatt)
          logger -t upssched-cmd "UPS running on battery"
          ;;
       earlyshutdown)
          logger -t upssched-cmd "UPS on battery too long, early 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 "UPS has been gone too long, can't reach"
          ;;
       *)
          logger -t upssched-cmd "Unrecognized command: $1"
          ;;
 esac

Make it executable: chmod +x /etc/nut/upssched-cmd

Be sure PIPEFN and LOCKFN point to a folder that esists, I’ve seen it point to /etc/nut/upssched/ instead of /etc/nut If it does, create the folder or update these variables. mkdir /etc/nut/upssched/

Test: systemctl restart nut-client

Then pull the plug on the ups connected to the master, check syslogs: tail /var/log/syslog

If everything works there should be log entrys and the machine should shutdown.