{"id":2093,"date":"2021-05-02T22:59:12","date_gmt":"2021-05-03T05:59:12","guid":{"rendered":"https:\/\/partofthething.com\/thoughts\/?p=2093"},"modified":"2023-05-13T21:59:30","modified_gmt":"2023-05-14T04:59:30","slug":"live-internet-bandwidth-monitor","status":"publish","type":"post","link":"https:\/\/partofthething.com\/thoughts\/live-internet-bandwidth-monitor\/","title":{"rendered":"Live internet bandwidth monitor for living room"},"content":{"rendered":"\n<p>I like the concept of measuring flows and so have sensors on my <a href=\"https:\/\/partofthething.com\/thoughts\/reading-a-tuf-2000m-ultrasonic-flow-meter-with-an-arduino-or-esp8266\/\" data-type=\"post\" data-id=\"1937\">water main<\/a> and my electric mains. Naturally, I wanted to add a reading of how much bandwidth I&#8217;m using and get it displayed in my living room. I already have the following in place:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>My <a href=\"https:\/\/partofthething.com\/thoughts\/the-infopanel-a-simple-mqtt-connected-display-system-for-weather-traffic-pictures-animations-anything\/\" data-type=\"post\" data-id=\"1169\">LED matrix infopanel<\/a><\/li>\n\n\n\n<li>A router running <a href=\"https:\/\/openwrt.org\/\">OpenWRT<\/a><\/li>\n\n\n\n<li>A local <a href=\"https:\/\/mosquitto.org\/\">MQTT server<\/a> (with bridge to a remote one, but that&#8217;s irrelevant for this post)<\/li>\n<\/ul>\n\n\n\n<p>As it turns out, this is enough to get live internet usage numbers showing with just a few simple scripts. <\/p>\n\n\n\n<!--more-->\n\n\n\n<p>First we need to just get the speed from the router. <a href=\"https:\/\/openwrt.org\/docs\/guide-user\/services\/network_monitoring\/bwmon\">Bmon is a great choice for this. <\/a> Before long I had figured out the command to show my WAN transmit and receive rates on stdout. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">root@thewrt:~# bmon -p eth1  -r 5.0 -o format:fmt='$(element:name)\\t$(attr:rxrate:bytes)\\t$(attr:txrate:bytes)\\n'\n eth1    0.00    0.00\n eth1    265898.28   19053.59\n eth1    67773.42    9319.65\n eth1    18138.26    3054.41<\/span><\/pre>\n\n\n\n<p>This refreshes every 5 seconds. Then I just wanted to send that to the MQTT server so I wrote this bash script:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/bash\n\ndown=$(echo \"scale=2; $2\/1000\" | bc)\nup=$(echo \"scale=2; $3\/1000\" | bc)\n\/usr\/bin\/mosquitto_pub -h host.int -u muser -P password -t home\/matrix\/$1down -m \"$down\" \n\/usr\/bin\/mosquitto_pub -h host.int -u muser -P password -t home\/matrix\/$1up -m \"$up\" <\/pre>\n\n\n\n<p>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 <code>host.int<\/code>. <\/p>\n\n\n\n<p>To get this all to work on my router I did have to <code>opkg install<\/code> a few tools, like <code>bmon<\/code>, <code>bc<\/code>, <code>bash<\/code>, an upgraded xargs, and <code>mosquitto_clients<\/code>. <\/p>\n\n\n\n<p>Then to tie it all together I wrote another script based on the upper command. It uses <code>xargs<\/code> on every newline to pass the three columns above as three arguments into this MQTT submission script. Pretty easy:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/ash\n\n\/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 \n <\/pre>\n\n\n\n<p>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 <code>\/etc\/init.d<\/code>. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">#!\/bin\/sh \/etc\/rc.common\n START=50\n USE_PROCD=1\n PROG=\/usr\/bin\/hass-bitrates.sh\n PIDFILE=\/var\/run\/hass-bitrates.pid\n start_service() {\n     procd_open_instance hass-bitrates\n     procd_set_param command $PROG\n     procd_set_param pidfile $PIDFILE\n     procd_close_instance\n }\n all_child_pids() {\n     pid=$1\n     echo $pid\n <code>for child_pid in $(pgrep -P $pid); do     echo \"$(all_child_pids $child_pid)\"; done<\/code>\n }\n stop_service() {\n     for pid in $(all_child_pids $(cat $PIDFILE)); do\n         kill $pid\n     done\n }\n reload_service()\n {\n         stop\n         start\n }\n          <\/pre>\n\n\n\n<p>And then in the infopanel I just set up a few new simple sprites and scene for all the flows. <\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">   upload:\n       type: Temperature\n       label: TX\n       low_val: 0.0 \n       high_val: 2000\n       val_fmt: \" {:.1f}\"\n       data_label: eth1up\n   download:\n       type: Temperature\n       label: RX\n       low_val: 0.0 \n       high_val: 2000\n       val_fmt: \" {:.1f}\"\n       data_label: eth1down<\/pre>\n\n\n\n<p>And that&#8217;s it! Very nice. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>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&#8217;m using and get it displayed in my living room. I already have the following in place: As it turns out, this is enough to &hellip; <a href=\"https:\/\/partofthething.com\/thoughts\/live-internet-bandwidth-monitor\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Live internet bandwidth monitor for living room<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":2099,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":""},"categories":[75],"tags":[],"class_list":["post-2093","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-home-automation"],"_links":{"self":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts\/2093","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/comments?post=2093"}],"version-history":[{"count":8,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts\/2093\/revisions"}],"predecessor-version":[{"id":2253,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/posts\/2093\/revisions\/2253"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/media\/2099"}],"wp:attachment":[{"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/media?parent=2093"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/categories?post=2093"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/partofthething.com\/thoughts\/wp-json\/wp\/v2\/tags?post=2093"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}