I like the concept of measuring flows and so have sensors on my water main and my electric mains. Naturally, I wanted to add a reading of how much bandwidth I’m using and get it displayed in my living room. I already have the following in place:
- My LED matrix infopanel
- A router running OpenWRT
- A local MQTT server (with bridge to a remote one, but that’s irrelevant for this post)
As it turns out, this is enough to get live internet usage numbers showing with just a few simple scripts.
First we need to just get the speed from the router. Bmon is a great choice for this. Before long I had figured out the command to show my WAN transmit and receive rates on stdout.
|
1 2 3 4 5 |
root@thewrt:~# bmon -p eth1 -r 5.0 -o format:fmt='$(element:name)\t$(attr:rxrate:bytes)\t$(attr:txrate:bytes)\n' eth1 0.00 0.00 eth1 265898.28 19053.59 eth1 67773.42 9319.65 eth1 18138.26 3054.41</span> |
This refreshes every 5 seconds. Then I just wanted to send that to the MQTT server so I wrote this bash script:
|
1 2 3 4 5 6 |
#!/bin/bash down=$(echo "scale=2; $2/1000" | bc) up=$(echo "scale=2; $3/1000" | bc) /usr/bin/mosquitto_pub -h host.int -u muser -P password -t home/matrix/$1down -m "$down" /usr/bin/mosquitto_pub -h host.int -u muser -P password -t home/matrix/$1up -m "$up" |
The script takes 3 arguments: interface, download speed, tx speed. It converts from bytes/s to kB/s using the bc (note that bash can only do integer division) and then sends the tx and rx speeds to the mqtt server at host.int.
To get this all to work on my router I did have to opkg install a few tools, like bmon, bc, bash, an upgraded xargs, and mosquitto_clients.
Then to tie it all together I wrote another script based on the upper command. It uses xargs on every newline to pass the three columns above as three arguments into this MQTT submission script. Pretty easy:
|
1 2 3 |
#!/bin/ash /usr/sbin/bmon -p eth1,wlan1 -r 5.0 -o format:fmt='$(element:name)\t$(attr:rxrate:bytes)\t$(attr:txrate:bytes)\n' | xargs -L1 /usr/bin/submit-bitrate-to-mqtt.sh |
So that will just run forever, updating the local MQTT service with the latest speeds every 5 seconds. Then I just made it a service by making a file in /etc/init.d.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#!/bin/sh /etc/rc.common START=50 USE_PROCD=1 PROG=/usr/bin/hass-bitrates.sh PIDFILE=/var/run/hass-bitrates.pid start_service() { procd_open_instance hass-bitrates procd_set_param command $PROG procd_set_param pidfile $PIDFILE procd_close_instance } all_child_pids() { pid=$1 echo $pid for child_pid in $(pgrep -P $pid); do echo "$(all_child_pids $child_pid)"; done } stop_service() { for pid in $(all_child_pids $(cat $PIDFILE)); do kill $pid done } reload_service() { stop start } |
And then in the infopanel I just set up a few new simple sprites and scene for all the flows.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
upload: type: Temperature label: TX low_val: 0.0 high_val: 2000 val_fmt: " {:.1f}" data_label: eth1up download: type: Temperature label: RX low_val: 0.0 high_val: 2000 val_fmt: " {:.1f}" data_label: eth1down |
And that’s it! Very nice.