- Repository
- Munin (contrib)
- Last change
- 2018-08-01
- Graph Categories
- Family
- auto
- Capabilities
- Keywords
- Language
- Shell
- License
- GPL-3.0-only
- Authors
wireless_signal_noise_
Name
wireless_signal_noise_ - Show signal strength and noise for all connected peers of wifi interface
Applicable Systems
This plugin is suitable for wifi interfaces with a stable selection of peers (e.g. infrastructure). It is probably not useful for hotspot-like scenarios.
Information is parsed from the output of the tool “iwinfo” (OpenWrt) or “iw” (most systems, incomplete information).
Configuration
Symlink this plugin with the name of the wifi interface added (e.g. “wlan0”).
Root permissions are probably required for accessing “iw”.
[wireless_signal_noise_*]
user root
Version
1.1
Author
Lars Kruse devel@sumpfralle.de
License
GPLv3 or above
Magic Markers
#%# family=auto
#%# capabilities=autoconf suggest
#!/bin/sh
: << =cut
=head1 NAME
wireless_signal_noise_ - Show signal strength and noise for all connected peers of wifi interface
=head1 APPLICABLE SYSTEMS
This plugin is suitable for wifi interfaces with a stable selection of peers (e.g. infrastructure).
It is probably not useful for hotspot-like scenarios.
Information is parsed from the output of the tool "iwinfo" (OpenWrt) or "iw" (most systems,
incomplete information).
=head1 CONFIGURATION
Symlink this plugin with the name of the wifi interface added (e.g. "wlan0").
Root permissions are probably required for accessing "iw".
[wireless_signal_noise_*]
user root
=head1 VERSION
1.1
=head1 AUTHOR
Lars Kruse <devel@sumpfralle.de>
=head1 LICENSE
GPLv3 or above
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf suggest
=cut
set -eu
SCRIPT_PREFIX="wireless_signal_noise_"
# prefer "iwinfo" for information retrieval, if it is available
if which iwinfo >/dev/null; then
# "iwinfo" has a stable output format but is only available on openwrt
get_wifi_interfaces() { iwinfo | grep "^[a-zA-Z]" | awk '{print $1}'; }
# return MAC of peer and the signal strength
get_wifi_peers() { iwinfo "$1" assoclist | grep "^[0-9a-fA-F]" | awk '{print $1,$2}'; }
# the noise should be the same for all peers
get_wifi_noise() { iwinfo "$1" info | sed -n 's/^.* Noise: \([0-9-]\+\).*/\1/p'; }
else
# "iw" is available everywhere - but its output format is not recommended for non-humans
get_wifi_interfaces() { iw dev | awk '{ if ($1 == "Interface") print $2; }'; }
get_wifi_peers() { iw dev wlan0 station dump \
| awk '{ if ($1 == "Station") mac=$2; if (($1 == "signal") && ($2 == "avg:")) print mac,$3}'; }
# TODO: there seems to be no way to retrieve the noise level via "iw"
get_wifi_noise() { echo; }
fi
if which arp >/dev/null; then
# openwrt does not provide 'arp' by default
get_arp() { arp -n; }
else
get_arp() { cat /proc/net/arp; }
fi
clean_fieldname() {
echo "$1" | sed 's/^\([^A-Za-z_]\)/_\1/; s/[^A-Za-z0-9_]/_/g'
}
get_ip_for_mac() {
local ip
ip=$(get_arp | grep -iw "$1$" | awk '{print $1}' | sort | head -1)
[ -n "$ip" ] && echo "$ip" && return 0
# no IP found - return MAC instead
echo "$1"
}
get_wifi_device_from_suffix() {
local suffix
local real_dev
# pick the part after the basename of the real file
suffix=$(basename "$0" | sed "s/^$SCRIPT_PREFIX//")
for real_dev in $(get_wifi_interfaces); do
[ "$suffix" != "$(clean_fieldname "$real_dev")" ] || echo "$real_dev"
done | head -1
}
do_config() {
local wifi
wifi=$(get_wifi_device_from_suffix)
[ -z "$wifi" ] && echo >&2 "Missing wifi: $wifi" && return 1
echo "graph_title Wireless signal quality - $wifi"
echo "graph_args --upper-limit 0"
echo "graph_vlabel Signal and noise [dBm]"
echo "graph_category wireless"
echo "graph_info This graph shows the signal and noise for all wifi peers"
echo "noise.label Noise floor"
echo "noise.draw LINE"
# sub graphs for all peers
get_wifi_peers "$wifi" | while read -r mac signal; do
fieldname=$(clean_fieldname "peer_${mac}")
peer=$(get_ip_for_mac "$mac")
echo "signal_${fieldname}.label $peer"
echo "signal_${fieldname}.draw LINE"
done
}
do_fetch() {
local wifi
local peer_data
local noise
wifi=$(get_wifi_device_from_suffix)
[ -z "$wifi" ] && echo >&2 "Missing wifi: $wifi" && return 1
peer_data=$(get_wifi_peers "$wifi")
echo "$peer_data" | while read -r mac signal; do
# ignore empty datasets
[ -z "$signal" ] && continue
fieldname=$(clean_fieldname "peer_${mac}")
echo "signal_${fieldname}.value $signal"
done
noise=$(get_wifi_noise "$wifi")
echo "noise.value ${noise:-U}"
}
ACTION="${1:-}"
case "$ACTION" in
config)
do_config || exit 1
if [ "${MUNIN_CAP_DIRTYCONFIG:-0}" = "1" ]; then do_fetch; fi
;;
autoconf)
if [ -z "$(get_wifi_interfaces)" ]; then
echo "no (no wifi interfaces found)"
else
echo "yes"
fi
;;
suggest)
get_wifi_interfaces | while read -r ifname; do
clean_fieldname "$ifname"
done
;;
"")
do_fetch
;;
*)
echo >&2 "Invalid action (valid: config / suggest / autoconf / <empty>)"
echo >&2
exit 2
;;
esac