Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / wifi / wireless_signal_ranges_ @ c81c20ab

Historique | Voir | Annoter | Télécharger (3,57 ko)

1
#!/bin/sh
2

    
3
: << =cut
4

    
5
=head1 NAME
6

    
7
wireless_signal_ranges_ - Group and count all connected wifi peers by signal strength ranges
8

    
9

    
10
=head1 APPLICABLE SYSTEMS
11

    
12
Information is parsed from the output of the tool "iwinfo" (OpenWrt) or "iw" (most systems).
13

    
14
This plugin is suitable for wifi interfaces with a variable selection of peers (e.g. mobile
15
clients).
16

    
17

    
18
=head1 CONFIGURATION
19

    
20
Symlink this plugin with the name of the wifi interface added (e.g. "wlan0").
21

    
22
Root permissions are probably required for accessing "iw".
23

    
24
  [wireless_signal_ranges_*]
25
  user root
26

    
27

    
28
=head1 VERSION
29

    
30
  1.1
31

    
32

    
33
=head1 AUTHOR
34

    
35
Lars Kruse <devel@sumpfralle.de>
36

    
37

    
38
=head1 LICENSE
39

    
40
GPLv3 or above
41

    
42

    
43
=head1 MAGIC MARKERS
44

    
45
  #%# family=auto
46
  #%# capabilities=autoconf suggest
47

    
48
=cut
49

    
50
set -eu
51

    
52

    
53
SCRIPT_PREFIX="wireless_signal_ranges_"
54

    
55
# thresholds for signal quality ranges: ascending values
56
SIGNAL_THRESHOLDS="-88 -80 -60 0"
57

    
58

    
59
# prefer "iwinfo" for information retrieval, if it is available
60
if which iwinfo >/dev/null; then
61
	# "iwinfo" has a stable output format but is only available on openwrt
62
	get_wifi_interfaces() { iwinfo | grep "^[a-zA-Z]" | awk '{print $1}'; }
63
	# return MAC of peer and the signal strength
64
	get_wifi_peers() { iwinfo "$1" assoclist | grep "^[0-9a-fA-F]" | awk '{print $2}'; }
65
else
66
	# "iw" is available everywhere - but its output format is not recommended for non-humans
67
	get_wifi_interfaces() { iw dev | awk '{ if ($1 == "Interface") print $2; }'; }
68
	get_wifi_peers() { iw dev wlan0 station dump \
69
		| awk '{ if (($1 == "signal") && ($2 == "avg:")) print $3}'; }
70
fi
71

    
72

    
73
clean_fieldname() {
74
	echo "$1" | sed 's/^\([^A-Za-z_]\)/_\1/; s/[^A-Za-z0-9_]/_/g'
75
}
76

    
77

    
78
get_level_fieldname() {
79
	echo "range_${1#-}"
80
}
81

    
82

    
83
get_wifi_device_from_suffix() {
84
	local suffix
85
	local real_dev
86
	# pick the part after the basename of the real file
87
	suffix=$(basename "$0" | sed "s/^$SCRIPT_PREFIX//")
88
	for real_dev in $(get_wifi_interfaces); do
89
		[ "$suffix" != "$(clean_fieldname "$real_dev")" ] || echo "$real_dev"
90
	done | head -1
91
}
92

    
93

    
94
do_config() {
95
	local wifi
96
	local lower
97
	wifi=$(get_wifi_device_from_suffix)
98
	[ -z "$wifi" ] && echo >&2 "Missing wifi: $wifi" && return 1
99
	echo "graph_title Wireless signal quality ranges - $wifi"
100
	echo "graph_args --upper-limit 0"
101
	echo "graph_vlabel Signal ranges"
102
	echo "graph_category network"
103
	echo "graph_info This graph shows numbers of peers with defined wifi signal ranges"
104
	lower="noise"
105
	for level in $SIGNAL_THRESHOLDS; do
106
		fieldname=$(get_level_fieldname "$level")
107
		echo "${fieldname}.label $lower...$level"
108
		echo "${fieldname}.draw AREASTACK"
109
		lower="$level"
110
	done
111
}
112

    
113

    
114
do_fetch() {
115
	local wifi
116
	local peer_data
117
	local previous_count
118
	local current_count
119
	local fieldname
120
	wifi=$(get_wifi_device_from_suffix)
121
	[ -z "$wifi" ] && echo >&2 "Missing wifi: $wifi" && return 1
122
	peer_data=$(get_wifi_peers "$wifi")
123
	previous_count=0
124
	for level in $SIGNAL_THRESHOLDS; do
125
		current_count=$(echo "$peer_data" | awk '
126
			BEGIN { count=0; }
127
			{ if (($1 != "") && ($1 <= '"$level"')) count++; }
128
			END { print count; }')
129
		fieldname=$(get_level_fieldname "$level")
130
		echo "${fieldname}.value $((current_count - previous_count))"
131
		previous_count="$current_count"
132
	done
133
}
134

    
135

    
136
ACTION="${1:-}"
137

    
138
case "$ACTION" in
139
	config)
140
		do_config || exit 1
141
		if [ "${MUNIN_CAP_DIRTYCONFIG:-0}" = "1" ]; then do_fetch; fi
142
		;;
143
	autoconf)
144
		[ -z "$(get_wifi_interfaces)" ] && echo "no (no wifi interfaces found)" && exit 1
145
		echo "yes"
146
		;;
147
	suggest)
148
		get_wifi_interfaces | while read -r ifname; do
149
			clean_fieldname "$ifname"
150
		done
151
		;;
152
	"")
153
		do_fetch
154
		;;
155
	*)
156
		echo >&2 "Invalid action (valid: config / autoconf / suggest / <empty>)"
157
		echo >&2
158
		exit 2
159
		;;
160
esac