APC Back-UPS BX1400U-FR

DIY HOME SERVER 2021 – Software – PROXMOX – NUT UPS Monitoring

1. DIY HOME SERVER - PROXMOX - UPS

When building a home lab server, you’re mostly going to use some kind of Uninterruptible Power Supply (UPS).

It’s important for your home servers to always know the status of the UPS providing the power. This makes it possible to gracefully shutdown all systems before the UPS batterries get drained.

APC Back-UPS BX1400U-FR
APC Back-UPS BX1400U-FR

In most cases, home users are running one or multiple Proxmox bare metal servers, each running several VMs and containers. Each virtualisation host can shutdown all of its own clients during a normal shutdown sequence.  But therefore each host has to be aware of the UPS status.

Most UPS have one port to connect them to computers or servers for management purposes. On the budget friendly devices, you’ll find a USB or serial connector. The more expensive devices often have an ethernet port.

My APC Back-UPS BX1400U-FR UPS is just a cheap and simple 700 Watt/1.4 kVA device. It has only 4 230V output sockets, but that’s not a problem because all devices in my network rack are connected to one single surge protected power distribution unit. The UPS has one USB port to communicate with connected devices.

Tip :
Before buying a certain UPS, always first check replacement batteries prices and availability!
I especially chose this UPS because replacement batteries are widely available, afordable and don’t have any exotic dimensions.

2. DIY HOME SERVER - PROXMOX - NUT

We’ll use the Open Source Network UPS Tools (NUT) to communicate with the UPS.

Because there’s only one (USB) port, this means that only one computer or server can communicate with the UPS directly. This brings us to the following topologies :

“Simple” configuration :

One UPS, one computer or server. This is also known as a “Standalone” configuration.

This is the configuration that most users will use. You need at least a driver, upsd, and upsmon running.

“Advanced” configuration :

One UPS, multiple computers or servers. Only one of them can actually talk to the UPS directly. That’s where the network comes in. The Master system runs the driver, upsd, and upsmon in master mode. The Slave systems only run upsmon in slave mode.

This is useful when you have a very large UPS that’s capable of running multiple systems simultaneously. There is no longer the need to buy a bunch of individual UPSes or “sharing” hardware, since this software will handle the sharing for you.

In our example, we’ll setup a “simple” configugartion. The UPS USB port is connected directly to an USB port on the Proxmox server.

Shutdown timeline (simple configuration) :

  • Main power failure occurs :
    • UPS device switches power to battery
    • UPS device notifies server with a “On battery” event message
  • USP battery is getting close to depletion :
    • UPS device notifies server with a “Battery low” event message
    • Server waits the set “Final delay” time
    • Server starts his shutdown procedure :
      • Sets the “Kill power” flag
      • Ends all running processes
      • Unmounts all file systems
      • Remounts file systems as read-only
      • Looks for the “Kill power” flag
      • Issues the “Kill power” command to the UPS device
      • Halts the system, but doesn’t power off
    • UPS device receives the “Kill power” command from the server :
      • UPS waits for the “Shutdown delay” time to pass
        This is to give all systems enough time to properly shut down
      • UPS device cuts power on all outlets
      • All connected systems lose power
    • Main power supply has been restored :
      • UPS device starts to reload its battery
      • UPS device waits for the “Startup delay” time to pass
        This is to reload the battery to a safe minimum level
      • UPS device restores power on all outlets
      • All connected systems start up again

If you want to set up an advanced configuration, please consult this excellent post.

We’ll install :

  1. NUT server and NUT client directly on to our Proxmox PVE.
    The server will communicate with the UPS over the USB connection and serve the data to all listening clients.
    The client will listen to the server and take appropriate actions depending on the UPS status.
  2. NUT client and an Apache webserver on a dedicated LXC container. This client will also listen to the server and present the UPS statistics in a graphical user interface.
    We use a seperate LXC container because, for security reasons, we don NOT want to install a webserver directly onto our Proxmox PVE.

NUT is a pain to configure. But it’s well documented and worth the pain.

3. DIY HOME SERVER - PROXMOX - NUT Installation

In Proxmox, select your PVE node → Shell.
Or use your favorite remote connection tool to connect to your proxmox server.

List all USB ports :
lsusb
Note the Bus and Device of your UPS device.
List the USB port details :
lsusb -v -s [bus]:[device]
In my case :
lsusb -v -s 2:2

Tip : If the above does not work, replace the USB cable and reboot the system.

Install NUT :

apt install nut -y

Probe the NUT devices :

nut-scanner -U

Take note of these values.

a. /etc/nut/nut.conf

