UPS Server on Raspberry Pi : homelab
Press J to jump to the feed. Press question mark to learn the rest of the keyboard shortcuts
Trending today
260
Archived
PlatinumGoldWholesomeSilver

UPS Server on Raspberry Pi

This tutorial will allow you to use a Raspberry Pi as a headless UPS server using the Network UPS Tools suite. NUT (http://networkupstools.org) is an extensible and highly configurable client/server application for monitoring and managing power sources. It includes a set of hardware-specific drivers, a server daemon (upsd), and clients like upsmon and upsc.

Why would you need a UPS server? I have a mixed environment with Linux, FreeBSD and Windows clients all hooked up to a single UPS. I want to shut down all services gracefully when the UPS battery is running empty. Setting up a NUT server allows you to do this quite easily. This is also a fun project that may put any RPi you may have laying around to good use in your rack.

The tutorial will take you thru the steps of preparing the SD card, Configure Raspbian, installing and testing the NUT server and deploying the NUT web UI. I have also covered how to configure Proxmox (any Debian/Ubuntu server really), pfSense and Synology DSM as NUT clients to control the graceful shutdown when the UPS battery runs out of power. A bonus step will allow you to get stats from your UPS to InfluxDB/Grafana and monitor your UPS via SNMP.

UPDATE: Added ESXI Client instructions.

What you need:

  • A raspberry Pi (I use a RPi 1 model B but any model should work)

  • SD card (I used a 16GB Samsung EVO)

  • USB cable

  • UPS with a USB interface (This was done on an APC Smart-UPS X 750i but should work with any UPS supported by NUT)

  • A working network and some clients to control from the NUT server

Remember that you will have to power the both the RPi and the network equipment needed to communicate with the clients from the UPS.

Prepare the SD card

Download the latest Raspbian Jessie Lite from: https://www.raspberrypi.org/downloads/raspbian/ Follow the guide for your OS to write it to your SD card: https://www.raspberrypi.org/documentation/installation/installing-images/README.md To enable ssh, you must create an empty file named “ssh” in the root of the SD card. For example on OS X:

touch /Volumes/boot/ssh

Now place the SD card in the RPi, connect it to your network and insert the power supply.

Preparing Raspbian

The RPi will try to get an IP adress from your DHCP server by default, so either check your DHCP leases to get the IP or simply connect to the host by the hostname “raspberrypi” the default username/password is pi/raspberry.

ssh pi@raspberrypi

The first thing you should do is to change the default password, so enter the following command and follow the instructions:

passwd 

The following step is not required and you will have to prefix most commands with “sudo” from now on if you skip it. The root account is disabled by default on Raspbian but I prefer to have it enabled, so:

sudo passwd root

We also have to make it possible to log in as root over ssh so edit /etc/ssh/sshd_config and search for PermitRootLogin and change it to yes. Then restart the ssh daemon using:

sudo service ssh restart

log out and log back in using:

ssh root@raspberrypi

It is time to apply any patches so type in:

apt update && apt upgrade -y

nano should be installed by default but I prefer to use vim to edit config files, so:

apt install vim

We want to access this server using a static IP. This is configured in /etc/dhcpcd.conf add a section like this at the bottom of the file:

interface eth0
  static ip_address=192.168.0.13/24
  static routers=192.168.0.1
  static domain_name_servers=192.168.0.1

Adjust the parameters according to your network and save the file

Now hook up the UPS to the RPi using the USB cable and reboot the RPi.

Install NUT

ssh as root to the RPi and install the NUT-server and NUT-client:

apt install nut

Verify that the UPS is visible on the USB interface using the command:

lsusb

This should return something like this:

Bus 001 Device 004: ID 051d:0003 American Power Conversion UPS
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp. LAN9500 Ethernet 10/100 Adapter / SMSC9512/9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Configure NUT

The first file to edit is /etc/nut/ups.conf Add the following section to the bottom:

[ups]
        driver = usbhid-ups
        port = auto
        desc = "APC Smart-Ups X 750i"

Within the bracket, you can set your UPS name (no space allowed) but keep the name “ups” for easier usage with Synology DSM.

Test the UPS driver by running:

upsdrvctl start

This will return something similar to the below depending on your UPS model and if not, a reboot usually does the trick to get the UPS to play along:

Network UPS Tools - UPS driver controller 2.7.2
Network UPS Tools - Generic HID driver 0.38 (2.7.2)
USB communication driver 0.32
Using subdriver: APC HID 0.95

Upsmon and upsd

The next step is to configure upsmon and upsd of which the later communicates with the UPS driver configured while upsmon monitors and communicates shutdown procedures to upsd. NUT allows multiple instances of upsmon to run on different machines while communicating with the same physical UPS.

For upsd to be accessible via the network we edit /etc/nut/upsd.conf

Uncomment the LISTEN directive for localhost (127.0.0.1) and add another LISTEN directive for the static IP we assigned to the RPi earlier.

LISTEN 127.0.0.1 3493
LISTEN 192.168.0.13 3493

We will also need to add some users to manage access to upsd by editing the upsd users config file /etc/nut/upsd.users and adding the following:

[admin]
        password = hunter2
        actions = SET
        instcmds = ALL
[upsmon_local]
        password  = hunter2
        upsmon master
[upsmon_remote]
        password  = hunter2
        upsmon slave
[monuser]				#This is what Synology DSM expects
        password  = secret   #Leave this here.
        upsmon slave

Then we edit /etc/nut/upsmon.conf and add the UPS to be monitored and user credentials for upsd in the MONITOR section:

MONITOR ups@localhost 1 upsmon_local hunter2 master

And finally edit /etc/nut/nut.conf and set the value for MODE equal to 'netserver' without any spaces before and after the = sign:

MODE=netserver

Verify the configuration

reboot the RPi and verify that the nut-server and local nut-client services are up

service nut-server status
service nut-client status

test the configuration using the following command:

upsc ups

This should produce something like this:

root@raspberrypi:~ # upsc ups
Init SSL without certificate database
battery.charge: 100
battery.charge.low: 10
battery.charge.warning: 50
battery.runtime: 33046
battery.runtime.low: 150
battery.type: PbAc
battery.voltage: 52.4
battery.voltage.nominal: 48.0
device.mfr: American Power Conversion 
device.model: Smart-UPS X 750
device.serial: AS1035120444
device.type: ups
driver.flag.pollonly: enabled
driver.name: usbhid-ups
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.version: 2.7.2
driver.version.data: APC HID 0.95
driver.version.internal: 0.38 
ups.beeper.status: enabled
ups.delay.shutdown: 20
ups.firmware: COM 03.6 / UPS 03.6
ups.mfr: American Power Conversion
ups.mfr.date: 2010/08/24
ups.model: Smart-UPS X 750
ups.productid: 0003
ups.serial: AS1035120666
ups.status: OL
ups.timer.reboot: -1
ups.timer.shutdown: -1
ups.vendorid: 051d

Now you can continue adding NUT-clients on your network, and on the clients set nut.conf MODE=netclient and upsmon.conf to:

MONITOR [email protected] 1 upsmon_remote hunter2 slave

Congratulations. Your NUT server is now officially running!

Web monitoring

You can optionally install a simple web GUI to monitor and control the UPS. This will require a web server on the RPi so we will begin by installing Apache but you can really use whatever cgi-capable web server you want. On the RPi:

apt install apache2

Install the nut-cgi package:

apt install nut-cgi

To monitor the UPS via the web CGI script, add the following line to /etc/nut/hosts.conf:

MONITOR ups@localhost "Local UPS"

Enable CGI support in apache:

a2enmod cgi

Restart Apache:

service apache2 restart

You can now access the web UI via: (http://192.168.0.13/cgi-bin/nut/upsstats.cgi)

Upsset will not run until you convince it that your CGI directory has been secured. You should therefore secure this directory according to the instructions in upsset.conf (outside of the scope of this tutorial) and when you’re done, uncomment the following line in /etc/nut/upsset.conf:

### I_HAVE_SECURED_MY_CGI_DIRECTORY

This will allow you to log in to http://192.168.0.13/cgi-bin/nut/upsset.cgi using the admin user/password we configured in /etc/nut/upsd.users. You will be able to view and set options on your UPS if this is supported by your ups.

Configuring Proxmox/Ubuntu/Debian node as client for remote NUT server

To shut down Proxmox including all VMs and containers gracefully, we need to install nut on the Proxmox server. SSH as root to your PVE host and:

apt update
apt install nut-client

Edit /etc/nut/nut.conf and tell it to act as a client:

MODE=netclient

Edit /etc/nut/upsmon.conf and add a MONITOR directive in the MONITOR section that tells it to listen to the NUT server:

MONITOR [email protected] 1 upsmon_remote hunter2 slave

Start monitoring:

service nut-client start

Verify the installation by checking the UPS status on the NUT server from Proxmox:

upsc [email protected] 

The default NUT shutdown command will let Proxmox shut down all VMs and Containers gracefully before Proxmox is shut down. This is of course depending on if the VMs and Containers allow that, so check your configs.

ESXi

René Margar has ported a NUT client to ESXi. This is is a well maintained client that works on ESXi 5.0, 5.1, 5.5, 6.0 and 6.5. It is available from his blog here: http://rene.margar.fr/2012/05/client-nut-pour-esxi-5-0/ (in French)

We need to enable SSH access first. Connect to the ESXi 6.5 Server using the Web Client. Go to the "default hypervisor home page", click the Host icon, and select Actions (the gear icon). Click Services in the drop-down menu and select Enable Secure Shell (SSH). Then enable console shell from the same menu.

Ssh to the ESXi server and set the hypervisor to the community acceptance level to accept unsigned (community-supported) VIBs. Change the acceptance level of the host by running the following command.

esxcli software acceptance set --level CommunitySupported

Go to the /tmp directory

cd /tmp

And download the NUT ESXi client:

wget http://rene.margar.fr/downloads/NutClient-ESXi-2.0.0.tar.gz

Extract the archive

tar -xzf NutClient-ESXi-2.0.0.tar.gz

Run the installer:

sh upsmon-install.sh

the result should be something like this:

Installation Result
   Message: Operation finished successfully.
   Reboot Required: false
   VIBs Installed: Margar_bootbank_upsmon_2.7.4-2.0.0
   VIBs Removed:
   VIBs Skipped:

You can delete the files that were downloaded and extracted in /tmp directory and disable the SSH service again if you want to.

You must configure NUT before launching for the first time and I found that I needed to reboot the machine for the config vars to appear in the web GUI.

Reboot and log in to the web GUI again. Go to Manage in the Navigator pane. Select the System tab and then Advanced Settings. There are 6 variables to configure for NUT:

  • UserVars.NutUpsName : The name of the UPS on the NUT server (as upsname@server_name or server_ip) ([email protected]). Several UPSes can be entered separated by a space. There will be no system shutdown until the last UPS has issued the stop command.

  • UserVars.NutUser : The account to the NUT server (upsmon_remote)

  • UserVars.NutPassword : Password for the NUT server login account (hunter2)

  • UserVars.NutFinalDelay : Seconds to wait after receiving the low battery event to shut down the system

  • UserVars.NutSendMail : Set to 1 so that the NUT client sends an e-mail for each UPS event

  • UserVars.NutMailTo : The e-mail address to send the UPS events to

Configure the variables and go to the Services tab. Select the NutClient service. Press Start and verify that the service is started.

Configure the NutClient to start automatically by clicking “Conffigure” on the service in the Services tab. Then select the Policy “Start and stop with host”.

That’s it. you’re done! You can use the configuration tab of the ESXi host in the web GUI to configure the order to start and stop (or suspend) virtual machines. This order will be respected by the shutdown procedure on NUT alerts. Clean OS shutdown in virtual machines is only possible if vmware tools are installed on each VM.

To uninstall the NUT client, use the upsmon-remove script in the file that you downloaded earlier:

/tmp # sh upsmon-remove 

To test the installation, type the command "upsmon -c fsd" on the ESXi host (via ssh or on the console). The shutdown procedure is started immediately.

pfSense NUT package

pfSense has a package for NUT so it is trivial to hook it up to the NUT server. In pfSense, go to System/Package Manager/Available Packages and install the nut package. Then go to Services/UPS and the Ups tab and configure the following:

  • UPS Type: Remote Nut Server

  • UPS Name: ups

  • Remote IP adress or hostname: 192.168.0.13

  • Remote Port: 3493

  • Remote Username: upsmon_remote

  • Remote Password: hunter2

Click Save and switch to the UPS status tab to verify that the UPS status is displayed properly.

Synology Diskstation UPS configuration

Synology DSM uses NUT to manage and share UPSes. The NUT UPS name and the username/password for the NUT client in DSM can’t be set in the GUI, but the config we created earlier is set to match what DMS expects, so there is no need to modify anything over SSH unles you want to.

In DSM, go to Control Panel/Hardware and Power and switch to the UPS tab. Configure the following:

  • Enable UPS support: true

  • Network UPS type: Synology UPS server

  • Network UPS server IP: 192.168.0.13

DSM looks for the “ups” UPS entry in /etc/nut/ups.conf on the RPi by default and uses the monuser/secret username/password pair that we created in the /etc/nut/upsd.users file on the RPi

Click save and then the Device Information button to verify that the connection to the RPi works as expected.

Test the NUT server

It is a good idea to test behaviour of the NUT server and connected clients in case of a power outage before it happens. One way to do it is to keep your devices connected to mains during the testing and then move them to the UPS once everything is verified.

To test the server behavior in case of power outage, use the following command on the NUT server:

upsmon -c fsd

If the UPS is connected to mains, the server will stop and then restart (don’t forget to set your BIOS power management to “Always on”). If the UPS is unplugged, the server will restart only after reconnection to mains.

NUT writes to the syslog by default on most Linux systems. You can monitor the log as the shutdown events happen using the command:

tail -f /var/log/syslog

You can also view the upslog status messages using the command:

upslog -s ups -l -

NUT and InfluxDB/Grafana

Here’s a method to push the NUT server UPS status over to InfluxDB/Grafana for monitoring. It uses a Python script from https://github.com/lf-/influx_nut. On the RPi:

apt install python3
apt install python3-pip
apt install git
pip3 install typing
cd /etc/nut/
git clone https://github.com/lf-/influx_nut

Edit /etc/nut/influx_nut/influx_nut.py and configure the settings for your NUT host, your InfluxDB host and what stats to send to InfluxDB. The var names you can use in the “nut_vars” entry can be seen using the command “upsc ups”

DEFAULT_CONFIG = {
    'interval': 20,
    'nut_host': '127.0.0.1',
    'nut_port': 3493,
    'nut_ups': 'ups',
    # variables from NUT to send to influxdb
    "nut_vars": {
      "battery.charge": {
           "type": "int",
           "measurement_name": "ups_charge"
      },
      "battery.runtime": {
           "type": "int",
           "measurement_name": "ups_runtime"
      },
      "battery.voltage": {
           "type": "float",
           "measurement_name": "ups_voltage"
      }
    },
    'influx_host': 'http://192.168.0.37:8086',
    'influx_db': 'telegraf',
    'influx_tags': {"ups": "apc"},
    'influx_creds': ["telegraf", “hunter2”]
}

Test the script:

python3 /etc/nut/influx_nut/influx_nut.py

The result should be something like this:

http://192.168.0.37:8086 {'db': 'telegraf', 'p': ‘hunter2’, 'u': 'telegraf'} b'ups_charge,ups=apc value=100\nups_runtime,ups=apc value=33046\nups_voltage,ups=apc value=52.2'

This should also produce a bunch of entries in your InfluxDB that you can graph using Grafana.

Now make the script run automatically after a reboot by adding the following line to /etc/rc.local:

/usr/bin/python3 /etc/nut/influx_nut/influx_nut.py &

Reboot the RPi to verify that the script starts.

Add SNMP support

You can also enable support for SNMP to the RPI to make it possible to monitor the UPS over the network using SNMP-based tools. This also provides an alternative way to get the stats into InfluxDB using Telegraf and the SNMP plugin if you prefer that over the Python script above. On the RPi:

apt install snmp
apt install snmpd
apt install snmp-mibs-downloader

Create the file /usr/local/bin/ups-status.sh and add the following script:

#!/bin/bash

# read value
VALUE=$(/bin/upsc UPS@localhost $1 2>&1 | /bin/grep -v '^Init SSL')
# return vaue
echo ${VALUE}

Make the script executable:

chmod +x /usr/local/bin/ups-status.sh

Execute the following command to add UPS MIB extensions for all variables reported by upsc to /etc/snmp/snmpd.conf:

upsc ups@localhost | sed 's/^\(.*\): .*$/extend \1 \/usr\/local\/bin\/ups-status.sh \1/' >> /etc/snmp/snmpd.conf

Edit /etc/snmp/snmpd.conf and add the following string to enable connections via the network interface in addition to localhost.

agentAddress udp:192.168.0.13:161 #change this to the static ip of the RPi

Also add the following line to provide snmp access to other machines in the network (You may narrow this down to specific machines if you want to):

rocommunity public

Restart the snmpd daemon:

service snmpd restart

You may get an error like “pcilib: pci_init failed” when the daemon is started due to a bug in Raspbian, but it should work regardless.

You should now be able to get the UPS status values using snmpwalk or snmpget like so:

snmpget -v 1 -c public localhost NET-SNMP-EXTEND-MIB::nsExtendOutputFull.\"battery.charge.low\"
snmpget -v 1 -One -c public localhost .1.3.6.1.4.1.8072.1.3.2.3.1.2.10.100.101.118.105.99.101.46.109.102.114
snmpwalk -v 1 -c public 192.168.0.13 NET-SNMP-EXTEND-MIB::nsExtendOutputFull
snmpwalk -v 1 -One -c public localhost .1.3.6.1.4.1.8072.1.3.2.3.1.2

Example output:

.1.3.6.1.4.1.8072.1.3.2.3.1.2.7.117.112.115.46.109.102.114 = STRING: "American Power Conversion"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.9.117.112.115.46.109.111.100.101.108 = STRING: "Smart-UPS X 750"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.10.100.101.118.105.99.101.46.109.102.114 = STRING: "American Power Conversion"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.10.117.112.115.46.115.101.114.105.97.108 = STRING: "AS1035120444"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.10.117.112.115.46.115.116.97.116.117.115 = STRING: "OL"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.11.100.114.105.118.101.114.46.110.97.109.101 = STRING: "usbhid-ups"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.12.98.97.116.116.101.114.121.46.116.121.112.101 = STRING: "PbAc"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.12.100.101.118.105.99.101.46.109.111.100.101.108 = STRING: "Smart-UPS X 750"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.12.117.112.115.46.102.105.114.109.119.97.114.101 = STRING: "COM 03.6 / UPS 03.6"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.12.117.112.115.46.109.102.114.46.100.97.116.101 = STRING: "2010/08/24"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.12.117.112.115.46.118.101.110.100.111.114.105.100 = STRING: "051d"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.13.100.101.118.105.99.101.46.115.101.114.105.97.108 = STRING: "AS1035120444"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.13.117.112.115.46.112.114.111.100.117.99.116.105.100 = STRING: "0003"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.14.98.97.116.116.101.114.121.46.99.104.97.114.103.101 = STRING: "100"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.14.100.114.105.118.101.114.46.118.101.114.115.105.111.110 = STRING: "2.7.2"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.15.98.97.116.116.101.114.121.46.114.117.110.116.105.109.101 = STRING: "45000"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.15.98.97.116.116.101.114.121.46.118.111.108.116.97.103.101 = STRING: "54.4"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.16.117.112.115.46.116.105.109.101.114.46.114.101.98.111.111.116 = STRING: "-1"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.17.117.112.115.46.98.101.101.112.101.114.46.115.116.97.116.117.115 = STRING: "enabled"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.18.98.97.116.116.101.114.121.46.99.104.97.114.103.101.46.108.111.119 = STRING: "10"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.18.117.112.115.46.100.101.108.97.121.46.115.104.117.116.100.111.119.110 = STRING: "20"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.18.117.112.115.46.116.105.109.101.114.46.115.104.117.116.100.111.119.110 = STRING: "-1"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.19.98.97.116.116.101.114.121.46.114.117.110.116.105.109.101.46.108.111.119 = STRING: "150"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.19.100.114.105.118.101.114.46.118.101.114.115.105.111.110.46.100.97.116.97 = STRING: "APC HID 0.95"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.20.100.114.105.118.101.114.46.102.108.97.103.46.112.111.108.108.111.110.108.121 = STRING: "enabled"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.21.100.114.105.118.101.114.46.112.97.114.97.109.101.116.101.114.46.112.111.114.116 = STRING: "auto"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.22.98.97.116.116.101.114.121.46.99.104.97.114.103.101.46.119.97.114.110.105.110.103 = STRING: "50"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.23.98.97.116.116.101.114.121.46.118.111.108.116.97.103.101.46.110.111.109.105.110.97.108 = STRING: "48.0"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.23.100.114.105.118.101.114.46.118.101.114.115.105.111.110.46.105.110.116.101.114.110.97.108 = STRING: "0.38"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.25.100.114.105.118.101.114.46.112.97.114.97.109.101.116.101.114.46.112.111.108.108.102.114.101.113 = STRING: "30"
.1.3.6.1.4.1.8072.1.3.2.3.1.2.29.100.114.105.118.101.114.46.112.97.114.97.109.101.116.101.114.46.112.111.108.108.105.110.116.101.114.118.97.108 = STRING: "2"
62 comments
98% Upvoted
This thread is archived
New comments cannot be posted and votes cannot be cast
Sort by
level 1
Comment deleted by user4 years ago
level 2

i don't get it

4
level 3
Your friendly neighborhood datacenter4 years ago
10
level 4

hahaha :)

4
level 4

hahaha :)

