Skip to content

Uninterruptible Power Supply (UPS)

UPS setup

  1. Plug devices into critical / noncritical outlet groups, where noncritical outlets get shut down first

OPNsense as Network UPS Tools (NUT) Server

Connect the UPS to the OPNsense host via USB; it runs the NUT server and acts as the single monitoring endpoint for the rest of the homelab.

Refs:

  • https://schnerring.net/blog/configure-nut-for-opnsense-and-truenas-with-the-cyberpower-pr750ert2u-ups/
  • https://forum.opnsense.org/index.php?topic=27936.0
  1. Install NUT plugin

  2. Restart

  3. Configure NUT

  4. General Settings > General Nut Settings

    • Name will be used as address for all netclients
  5. General Settings > Nut Account Settings
    • Monitor Password is password for monuser account that will be used for all netclients
  6. UPS Type > USBHID-Driver

    • [x] enable
  7. Configure NAT: port forward internal traffic hitting firewall IPs port 3493 to 127.0.0.1:3493

  8. Test

sh upsc <UPS_NAME>@<OPNSENSE_IP>:3493

TrueNAS integration

  1. Ensure NUT configured on OPNsense (acting as NUT server)

  2. On TrueNAS, test with:

sh upsc <UPS_NAME>@<OPNSENSE_IP>:3493

  1. Find configuration: System Settings > Services > UPS

  2. TrueNAS config

  3. Test that it actually shuts devices down:

sh # from server (OPNsense) upsmon -c fsd

Ordered shutdowns

Goal: linux machines shut down first, then TrueNAS, then OPNsense (primary).

NUT does not provide strict ordering between secondaries, so use FINALDELAY per host to stagger shutdowns and set HOSTSYNC on the primary long enough to wait for secondaries.

Suggested delays:

  • Linux (secondary): FINALDELAY 5
  • TrueNAS (secondary): FINALDELAY 600 (or more if kubernetes shutdowns are slow)
  • OPNsense (primary): FINALDELAY 900
  • OPNsense HOSTSYNC: >= 900

Linux clients in this repo use templated values:

  • nut.nut_finaldelay for FINALDELAY
  • nut.nut_hostsync for HOSTSYNC

HOSTSYNC meaning differs by role:

  • Primary (OPNsense): how long the master waits for secondaries to disconnect after FSD; should be >= the longest secondary FINALDELAY.
  • Secondary (Linux/TrueNAS): how long to wait for the master to set FSD if the UPS is critical; keep modest (e.g., 30) to avoid long hangs.

Linux configurations

These samples apply to NUT clients (Linux) connecting to the OPNsense NUT server.

nut.conf

MODE=netclient

upsmon.conf

MONITOR PR1500RT2U@<opnsense_address>:3493 1 monuser <password> slave
# bsd
; SHUTDOWNCMD "/usr/local/etc/rc.halt"
# linux
SHUTDOWNCMD /sbin/shutdown -h +0
POWERDOWNFLAG /etc/killpower
FINALDELAY 5
HOSTSYNC 30

TrueNAS configuration (UI-driven)

TrueNAS generates NUT config files from the UI; do not edit upsmon.conf or upssched.conf directly.

Recommended UI settings:

  • Shutdown Mode: UPS goes on battery
  • Shutdown Timer: 600
  • Shutdown Command: /sbin/shutdown -P +1
  • Power Off UPS: unchecked
  • No Communication Warning Time: 120
  • Host Sync: 30

These map to the generated config roughly like this:

/etc/nut/upsmon.conf:

MONITOR <redacted> SLAVE
NOTIFYCMD /usr/sbin/upssched
NOTIFYFLAG ONBATT SYSLOG+EXEC
NOTIFYFLAG LOWBATT SYSLOG+EXEC
NOTIFYFLAG ONLINE SYSLOG+EXEC
NOTIFYFLAG COMMBAD SYSLOG+EXEC
NOTIFYFLAG COMMOK SYSLOG+EXEC
NOTIFYFLAG REPLBATT SYSLOG+EXEC
NOTIFYFLAG NOCOMM SYSLOG+EXEC
NOTIFYFLAG FSD SYSLOG+EXEC
NOTIFYFLAG SHUTDOWN SYSLOG+EXEC
SHUTDOWNCMD "/sbin/shutdown -P +1"
HOSTSYNC 60
NOCOMMWARNTIME 120

/etc/nut/upssched.conf:

CMDSCRIPT   "/usr/bin/sudo /usr/local/bin/custom-upssched-cmd"
PIPEFN      /var/run/nut/private/upssched.pipe
LOCKFN      /var/run/nut/private/upssched.lock

AT NOCOMM   * EXECUTE NOTIFY-NOCOMM
AT COMMBAD  * START-TIMER NOTIFY-COMMBAD 10
AT COMMOK   * CANCEL-TIMER NOTIFY-COMMBAD COMMOK
AT FSD      * EXECUTE NOTIFY-FSD
AT LOWBATT  * EXECUTE NOTIFY-LOWBATT
AT ONBATT   * EXECUTE NOTIFY-ONBATT
AT ONLINE   * EXECUTE NOTIFY-ONLINE
AT REPLBATT * EXECUTE NOTIFY-REPLBATT
AT SHUTDOWN * EXECUTE NOTIFY-SHUTDOWN
AT ONBATT   * START-TIMER SHUTDOWN 600
AT ONLINE   * CANCEL-TIMER SHUTDOWN