Backup /etc/nut/nut.conf :

cp /etc/nut/nut.conf /etc/nut/nut.example.conf

Edit /etc/nut/nut.conf :

nano /etc/nut/nut.conf

Delete all and add :

MODE=netserver
Ref : nut.conf(5)

b. /etc/nut/ups.conf

Backup /etc/nut/ups.conf :

cp /etc/nut/ups.conf /etc/nut/ups.example.conf

Edit /etc/nut/ups.conf :

nano /etc/nut/ups.conf

Delete all and add :


pollinterval = 15
maxretry = 3
offdelay = 120 ondelay = 240 [apc] # APC Back-UPS BX1400U-FR driver = usbhid-ups port = auto desc = "APC Back-UPS BX1400U-FR" vendorid = 051D productid = 0002 serial = xxxxxxxxxxxx

Use the values returned by the nut-scanner command above.

After saving the file, you can test it by entering the command :
upsdrvctl start
You should get a return like :
Network UPS Tools - UPS driver controller 2.7.4
Network UPS Tools - Generic HID driver 0.41 (2.7.4)
USB communication driver 0.33
Using subdriver: APC HID 0.96

Please check the Network UPS Tools – Hardware Compatibility List to identify the correct driver suited for your UPS.

c. /etc/nut/upsd.conf

Backup /etc/nut/upsd.conf

cp /etc/nut/upsd.conf /etc/nut/upsd.example.conf

Edit /etc/nut/upsd.conf :

nano /etc/nut/upsd.conf

Delete all and add :

LISTEN 0.0.0.0 3493
LISTEN :: 3493

By using 0.0.0.0 instead of 127.0.0.1 we instruct the server to respond to requests from all networks.

Ref : upsd.conf(5)

d. /etc/nut/upsd.users

Backup /etc/nut/upsd.users

cp /etc/nut/upsd.users /etc/nut/upsd.example.users

Edit /etc/nut/upsd.users :

nano /etc/nut/upsd.users

Delete all and add :

[upsadmin]
# Administrative user
password = ********
# Allow changing values of certain variables in the UPS.
actions = SET
# Allow setting the "Forced Shutdown" flag in the UPS.
actions = FSD
# Allow all instant commands
instcmds = ALL
upsmon master

[upsuser]
# Normal user
password = ********
upsmon slave

Replace ******** with your own password(s).

e. /etc/nut/upsmon.conf

Backup /etc/nut/upsmon.conf :

cp /etc/nut/upsmon.conf /etc/nut/upsmon.example.conf

Edit /etc/nut/upsmon.conf :

nano /etc/nut/upsmon.conf

Delete all and add : 

RUN_AS_USER root
MONITOR apc@localhost 1 upsadmin ******* master

MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h"
NOTIFYCMD /usr/sbin/upssched
POLLFREQ 4
POLLFREQALERT 2
HOSTSYNC 15
DEADTIME 24
MAXAGE 24
POWERDOWNFLAG /etc/killpower

NOTIFYMSG ONLINE "UPS %s on line power"
NOTIFYMSG ONBATT "UPS %s on battery"
NOTIFYMSG LOWBATT "UPS %s battary 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+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
NOTIFYFLAG NOCOMM   SYSLOG+WALL+EXEC
NOTIFYFLAG NOPARENT SYSLOG+WALL

RBWARNTIME 43200
NOCOMMWARNTIME 600

FINALDELAY 5

Replace ******** with your own password(s).

Tip :

If you frequently loose the USB connection (data becomes stale) between your server and the UPS, then change the values for :

  • POLLFREQ
  • POLLFREQALERT (= POLLFREQ / 2)
  • DEADTIME (= POLLFREQ * 6)
  • MAXAGE (= POLLFREQ * 6)

f. /etc/nut/upssched.conf

Backup /etc/nut/upssched.conf

cp /etc/nut/upssched.conf /etc/nut/upssched.example.conf

Edit /etc/nut/upssched.conf :

nano /etc/nut/upssched.conf

Delete all and add :

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

AT ONBATT * START-TIMER onbatt 30
AT ONLINE * CANCEL-TIMER onbatt online
AT ONBATT * START-TIMER earlyshutdown 30
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 SHUTDOWN * EXECUTE powerdown

A tip from TechnoTim

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/

g. /etc/nut/upssched-cmd

(If exists) Backup /etc/nut/upssched-cmd :

cp /etc/nut/upssched-cmd /etc/nut/upssched-cmd.example

Edit /etc/nut/upssched-cmd :

nano /etc/nut/upssched-cmd

(Delete all and) Add :

