Monitoring UPS status with NUT(Network UPS Tools) on OpenWrt

I have a UPS (APC BK650) to supply power for my OpenWrt router, Network switch and Wireless AP. Since the UPS has no indicator screen, i can’t check its running status(Load, Battery runtime), that’s a little unacceptable for me.

Then i spent some time googling and deployed NUT (Network UPS Tools) on the OpenWrt router, which provides a simple web page showing status of connected UPS.

Web interface of nut web cgi

Here is my installation and configuration process:

1. Install NUT and dependences

opkg install nut nut-common nut-driver-usbhid-ups nut-server nut-upsc nut-web-cgi usbutils
  • nut nut-common nut-server basic packages
  • nut-driver-usbhid-ups nut driver compatible with APC BK650
  • nut-upsc provides upsc command
  • nut-web-cgi provides a web status page
  • usbutils provides lsusb command

2. Configure NUT server, edit /etc/config/nut_server

config driver 'apc'
# APC BK650 is compatible with the usbhid driver
  option driver usbhid-ups
# auto detect USB port
  option port auto

config listen_address
   option ::1

config upsd upsd

Reload nut server

/etc/init.d/nut-server reload

3. Configure the status web page, edit /etc/config/nut_cgi (Skip this step If you just want to check UPS status by upsc command)

# Local UPS configured at /etc/config/nut_server
config host
	option upsname apc
	option hostname localhost
	option displayname "Router"

# This is my another UPS connected with Synology NAS
# You can just ignore this section
config host
	option upsname ups
	option hostname
	option displayname "Synology"

config upsset
	option enable 0

Reload nut cgi

/etc/init.d/nut-cgi reload

5. Connect UPS and OpenWrt router with a USB cable

6. Check if the UPS has been detected

root@OpenWrt:~# lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 051d:0002 American Power Conversion Uninterruptible Power Supply
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
root@OpenWrt:~# ps ax|grep usbhid
 2753 pts/1    S+     0:00 grep usbhid
 2865 ?        Sl   111:50 /lib/nut/usbhid-ups -D -a apc -u nut

The UPS device should appear in output of lsusb, and usbhid-ups process will also start automatically.

7. If everything goes well, you can get UPS status by command upsc, or visit status web page at http://your router ip/nut/ (if nut-cgi installed),

root@OpenWrt:~# upsc apc
battery.charge: 100
battery.charge.low: 10
battery.charge.warning: 50 not set 2018/10/05
battery.runtime: 2197
battery.runtime.low: 120
battery.type: PbAc
battery.voltage: 13.6
battery.voltage.nominal: 12.0
device.mfr: APC
device.model: Back-UPS 650
device.serial: 3B1840X68970
device.type: ups usbhid-ups
driver.parameter.pollfreq: 30
driver.parameter.pollinterval: 2
driver.parameter.port: auto
driver.parameter.synchronous: no
driver.version: 19.07.5-14-ge290024717 APC HID 0.96
driver.version.internal: 0.41
input.sensitivity: low
input.transfer.high: 266
input.transfer.low: 165
input.transfer.reason: input voltage out of range
input.voltage: 232.0
input.voltage.nominal: 220
ups.beeper.status: enabled
ups.delay.shutdown: 20
ups.firmware: 822.A3.I
ups.firmware.aux: A3
ups.load: 16
ups.mfr: APC 2018/10/05
ups.model: Back-UPS 650
ups.productid: 0002
ups.serial: 3B1840X68970
ups.status: OL
ups.timer.reboot: 0
ups.timer.shutdown: -1
ups.vendorid: 051d

Free Microsoft 365 E5 subscription for developers

Our company purchased two Microsoft Office 365 subscriptions, which are mainly used for the development and testing of our enterprise product. Until today I found that Microsoft provides free E5 subscriptions(25 accounts) for developer accounts… anyone can setup the subscription at

Two points about the developer subscription:

  1. If we’re using the subscription for development, it will be renewed every 3 months and will last indefinitely.
  2. Windows and Audio Conferencing are not included in developer E5 subscription.

How to limit ingress bandwith with tc command in Linux

tc (Traffic Control) is a builtin command in linux, can be used to configure traffic control rules in linux kernel. is a bash script that I use to simulate a low-speed network during software testing. it sets ingress bandwith limit with the tc command.

# Modify speed variable according to your needs
# Find the default network device in route table
DEVICE=$(route | grep '^default' | grep -o '[^ ]*$')

