What's up, home? part 113 cover image

Can you monitor the signal strength of your different Wi-Fi devices that are connected to your (home) router with Zabbix? Of course you can! This is a really quick morning post before I hop on to my work duties, showing also how ChatGPT or any LLM can boost your productivity when doing this kind of things.

I have an ASUS RT-AX68U router running on Asuswrt-Merlin firmware. On its web interface, it can show you all kinds of details of your network and the devices, which is nice, but of course even more nice would be to add some of that to Zabbix. One interesting bit for me would be to monitor the signal strength of my Wi-FI devices around the house, so let's do that and start monitoring RSSI!

What's RSSI?

Here's a reply by ChatGPT:

In Wi-Fi (and RF in general), RSSI (Received Signal Strength Indicator) is typically measured in negative dBm values:

The closer the value is to 0 dBm, the stronger (better) the signal.

The more negative the value, the weaker the signal.

Broadly speaking, here is a rough guideline:

-30 dBm: Extremely strong signal (almost too strong – rare in normal conditions).

-50 dBm: Excellent signal.

-60 dBm: Very good signal, plenty strong for most uses.

-70 dBm: Adequate; connectivity is usually reliable but might slow at times.

-80 dBm: Marginal; still connected but performance may degrade.

-90 dBm or lower: Very weak; likely to drop connection or have very poor speeds.

Monitoring implementation

If you are a regular reader, by now you should know that I'm not a fan of letting Zabbix agent or any other agent to run commands directly for gathering the metrics unless I really need the metrics for that second. Rather, I'll let cron jobs or any other background way to create text files which then will be parsed by Zabbix.

That said, my ASUS now runs a shell script every minute, which then writes a text file /tmp/rssi.txt, which is read by Zabbix agent. 

The shell script

Thank you ChatGPT for the following: The script uses wl -i assoclist command to list the connected devices with their MAC addresses and signal strength, and converts those MAC addresses to hostnames to be human-readable.

#!/bin/sh

# Interfaces for 2.4 and 5 GHz (adjust if your router uses different names)
IFACES="eth5 eth6"

LEASES_FILE="/var/lib/misc/dnsmasq.leases"
rm -f /tmp/rssi.txt

echo "Hostname:RSSI" >/tmp/rssi.txt
for iface in $IFACES
do
 # List all MACs associated on this interface
 for MAC in $(wl -i "$iface" assoclist 2>/dev/null | awk '{print $2}')
 do
   # Get RSSI
   RSSI=$(wl -i "$iface" rssi "$MAC" 2>/dev/null)

   # Look up IP and hostname in dnsmasq leases (if present)
   # The leases file format is: <epoch> <MAC> <IP> <hostname> <clientid>
   IP=$(grep -i "$MAC" "$LEASES_FILE" | awk '{print $3}')
   HOSTNAME=$(grep -i "$MAC" "$LEASES_FILE" | awk '{print $4}')

   # If the device is static or not found in dnsmasq leases, IP/HOSTNAME might be empty
   # so handle that gracefully
   [ -z "$IP" ] && IP="Unknown"
   [ -z "$HOSTNAME" ] && HOSTNAME="Unknown"

   #echo "MAC $MAC:"
   #echo "  RSSI:      $RSSI dBm"
   #echo "  IP:        $IP"
   #echo "  Hostname:  $HOSTNAME"
   echo "$HOSTNAME:$RSSI" >>/tmp/rssi.txt
 done
done

It outputs this, with self-explanatory results. 

Hostname:RSSI
Watch:-43
058743599:-66
Samsung:-62
SonosZP:-45
BroadLink_OEM-T1-89-d3-bb:-57
Kitchen:-52
Mac:-39
iPhone:-40
*:-60
MacBookPro:-43

Adding it to Zabbix

First, I added a new template, for which I then added a new master item reading the /tmp/rssi.txt file.

Master item

As ChatGPT script did make the output in CSV format with : as delimiter, we can use Zabbix item preprocessing to convert that CSV to JSON.  The JSON output looks like this.

[{"Hostname":"Watch","RSSI":"-45"},{"Hostname":"058743599","RSSI":"-70"},{"Hostname":"Samsung","RSSI":"-60"},{"Hostname":"SonosZP","RSSI":"-44"},{"Hostname":"BroadLink_OEM-T1-89-d3-bb","RSSI":"-61"},{"Hostname":"Kitchen","RSSI":"-53"},{"Hostname":"Mac","RSSI":"-37"},{"Hostname":"iPhone","RSSI":"-39"},{"Hostname":"*","RSSI":"-56"},{"Hostname":"MacBookPro","RSSI":"-41"}]

With this, we can then use Zabbix low-level discovery to automatically create the items.

CSV to JSON preprocessing

Discovery rule

Now that we have our master item, let's add the discovery rule which can go through the JSON. The discovery rule uses my previous item as a dependent item, from which it can parse everything in one go.

DiscoveryDiscovery preprocessing

 

Discovery LLD macros

Discovery item prototype

In item prototype, let's make it again use the raw list as a dependent item, and go from there.

Item prototype

Then in preprocessing, it picks the RSSI value for the whatever device LLD was going through by using a JSONPath query.

 

or as text: 

$[?(@.Hostname=='{#WIFICLIENT}')].RSSI.first()

That's pretty much it! 

We now have the data coming in once per minute: 

Latest data

Here's a little dashboard, too. It shows you the traditional bar that's available on Top hosts/items widget, and also the new Sparkline that's on Zabbix 7.2.

Dashboard

Bonus: Location estimation

After a little bit walking around and observing the devices, I added some value mapping to make Zabbix to estimate where the devices would be located. Not useful for static objects but when I move around with my Apple Watch and iPhone, here's an attempt to monitor my location at home, too.

Location estimationLikely location

... after this fine-tuning, my dashboard now looks like this.




Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
Submitted by whatsuphome on