#!/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

Then :

chmod +x /etc/nut/upssched-cmd

Now reboot your Proxmox server. Or enter the following command sequence to restart the services : 

service nut-server restart
service nut-client restart
systemctl restart nut-monitor
upsdrvctl stop
upsdrvctl start

Test your configuration by running the command :

upsc apc@localhost

You should see the UPS replying its data.

Tip : If the above does not work, replace the USB cable and reboot the system once again.

At the moment, the system is configured to shut down when the UPS runtime or battery charge values fall below their values. By default, those values are way too low on an APC UPS, so we will set this parameter to a higher value to keep enough reserves in the UPS. You can list the editable values :
upsrw apc@localhost
We will set the parameter for minimum runtime to 10 minutes and the minimum charge to 50% :
upsrw -s battery.runtime.low=600 apc@localhost 
upsrw -s battery.charge.low=50 apc@localhost
These commands will ask for a username and password. Be sure to use the upsadmin account and password specified in /etc/nut/upsmon.conf and /etc/nut/upsd.users. New values will be visible after restart.

4. DIY HOME SERVER - PROXMOX - NUT Monitoring

a. Create LXC container

Let’s create a new LXC container and install nut-client to monitor the UPS.

In Proxmox, select local (storage) → CT Templates → Templates.

In the dropdown, select the latest Ubuntu LTS (.04) template and click the Download button.

Click the Create CT button to create a new LXC.

On the General tab, specify the container name an set the password for the root user.

Click Next

On the Template tab, select the latest Ubuntu CT Template.

Click Next.

On the Root Disk tab, set a 2 GB Disk size.

Click Next.

On the CPU tab, there’s nothing to change.

Click Next.

On the Memory tab, there’s nothing to change.

Click Next.

On the Network tab, set the static IP address and specify the Gateway.

Click Next.

On the DNS tab, there’s nothing to change.

Click Next.

On the Confirm tab, check the Start after created option. 

Click Finish.

The container will be installed.

Select the container and click Options → Start at boot → Edit.

Set the Start at boot option and click OK.

In Proxmox, select the newly created LXC container and open the Console

Update and upgrade the system :

apt update && apt upgrade -y

Install openssh-server to allow remote access :

apt install openssh-server -y

Configure the openssh-server :

nano /etc/ssh/sshd_config

Uncomment or add :

PasswordAuthentication yes
PermitRootLogin yes

Save the file.

Restart openssh-server :

systemctl restart ssh

Install an Apache webserver and nut-cgi :

apt install apache2 nut-cgi -y

Install NUT client :

apt install nut-client -y

b. /etc/nut/nut.conf

Backup /etc/nut/nut.conf :
cp /etc/nut/nut.conf /etc/nut/nut.example.conf
Edit /etc/nut/nut.conf :
nano /etc/nut/nut.conf
Delete all and add :
MODE=netclient
Ref : nut.conf(5)

c. /etc/nut/hosts.conf

Backup /etc/nut/hosts.conf :

cp /etc/nut/hosts.conf /etc/nut/hosts.example.conf

Edit /etc/nut/hosts.conf :

nano /etc/nut/hosts.conf

Delete all and add :

MONITOR apc@xxx.xxx.xxx.xxx "APC Back-UPS BX1400U-FR"

Replace xxx.xxx.xxx.xxx with the IP address of your Proxmox (NUT) server.

Ref : hosts.conf(5)

d. /etc/nut/upsset.conf

Backup /etc/nut/upsset.conf :
cp /etc/nut/upsset.conf /etc/nut/upsset.example.conf
Edit /etc/nut/upsset.conf :
nano /etc/nut/upsset.conf
Delete all and add :
I_HAVE_SECURED_MY_CGI_DIRECTORY

e. /etc/nut/upsmon.conf

Backup /etc/nut/upsmon.conf

cp /etc/nut/upsmon.conf /etc/nut/upsmon.example.conf

Edit /etc/nut/upsmon.conf :

nano /etc/nut/upsmon.conf

Delete all and add :

RUN_AS_USER root
MONITOR apc@xxx.xxx.xxx.xxx 1 upsuser ******* slave

Replace xxx.xxx.xxx.xxx with the IP address of your Proxmox (NUT) server.
Replace ******** with your own password(s).

Enter the command :
sudo a2enmod cgi
Then restart the webserver :
sudo systemctl restart apache2

Now test the monitoring. Open a new browser tab and go to the UPS status page :

http://xxx.xxx.xxx.xxx/cgi-bin/nut/upsstats.cgi

Replace xxx.xxx.xxx.xxx with the IP address of your LXC container.