# Linux does not support shaping on ingress
# but we can redirect ingress taffic to ifb device, then do
# taffic shaping on egress queue of ifb device.

if test -z "$(lsmod | grep ifb)"; then
    modprobe ifb

if test -z "$(ip link | grep ifb0)"; then
    ip link add name ifb0 type ifb
    ip link set dev ifb0 up

tc qdisc add dev ifb0 root handle 1: htb r2q 1
tc class add dev ifb0 parent 1: classid 1:1 htb rate $SPEED
tc filter add dev ifb0 parent 1: matchall flowid 1:1

tc qdisc add dev $DEVICE ingress
tc filter add dev $DEVICE ingress matchall action mirred egress redirect dev ifb0 is used to clean bandwith limit rules

DEVICE=$(route | grep '^default' | grep -o '[^ ]*$')
tc qdisc del dev $DEVICE ingress
tc qdisc del dev ifb0 root

Test results on CentOS 7.8

# wget
--2021-09-24 10:44:43--
Resolving ( 2600:3c01::f03c:91ff:feae:68d,
Connecting to (|2600:3c01::f03c:91ff:feae:68d|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: ‘100MB-fremont.bin’

30% [=========================>                                                               ] 31,633,828  15.0MB/s             ^C
# wget
--2021-09-24 10:45:12--
Resolving ( 2600:3c01::f03c:91ff:feae:68d,
Connecting to (|2600:3c01::f03c:91ff:feae:68d|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: ‘100MB-fremont.bin’

 0% [                                                                                         ] 171,104     27.4KB/s  eta 60m 25s^C

Fix Linksys Velop with Cisco SG 200-08

My network topology: router > managed switch(Cisco SG 200-08) > Linksys Velop WHW0301 x 4 (bridge mode).

I configured all 4 velop nodes through the mobile app, turn on bridge mode. then only the parent velop node is working, all other 3 child nodes can’t be connected. After google search, i found that Linksys Velop require vlan with id 3 and 4 configured in managed switch as mentioned in this article.

Here is the vlan configuration process of Cisco SG 200-08:

1. open VLAN Management > Create VLAN, create two vlan with id 3 and 4.

2. open VLAN Management > Port To VLAN, make sure the ports velop connected are members of vlan 3 and 4, tagged should also be checked.

My homelab 2021

Devices inside shoebox

1. UPS APC BK650

2. Optical modem

3. OpenWrt router

Specs of the router: Intel N4200 1.1GHz 4 core, 4GB RAM, Intel i211 x 4, 120G SSD Disk

Firmware: OpenWrt 19.07 X86 built with glibc (enable openwrt to run common linux binary)

4. LINKSYS VELOP WHW0301 (running in birdge mode)

5. Cisco SG200-08 8-Port Managed Switch

Devices near my desk
Devices near my desk

1. LINKSYS VELOP WHW0301 (running in birdge mode)

2. AirPort Time Capsule (will be replaced by new NAS)

3. USB 3.1 HDD CASE (will be replaced by new NAS)

4. Synology 218 play (Consider upgrading to Synology 4-6 bays model)

5. Cisco SG90D-08 8-Port Gigabit Desktop Switch (I like the blinking LEDs)

6. Raspberry pi 3b (running Zerotier client)

7. UPS APC BK650M2

How to resize image with ImageMagick with a max width/height

Resize image with max width and height

set max width:600 max height 400

convert image.jpg -resize 600x400\> image.jpg

Resize image with max width and keep aspect ratio

set max width 1024

convert image.jpg -resize 1024\> image.jpg

Resize image with max height and keep aspect ratio

set max height 800

convert image.jpg -resize x800\> image.jpg

Basic iptables rules for linux web server

# Reset rules
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -A INPUT -s -d -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -j ACCEPT
# Allow ssh remote login
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Allow https
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow http
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# Allow ping
iptables -A INPUT -p icmp -j ACCEPT
iptables -A INPUT -j REJECT
iptables -A FORWARD -j REJECT

Add User to Group in Linux

Add an Existing User to a Group

sudo usermod -a -G newgroupname username

Add an Existing User to Multiple Groups in One Command

sudo usermod -a -G newgroup1,newgroup2 username

Remove a User From a Group

sudo gpasswd -d username groupname

Create a Group

sudo groupadd groupname

Delete a Group

sudo groupdel groupname

Display User Groups

id username