1
level 1
Original Poster4 years ago

I recently bought an APC Smart-Ups X 750i. It didn't have the smartslot nic and used ones cost more than the UPS (including new batteries) so I decided to try to use an RPi instead. This tutorial is a result of my efforts so far. I hope it is useful for someone else too.

24
level 2
Comment deleted by user4 years ago
level 3
Original Poster4 years ago

It does support multiple UPSs and a whole set of more advanced scenarios. From their web site:

  • upsmon can handle high-end servers which receive power from multiple UPSes simultaneously (with redundant PSUs).

  • upsmon won’t initiate a shutdown until the total power situation across all source UPSes becomes critical (on battery and low battery).

  • You can lose a UPS completely as long as you still have at least the minimum number of sources available. The minimum value is configurable.

More info is available here: http://networkupstools.org/features.html

5
level 1

Great write up. I just set up NUT on a Pi last week for the first time, to monitor the UPS in our "Server in a box" solution for our remote sites. Much cheaper than the add-in cards, and I can use the Pi for more too.

3
level 2
Original Poster4 years ago

Thanks. I'm still thinking about what else to use it for in the Lab now that I have it.

1
level 3
Comment deleted by user4 years ago
level 4
Original Poster4 years ago

Syslog is something I have been thinking about. It would be nice to have that on a separate device for post-mortems in case something goes terribly wrong. I am however concerned about the wear of the SD card with that kind of I/O load.