5. Testing

a. System shutdown

Now you can test if your system shuts down gracefully.
In Proxmox, select your PVE node → Shell.

Issue the following command :

upsmon -c fsd

Your system should shut down all its subsystems and then shutdown itself.

b. Power outage

Now you are ready to pull the AC power plug going from your AC wall outlet to the UPS.
At the moment the UPS reaches the values set in battery.runtime.low or battery.charge.low, the shutdown should be initiated.

28 Comments

  1. Thanks very much for the well documented setup procedures for Nut server and client. There were definitely a lot of steps and configs to attend to but you provided all that was needed. My UPS was a Tripp Lite so I had to use a different driver and I used a different name than apc@ so I had to modify the configs. I also created the LXC container and got that working as well. The upsrw examples do not work with the Tripp Lite and there does not appear to be equivalent settings. When I list the settings they are drastically different and I don’t understand what they are. I think though the Tripp Lite just issues a low battery notice at a prescribed % (probably 50%) but I have not had time to test that. There is no way I could have completed this without your fine efforts! Thanks again.

    Scott.

  2. Hi Marc, thanks for your guide. I’m using it on a system runnin Proxmox 8 and a small APC UPS. When I unplug the system PC starts a 30′ countdown and shutdowns the system, which is not the expected behavior. In fact in upssched.conf you have “AT ONBATT * START-TIMER onbatt 30” which I guess supersedes all other timers and shutdown events you wanted to set.

    In other words, you state “At the moment, the system is configured to shut down when the UPS runtime or battery charge values fall below their values. ” but those directives AT ONBATT * START-TIMER onbatt 30 and AT ONBATT * START-TIMER earlyshutdown 30 in the upssched.conf seem to supersede ALL other settings. Do you agree?

    My goal would be to shutdown my PC when battery charge reaches 40% (or, in alternative, after 15 minutes on battery).

    Can I have your opinion?
    Thanks in advance
    Cheers

    • Hi Fabbio,

      At the moment I’m busy with other projects and don’t have the time to look into this issue.
      Feel free to experiment on your system until you have found a working solution.
      Then please report back to me so I can correct my article to inform other readers the correct way.
      I’m sorry I can’t be of more help at this time. Succes.

      Kind regards.
      Marc

      • He is right, it shuts down after 30 seconds. DO NOT USE THIS GUIDE OTHERWISE YOUR PC WILL SHUT DOWN AFTER 30 SECONDS

        • Hi all,

          At the moment, I do not have the time to look into this.
          But take a look at this post where this topic is worked out in the same matter but with more detail.

          Please contact me when you can solve the issue.
          Thanks.

        • Hi, would you be so kind to test the solution mentioned by elPapaPig below and report back if it improves the situation? This way we can solve the issue and optimize the scripts for future readers.

          Thanks in advance.

          Marc

      • Hi, would you be so kind to test the solution mentioned by elPapaPig below and report back if it improves the situation? This way we can solve the issue and optimize the scripts for future readers.

        Thanks in advance.

        Marc

    • Hello Flabio,

      I have the same problem as you. Have you found a solution? The configuration to achieve your goal?

  3. Hello,
    As I was losing connection, i change this parameters to this

    POLLFREQ 2
    POLLFREQALERT 1
    DEADTIME 12
    MAXAGE 12

    Are these OK?
    I will give feedback afterwards.

    • Well, as I said, I changed the parameters in order to keep the connection, but it still fails after some time.

      UPS apc@localhost is unavailable

      Can someone help where to start how to debug?

      • Hi Fabio,

        You could try replacing the USB cable by a better one. You could try another USB port (USB 2 or USB 3).
        If that doesn’t help, you have a problem with the driver or the settings.

        Kind regards.

        Marc

  4. Nice guide, thanks. All working as expected but using the web monitor on separate LXC as you suggest I can only access the UPS data if the PVE firewall is off. I can’t work out how to allow it through. The obvious ones like enabling WEB and the port 3493 do not do it. The same happens with Windows NUT client and the docker method in Techno Tim’s article you refer to.

  5. Hi, thanks for an awesome tutorial! I’ve been going through some of your other tutorials too and they are really well done. I especially appreciate the screenshots of expected output. I was able to follow this one all the way through the end, but when I went to test a NUT directed shutdown of my Proxmox, I ran into some problems. I tried by unplugging my UPS and waiting for the low battery mark. It came and went, but no shutdown signal was sent. I googled around and found a way to test by using the following command on the host (pve node):

    upsmon -c fsd

    I get the error back:
    Network UPS Tools upsmon 2.7.4
    fopen /run/nut/upsmon.pid: No such file or directory

    Any ideas how to work through this? Was I correct to try and run this command from the pve node and not the LXC container? I did some googling on this pid issue, but wasn’t quite able to follow the chatter. Some were suggesting workarounds, but I wanted to check here in case there is a Proxmox specific situation that I might be running into.

    FYI, I’m running this as root on my pve node. Also if it helps, the command ‘which upsmon’ tells me that my upsmon is located in /usr/sbin

    Thanks!
    Dave

  6. Very good tutorial, thank you!
    Unfortunately I have the problem that my proxmox host immediately shuts down all clients and then itself on power failure instead of waiting for battery.charge.low.
    With Eaton there is also no battery.runtime.low.
    Do you have any idea what this could be?

  7. Hello,
    What an amazing guide, very well explained, visually very simple to follow and not mess up.
    The NUT tools are in fact a pain to configure, but with this very detailed guide, it was easy!!!!
    I appreciated a lot the detail of always backing up the default .conf file, very well done, thank you.

    Just two things:
    1- not so important, I didn’t have a /etc/nut/upssched-cmd file, so the cp didn’t work obviously.
    But I follow to the nano command and did everything.

    2-I can’t change the parameters of battery.runtime.low and battery.charge.low.
    I input the commands and nothing happens, nothing is changed.
    I didn’t got the user wrong, as I tried bad password and it gives me denied message.
    I am not using the ups user upsuser, as this one gives me a denied message.
    When I enter the command upsrw -s battery.runtime.low=900 apc@localhost or upsrw -s battery.charge.low=40, with the upsadmin and password, it says OK, but when I list the commands again, they are the same: 300s and 10%.

    I am yet to try the graceful shutdown, I wanted to change the settings first.

    What am I doing wrong?
    Maybe the apc driver with my Cyberpower BU650EU doesn’t allow the change?
    Can you please help?

    Thank you very much!

    • Hi Fabio,
      1. Indeed, just create the /etc/nut/upssched-cmd file and add the content.
      2. Changed values are visible after you restart the services.

      Kind regards…

      • Hello,

        Once again thank you for your help, but something is going on here…

        On the CLI of Proxmox, I ran the commands:

        upsrw -s battery.runtime.low=900 apc@localhost
        (user and pass and gave OK)
        upsrw -s battery.charge.low=40 apc@localhost
        (user and pass and gave OK)

        then once at a time
        service nut-server restart
        service nut-client restart
        systemctl restart nut-monitor
        upsdrvctl stop
        upsdrvctl start

        then
        upsrw apc@localhost

        it shows battery.runtime.low at 600 and not 900, and battery.charge.low keeps at 10

        I tried then battery.runtime.low=500, battery.charge.low=40 and the restart commands, and it changes battery.runtime.low to 500 and battery.charge.low keeps at 10.
        I tried again battery.runtime.low=900, battery.charge.low=40 and the restart commands, and it changes battery.runtime.low to 600 and battery.charge.low keeps at 10.

        I also tried battery.charge.low to 4 and 9, and always kept at 10.

        So it seems that battery.runtime.low is somehow capped to 600 and battery.charge.low can’t be changed.

        I always did this with upsadmin admin user and always gave OK.

        Is there any other command that is overriding these ones?
        Are there any other UPS drivers?
        Is this a known problem?
        Have you ever encountered this?

        Thank you very much!

  8. Thanks so much for this awesome tutorial. I greatly appreciate you taking the time to document and share!

  9. Hi Marc,
    Thanks for this very straitforward tutorial. I set up a EATONEllipse Pro 650 with this. With your tutorial this was realy easy.
    The Eaton does not support the battery.runtime parameter, therefore battery.charge.low is the only one I set.

    Instead of a separate LXC Container, I used the NUT Integration of Home Assistant (https://www.home-assistant.io/integrations/nut/) to monitor my UPS. Just enter apc@IP-addr and the credentials of upsuser and you are done.

    Thanks again!
    Markus

  10. This is an awesome guide but after I pull the plug from my UPS, it’s not triggering my master and slave servers to shutdown and I’m not sure how to troubleshoot this. I do see a message on master & slave that the UPS battery is low but it never shuts anything down. Also for some reason I receive a broadcast message that the UPS battery is low even when it’s charged 100%. I checked upsc (battery charge shows 100, battery charge low shows 40, battery runtime shows 1020 and battery runtime low shows 900).

    • No, only on those ProxMox nodes connected to the same UPS.
      Not on their VM’s, they’ll be shut down by their host.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.