dd-wrt-munin

I have two WiFi access points in the house, a FritzBox 7412 and a TP-Link TL-WR740N v4 running the open source DD-WRT firmware.

I also use Munin for monitoring my home, and had the fritzbox-munin plugin installed to see the number of connected WiFi devices:

FritzBox connected wifi devices

There was no dd-wrt plugin available for munin, so I built one: The source code can be found at my git server and on sourcehut: ~cweiske/dd-wrt-munin.

As of 2022-03-11, the dd-wrt-munin is part of the official munin-contrib plugin repository.

It will generate a graph like this:

dd-wrt munin plugin showing number of connected devices over time

Combined view of connected devices

Now I had two graphs; one for the devices on the FritzBox, and one for the DD-WRT router. I wanted to have them in one single graph. The keyword here is loaning data:

/etc/munin/munin.conf
    wifidevs.update no
    wifidevs.graph_title Connected Wifi devices
    wifidevs.graph_args --base 1000
    wifidevs.graph_vlabel Number of devices
    wifidevs.graph_info Sum of all access points
    wifidevs.graph_scale no
    wifidevs.graph_category network-wifi
    wifidevs.graph_total  Total

    wifidevs.total.label not_used
    wifidevs.total.type GAUGE
    wifidevs.total.draw AREA
    wifidevs.total.stack \
        frit_rt=frit:fritzbox_wifi_devices.wifi \
        tpli_wz=frit:dd_wrt_wifi_devices_tpli_wz.wifi

This combines the wifi data from plugin fritzbox_wifi_devices on node frit and the wifi data from plugin dd_wrt_wifi_devices_tpli_wz. The result is what I wanted:

combined view

Status_Wireless.live.asp format

My dd-wrt-munin plugin uses DD-WRT's /Status_Wireless.live.asp page and tries to parse it. Here are some example data with two connected devices:

{wl_mac::F8:D1:11:8B:23:42}{wl_ssid::home.cweiske.de}{wl_channel::11 + 7 (2462 MHz HT40)}{wl_radio::Radio is On}{wl_xmit::18 dBm}{wl_rate::150 Mbit/s}{wl_busy::20053342 ms}{wl_active::785275128 ms}{wl_quality::98%}{wl_ack::15µs (2250m)}{active_wireless::'48:2C:A0:74:23:42','','ath0','1:33:36','72M','1M','HT20SGI[PS]','-61','-95','34','780','-58','0','0','0','98:CD:AC:2E:23:42','','ath0','1 day,  8:19:17','43M','48M','HT20SGI','-72','-95','23','560','-71','0','0','0'}{active_wds::}{assoc_count::10}{packet_info::SWRXgoodPacket=1965092;SWRXerrorPacket=0;SWTXgoodPacket=13036095;SWTXerrorPacket=0;}{uptime:: 16:59:35 up 9 days,  2:40,  load average: 0.00, 0.01, 0.04}{ipinfo::: Disabled}

This are blocks beginning with { and ending with }. The block name is up to the first :::

wl_mac::F8:D1:11:8B:23:42
wl_ssid::home.cweiske.de
wl_channel::11 + 7 (2462 MHz HT40)
wl_radio::Radio is On
wl_xmit::18 dBm
wl_rate::150 Mbit/s
wl_busy::20053342 ms
wl_active::785275128 ms
wl_quality::98%
wl_ack::15µs (2250m)
active_wireless::'48:2C:A0:74:23:42','','ath0','1:33:36','72M','1M','HT20SGI[PS]','-61','-95','34','780','-58','0','0','0','98:CD:AC:2E:23:42','','ath0','1 day,  8:19:17','43M','48M','HT20SGI','-72','-95','23','560','-71','0','0','0'
active_wds::
assoc_count::10
packet_info::SWRXgoodPacket=1965092;SWRXerrorPacket=0;SWTXgoodPacket=13036095;SWTXerrorPacket=0;
uptime:: 16:59:35 up 9 days,  2:40,  load average: 0.00, 0.01, 0.04
ipinfo::: Disabled

The active_wireless line is a bit cryptic, but the source code wireless_madwifi.c: active_wireless_if helps to understand the columns:

websWrite(
  wp,
  "'%s','%s','%s','%s','%dM','%dM','%s','%d','%d','%d','%d','%d','%d','%d','%d'",
  mac,
  radioname,
  wc->ifname,
  UPTIME(wc->uptime, str),
  wc->txrate / 10 * mul / div,
  wc->rxrate / 10 * mul / div,
  info,
  wc->signal + bias,
  wc->noise + bias,
  wc->signal - wc->noise,
  qual,
  wc->chaininfo_avg[0],
  wc->chaininfo_avg[1],
  wc->chaininfo_avg[2],
  wc->chaininfo_avg[3]
);

Written by Christian Weiske.

Comments? Please send an e-mail.