ativerc

Homelab Something.Zero

Got downgraded to a Pi Zero 2w after my RPi 2 became very unreliable with its power circuitry. Over the last few days I set up an nginx server, ntfy.sh, mqtt, and a couple of OpenWRT scripts on my router in order to have basic network monitoring. I was brave/overconfident and actually installed Docker on my Pi Zero 2w and thought I would try something on it via ntfy.sh, a few TG Bots, and Apprise. But, n.o.p.e. Just running a single container (Apprise) rendered the RPi unusable and I had to reflash the RPi.

Setup

Given the Pi Zero 2w, is an extremely low-specced device, I had to be careful about what I could install on it. For starters, I wanted the following:

Network Monitoring

I have 2 internet connections at home which are fed into my main router with the second one acting as a failover, I could load balance between them but the second ISP has a weird inclination of messing around with my DNS, or blocking github.com's subdomains for no reason at all. So, I am not overly fond of using them.

For now, I am just monitoring the status of these Internet connections.

Since my RPi would need to somehow discern between ISP1 and ISP2, I figured it would be easier for router (with OpenWRT) to monitor my WAN connections and respond accordingly.

With OpenWRT installed on my router, all I had to do was look for a way the router to respond to events. And I found it. OpenWRT's Hotplug directory. TL;DR: Place some scripts in the router's /etc/hotplug.d directory and they will respond when certain events occur.

The script is event-triggered that way and also schedule-triggered every minute via cron.

Currently the script looks like this:

1#!/bin/ash
2
3TARGET=8.8.8.8 # Google DNS
4MQTT_SERVER= # pizero's network address
5TIMESTAMP=$(date)
6
7MAIN_ISP=ISP1
8MAIN_ISP_INTERFACE=pppoe-wan
9MAIN_ISP_TOPIC="$MAIN_ISP"WanStatus
10MISP_WEIGHT=0
11
12SECOND_ISP=ISP2
13SECOND_ISP_INTERFACE=lan1
14SECOND_ISP_TOPIC="$SECOND_ISP"WanStatus
15SISP_WEIGHT=1
16
17test_isp() {
18 ISP=$1
19 INTERFACE=$2
20 TOPIC=$3
21 WEIGHT=$4
22
23 MESSAGE="{\"timestamp\":\"$TIMESTAMP\", \"isp\":\"$ISP\", \"weight\": \"$WEIGHT\", \"value\": \"1\", \"message\": \"$ISP-OK\"}"
24
25 ping -I $INTERFACE -W1 -c1 $TARGET
26
27 if [ $? -eq 1 ]; then
28 MESSAGE="{\"timestamp\":\"$TIMESTAMP\",\"isp\":\"$ISP\", \"weight\": \"$WEIGHT\", \"value\": \"0\", \"message\": \"$ISP-FAIL\"}"
29 mosquitto_pub -h $MQTT_SERVER -t $TOPIC -m "$MESSAGE" -r
30 else
31 echo $MQTT_SERVER $TOPIC $MESSAGE
32 mosquitto_pub -h $MQTT_SERVER -t $TOPIC -m "$MESSAGE" -r
33 fi
34}
35
36test_isp $MAIN_ISP $MAIN_ISP_INTERFACE $MAIN_ISP_TOPIC $MISP_WEIGHT
37test_isp $SECOND_ISP $SECOND_ISP_INTERFACE $SECOND_ISP_TOPIC $SISP_WEIGHT

All the script does is ping googleDNS once and then sends a "status" message via MQTT which is consumed by other MQTT clients on the network.

While the ISP1 internet connects via PPPoE which is initiated by my router, due to which if the PPPoE connection is lost -- because of powerloss of ONT device upstream or fiber cut upstream, the PPPoE connection goes down immediately and is handled perfectly by my script.

There are a few problems though:

Problem 1: ISP2 has provided me a Wifi AP/Router/Switch combo Customer Premises Equipment (CPE) device which feeds internet from its Ethernet port to the WAN port 2 of my main router. Unless there's a powerloss of this combo CPE device, this Ethernet connection will remain active, failing to trigger OpenWRT's hotplug.d event-trigger and, hence even if the there's an upstream connection loss, since my script pings only once a minute, there might be a minute of Internet Connection loss on my ISP2 connection before my script catches this. This can be mitigated though. I have a few ideas.

Problem 2: This script pings Google DNS to check status. IMHO, This is a wrong metric to look at since there are some rare times when GoogleDNS works but other sites don't. And I could implement something more involved like curl'ng a random site and checking its output. This is what Microsoft's Network Connection Status Indicator (NCSI) does.

NGINX setup

Followed this guide from NGINX docs here. Pretty self-explanatory. Except:

ntfy.sh

ntfy.sh works great once you have set it up. Else it has some problems:

Networking

The Pizero uses mDNS to announce its hostname over the network. This might create trouble if any of the devices don't support mDNS. One of the phones in my house didn't because of which I couldn't ping it over its hostname. And ntfy.sh messages would be received on the phone but the images from it wouldn't. That was because I had configured ntfy.sh to send host images from RPI's hostname as the base-url but had set its IP address as the ntfy.sh instance's listening endpoint.

So, what I did was add a hostname against RpI's IP address on the router. That fixed it. God, this stupid problem took almost a week away. I should have checked this faster. Also, custom notifications setup's UIUX on old Android phones are broken.

Powering the RPi

A bit about powering the RPi.

Don't run a RPi directly from a DC adapter connected to an unreliable Indian AC power source. Even one that's backed up by an inverter. The inverter won't switch fast enough (even with its UPS mode) to prevent power loss. Secondly, power banks won't work because almost all powerbanks sold in the Indian market will cut power to all currently-charging USB devices when AC power resumes or cuts off for a second or more while the circuitry renegotiates power output with the connected devices. Both of these options will eventually kill your RPi. Which happened with my old RPi.

You can choose to have a UPS with a Data/Serial/COM port from APC or CyberPower but most of their models are LOUD because of their fan which runs constantly. Very very loud. The kind of loud you won't want in any room. The kind of loud which will kill your sleep and kill your living room TV-watching experience. There was one UPS from APC - the BE700YIND which was fanless, small and had a COM port. APC doesn't sell that UPS anymore.

So, options? Well, those Router UPSs we get on the market these days, specifically a Cuzor Mini UPS PRO. This and a buck converter and you are in business. Granted you won't have the fancy features of a UPS with data port which will give you a custom functionality like soft shutdown on power loss, wake on power resumption, etc. and especially the Time-To-Shutdown. But, hey on the bight side, you don't have to turn off the RPi. Ever! Even when switching between AC power resumption, which you would have to incase of a powerbank.

Bye for now!

Edit 27-01-2025:

The code for my homelab is here. Lots of things have changed.