A notification service backed by a Cellular USB modem and Pushover or similar would be cool. It could provide a method to send messages during power outages.

1
level 1

Nice tutorial!

Suggestion: Publish it on the homelab wiki.

3
level 2
Original Poster4 years ago

Already done.

4
level 1

Saving for a weekend project. Thank you for the writeup!

2
level 1
[deleted]
4 years ago

Thanks a lot :)

Now I have a nice project for my RasPi ;)

2
level 1
Where does all my lab time go?4 years ago

Really great tutorial, I'm putting this on my to do list. Do you install the client on VM hosts and guests or just on the hosts?

2
level 2
Original Poster4 years ago

Only on the VM host (Proxmox in my case) and it takes down the VMs automatically. I haven't tried this on esxi yet but expect it to be similar.

1
level 3

actually on ESXi it's a hassle as there is no official and recent nut package.

3
level 4
Original Poster4 years ago · edited 4 years ago

Thanks for the update. I will have to fire up the ESXI box and play with it a bit to see how it works. I've found this (translated from french) and it seems compatible with ESXI 5.0, 5.1, 5.5, 6.0, and 6.5. I may give it a shot tomorrow and add it to the tutorial if successful.

EDIT: There's now a section on how to configure ESXi in the tutorial.

2
level 4
Where does all my lab time go?4 years ago

Good to know. I've got one box running Hyper-V and I'm trying to decide between Proxmox and ESXi as the hypervisor for the other so this is helpful.

1
level 5

ESXi hast good support for apcupsd as for as I know. In case you have a APC UPS (I don't), you might want to have a look at that.

2
level 4
Original Poster4 years ago

I updated the tutorial with a section on ESXi. It's not that hard imo.

1
level 5

No it's not that hard but i'd rather not install a unsupported precompiled binary from an unknown source on the central of my infrastructure.

1
level 1

How do you connect it to Windows servers so that it can initiate shut downs on those?

2
level 2
Original Poster4 years ago

There is a binary for windows available here: http://networkupstools.org/download.html I haven't tried it myself yet.

1
level 1
4 years ago · edited 4 years ago

Well written. Mostly not new for me but it's surely helpful for some homelabbers. It is not the worst idea to have the NUT server on a dedicated piece of hardware so it can safely shutdown everything else beforehand. I'm doing that by having a delayed shutdown command for the VM host hosting NUT. Edit: One more remark, netdata has NUT support OOTB. Not need to fiddle with grafana.

3
level 1

What are the benefits of setting up a client server architecture like this, over just issuing shutdown commands to all the PCs in the shutdown script of the Pi?

Then you don't need any software on the clients, and you may not even need software on the server (if Linux power management allows shutdown at a certain battery %).

Surely I'm missing something right?

3
level 2

Yeah and no. I mean yes; you can absolutely do it your way and it can be quite successful, but NUT is pretty nice because it is really an open and extensible framework. It provides a lot of insight that your script doesn't... for example I can read voltages and so forth from any client and not just from the host to which the UPS is connected. Plus, there are clients available for Windows... having an SSH script shut down Windows is an exercise in pain in my experience so having the NUT client on a Windows server is really helpful.

Plus there's the fact that NUT provides plenty of "recipes" of different configurations you can set up. And as a VERY low power device, a Pi can actually stay running on most UPS's for a very long time thus opening up even more options.

For example, if you use NUT to shut down all of your hosts when the power fails or when your battery reaches say 50%, if your switch and Pi are both on the UPS you might be able to keep them running a long time... hours potentially. I know my UPS can keep my Pi and switch going for about 6 hours with no other loads. That means if the power comes back on then you can use WOL to wake up all your servers again once the battery is charged to say more than 40%. That's how mine is set up. With all my hardware powered on, the UPS will maybe run for an hour, so about half an hour to my shutdown point. That's enough to deal with most minor outages. Major outages of more than an hour it's nice to know that my Pi is still sitting there humming away and waiting for the power to come back... and if the UPS hits 5% then the Pi shuts itself down too. In my case though I actually have mine set so it shuts down all the services and remounts root in Read-Only, leaving only NUT running in memory. If the Pi then gets turned off due to power loss it'll come back as soon as power does and then send WOL packets as required.

The shutdown script is perfect but is exactly what it purports to be; a quick hack to perform one specific task. If you want to do more with your configuration then it requires thinking outside the box a bit. NUT gives you more flexibility... and while yeah I could definitely do all of this with scripts via SSH (I have no Windows servers either, but every now and again I'll spin one up for various reasons) but I'd still need software somewhere monitoring the UPS in order to do it properly... and given that why not use NUT?

4
level 3

Well I mean I wrote a powershell script that shuts down a list of clients, actually waits for them to shutdown, and then emails me the results.

So if the pc was already shutdown when the script ran, if the PC timed out (locked up or installing updates), or it shut down successfully.

Just making sure I wasn't missing some amazing feature or something that I hadn't thought about.

I run windows machines with AD so shutting down via the shut down command is easy since domain creds always work.

1
level 4

Oh yeah; if you're already pretty much embedded into the Windows ecosystem then it might not make a HUGE amount of sense to do something like this... but then again it might. Again, the NUT server on a Pi can be connected to any number of clients running on the Windows/Linux/Mac clients/servers. They can all be configured for shutdown at different times depending on load, and as I said if you want to get REALLY fancy you can start playing with Wake-On-LAN and stuff.

EDIT: And yes, if you want you can monitor load and dynamically shut down hosts if the load tops a certain percentage. It's very flexible... REALLY handy in a cluster.

For my part, the other part I like is that because my firewall is also a fully-fledged PC (a Zotac-CI323 running PFSense), it's nice to also have the NUT client running on that and connected to the Pi, so it also can be cleanly shut down and woken up same as any server.

Really depends what you want to do. If you run a pretty flat environment with only one or two platforms then yeah... PowerShell is awesome and/or SSH is awesome. If you're running a pretty heterogeneous environment then NUT actually reduces your complexity quite a bit. There's even a good NUT client for VMware.

The requirements will vary a lot by need, but NUT is a good solution regardless I think. At least worth looking at.

Besides, gotta put those CPU cycles to work on my Pi :)

2
level 2

Doing it in a fedarated client server architecture is required if you run multiple UPSs powering redundant PSUs. This way the system can keep track of how many PSUs are powered.

3
level 2
Original Poster4 years ago

You can of course do what you describe but a client/server approach has some merits that are harder to implement using only remote shutdown commands. http://networkupstools.org/features.html has a few examples of benefits if you are interested.

1
level 1

Saved. Hope the driver works for my model. This would be a great addition when I repurpose my old PC as server.

1
level 2
Original Poster4 years ago

There is a compatibility chart here: http://networkupstools.org/stable-hcl.html Good luck with your new server!

1
level 1

vi is on raspbian, I don't think you need to install vim

1
level 2

vim is different than the vi that comes with debian, it includes features such as syntax highlighting, and ability to use arrow keys in insert mode.

2
level 2
Original Poster4 years ago

Cool. I guess I'm too used to type "vim" to notice :)

1
level 1

Ive tried to set this up in the past using this: http://abakalidis.blogspot.com/2013/04/using-raspberry-pi-as-ups-server-with.html but it was buggy Im gonna try this again from scratch using your tutorial Thank you.

1
level 1

Nice work. Now off to see if I can do this with a serial cable...

1
level 1
Comment deleted by user4 years ago
level 2
Original Poster4 years ago

I think /u/Sinister_Crayon sums it up quite well in his comment here. A low-power device that can stay on until everything else has been shut down safelly.

1
level 1
[deleted]
4 years ago · edited 4 years ago

If we deploy many of these in many data centers, and we wanted the status on a central server would we add that server's ip as a listener in /etc/nut/upsd.conf, then install apache on the server?

Actually, using snmp to our solarwinds server should do the trick?

1
level 2

the LISTEN directive opens a port at the NUT host, so you would add the local interface ip, not the remote server's ip.

You can add multiple remote NUT instances with a PSU value of 0 for strictly passive monitoring (without shutdown) in upsmon.conf and then connect to the local upsmon to e.g. visualize it.

2
level 1

Bookmarking 😁

1
level 1

As said in comments, details for ESXi (and Hyper-V) would be the only thing missing in this tutorial.

1
level 2
Original Poster4 years ago · edited 4 years ago

I added a section on ESXi to the tutorial. I don't have any Windows servers (so no Hyper-V) in my lab so I hope someone else can take on that part.

1
level 3

Thank you for adding the section.

1
level 1
4 years ago · edited 4 years ago

I installed & it works fine. the only problem i have is that it doesnt autostart on boot. i have to do this manually.

my ps -ef | grep ups output is

root       667     1  0 23:01 ?        00:00:00 /lib/nut/upsmon
nut        668   667  0 23:01 ?        00:00:00 /lib/nut/upsmon
nut       1260     1  0 23:03 ?        00:00:00 /lib/nut/usbhid-ups -a ups
nut       1263     1  0 23:03 ?        00:00:00 /lib/nut/upsd
root      1285  1233  0 23:04 pts/0    00:00:00 grep ups`
1
level 2
Original Poster4 years ago

Check your syslog (less /var/log/syslog | grep ups) to see if there are any problems related to nut during startup. This could for example be a timing issue where nut is started too early. Have you for example assigned a static IP to the RPi or is it waiting for a dhcp lease?

1
level 3
4 years ago · edited 4 years ago

it has a static ip.

syslog (less /var/log/syslog | grep ups) returns empty

how do i delay the start of nut?

here's my /etc/rc.d

lrwxrwxrwx   1 root root   18 Sep 22 22:23 S01bootlogs -> ../init.d/bootlogs
lrwxrwxrwx   1 root root   16 Sep 22 22:39 S01dhcpcd -> ../init.d/dhcpcd
lrwxrwxrwx   1 root root   14 Sep 22 22:23 S01motd -> ../init.d/motd
lrwxrwxrwx   1 root root   17 Sep 22 22:24 S01rsyslog -> ../init.d/rsyslog
lrwxrwxrwx   1 root root   22 Sep 22 22:27 S01triggerhappy -> ../init.d/triggerhappy
lrwxrwxrwx   1 root root   17 Feb 12 22:03 S02apache2 -> ../init.d/apache2
lrwxrwxrwx   1 root root   14 Feb 12 22:03 S03cron -> ../init.d/cron
lrwxrwxrwx   1 root root   14 Feb 12 22:03 S03dbus -> ../init.d/dbus
lrwxrwxrwx   1 root root   24 Feb 12 22:03 S03dphys-swapfile -> ../init.d/dphys-swapfile
lrwxrwxrwx   1 root root   13 Feb 12 22:03 S03ntp -> ../init.d/ntp
lrwxrwxrwx   1 root root   20 Feb 12 22:42 S03nut-server -> ../init.d/nut-server
lrwxrwxrwx   1 root root   15 Feb 12 22:03 S03rsync -> ../init.d/rsync
lrwxrwxrwx   1 root root   13 Feb 12 22:03 S03ssh -> ../init.d/ssh
lrwxrwxrwx   1 root root   32 Feb 12 22:03 S03vncserver-x11-serviced -> ../init.d/vncserver-x11-serviced
lrwxrwxrwx   1 root root   22 Feb 12 22:01 S04avahi-daemon -> ../init.d/avahi-daemon
lrwxrwxrwx   1 root root   19 Feb 12 22:01 S04bluetooth -> ../init.d/bluetooth
lrwxrwxrwx   1 root root   17 Feb 12 22:01 S04lightdm -> ../init.d/lightdm
lrwxrwxrwx   1 root root   20 Feb 12 22:42 S04nut-client -> ../init.d/nut-client
lrwxrwxrwx   1 root root   18 Feb 12 22:01 S05plymouth -> ../init.d/plymouth
lrwxrwxrwx   1 root root   18 Feb 12 22:01 S05rc.local -> ../init.d/rc.local
lrwxrwxrwx   1 root root   19 Feb 12 22:01 S05rmnologin -> ../init.d/rmnologin
1
level 1
I've seen the light/quiet of tower servers.4 years ago

I just got the Web monitoring section and noticed it only shows Status, Battery, and Runtime. I am using the USB port on the back of my UPS which is a Dell branded APC Smart-UPS 3000 (Model# DLT3000MR2U). Will switching over to the serial port allow it to see the Input, Output, and Load?

1
level 2
Original Poster4 years ago

Hi. That is the same info i get over USB. I have read some reports about more info being available over serial, but I haven't tried that myself. Please report back here if you get that to work.

1
level 3
I've seen the light/quiet of tower servers.4 years ago

I will try it out tonight. Do you mind going into more depth on securing the CGI Directory? I am completely lost when I look at the upsset.conf

1
level 1

Id like to continue with the tutorial but sadly Im stuck when it comes to the service coming up automatically.

I have to manually stop and start it.

Any tips?

1
level 2
Original Poster4 years ago

That's Interesting. It comes right up after a boot on my system. What does your syslog have to say?

1
level 3

Do you mind lending a hand telling me the command you want me to run to give syslog output?

(Besides cat ; I mean cat on what file)

1
level 4
Original Poster4 years ago

take a look at your /var/log/syslog right after a reboot and see if you can find any clues. Pay attention to the entries regarding the upsd and upsmon services.

1
level 5
4 years ago · edited 4 years ago

Wow, a lot of errors:

http://pastebin.com/71VuEPfA

1
level 6

OK, rechecked everything and everything seems to be in order.

Im using a Cyberpower instead of a APC but like I said; If I manually stop and then start the service, it works fine.

It seems that it might be a permissions issue; What permissions are set on your files?

1
level 7
Original Poster4 years ago · edited 4 years ago

It can be a timing issue with the driver and the USB interface but I'm not sure about that. I can check the permissions and take a look at your log in the morning (it is getting pretty late here). Did you install as root or some other user?

Edit: I think this is your problem: no listening interface available. The network doesn't seem to be available when upsd tries to start.

Edit2: Another user with a similar problem: https://www.raspberrypi.org/forums/viewtopic.php?t=129623&p=866076

1
level 8
4 years ago · edited 4 years ago

Did you install as root or some other user?

Sudo'd all the commands.

Edit: I think this is your problem: no listening interface available. The network doesn't seem to be available when upsd tries to start.

I believe I have both a static IP set AND in the DHCP server I have it statically assigned.

1
level 8

VPNd into my session and got the output of the file:

myuser@nutserver:~ $ cat /etc/dhcpcd.conf
# A sample configuration for dhcpcd.
# See dhcpcd.conf(5) for details.

# Allow users of this group to interact with dhcpcd via the control socket.
#controlgroup wheel

# Inform the DHCP server of our hostname for DDNS.
hostname

# Use the hardware address of the interface for the Client ID.
clientid
# or
# Use the same DUID + IAID as set in DHCPv6 for DHCPv4 ClientID as per RFC4361.
#duid

# Persist interface configuration when dhcpcd exits.
persistent

# Rapid commit support.
# Safe to enable by default because it requires the equivalent option set
# on the server to actually work.
option rapid_commit

# A list of options to request from the DHCP server.
option domain_name_servers, domain_name, domain_search, host_name
option classless_static_routes
# Most distributions have NTP support.
option ntp_servers
# Respect the network MTU.
# Some interface drivers reset when changing the MTU so disabled by default.
#option interface_mtu

# A ServerID is required by RFC2131.
require dhcp_server_identifier

# Generate Stable Private IPv6 Addresses instead of hardware based ones
slaac private

# A hook script is provided to lookup the hostname if not set by the DHCP
# server, but it should not be run by default.
nohook lookup-hostname

interface eth0

static ip_address=192.168.1.160/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1
myuser@nutserver:~ $ 

Everything seems fine. I installed the PIXEL version; Any way I can set it up in the GUI just in case?

1
level 9
Original Poster4 years ago

That seems fine but I have no experience with the Pixel version at all. It is possible that it does boot order completely different compared to standard Raspbian.

1
level 10

It would seem that the GUI is the last thing it boots, wouldnt it?

1
level 1

Wow this is a great writeup. Thanks a lot

1

About Community

Welcome to your friendly /r/homelab, where techies and sysadmin from everywhere are welcome to share their labs, projects, builds, etc.
410k

Members

1.7k

Online


Created 19 Jun 2012

r/homelab Rules

1.
Don't be an asshole.
2.
Post Details.
3.
No Memes
4.
Not Homelab Related
5.
Shitpost/Low Effort
6.
No piracy
7.
No Referral Links/Advertising
8.
Sales & Offers

Related Subreddits

r/sysadmin

581,316 members

r/networking

234,443 members

r/PowerShell

170,821 members

r/linux

644,598 members

r/linuxadmin

173,712 members

r/PFSENSE

76,301 members

r/hardwareswap

284,458 members

r/buildapcsales

801,567 members

r/HomeNetworking

182,790 members

r/homeautomation

1,123,982 members