root / plugins / squeezebox / squeezebox_multi @ 28db7a12
Historique | Voir | Annoter | Télécharger (5,99 ko)
| 1 |
#!/usr/bin/perl |
|---|---|
| 2 |
|
| 3 |
=head1 NAME |
| 4 |
|
| 5 |
squeezebox_ - plugin to monitor a Logitech Media Server and associated |
| 6 |
players. |
| 7 |
|
| 8 |
=head1 APPLICABLE SYSTEMS |
| 9 |
|
| 10 |
Probably any system running Logitech Media Server. Change the host to |
| 11 |
enable remote monitoring. |
| 12 |
|
| 13 |
=head1 CONFIGURATION |
| 14 |
|
| 15 |
No configuration should be required if run on the same server as |
| 16 |
the Logitech Media Server. If the plugin is run from another unit or |
| 17 |
in a non-default configuration, please use the environment variables |
| 18 |
'squeezebox_host' and 'squeezebox_port' to connect. |
| 19 |
|
| 20 |
Sample content for plugin-conf.d/ follows: |
| 21 |
|
| 22 |
[squeezebox] |
| 23 |
env.squeezecenter_host 192.168.100.10 |
| 24 |
env.squeezecenter_port 9095 |
| 25 |
|
| 26 |
=head1 INTERPRETATION |
| 27 |
|
| 28 |
The "volume" graphs only graphs the player volume levels, not the |
| 29 |
amplifier or whatever the player may be connected to. |
| 30 |
|
| 31 |
=head1 MAGIC MARKERS |
| 32 |
|
| 33 |
#%# family=auto |
| 34 |
#%# capabilities=autoconf suggest |
| 35 |
|
| 36 |
=head1 BUGS |
| 37 |
|
| 38 |
None known |
| 39 |
|
| 40 |
=head1 AUTHOR |
| 41 |
|
| 42 |
Bjørn Ruberg |
| 43 |
|
| 44 |
=head1 LICENSE |
| 45 |
|
| 46 |
GPLv2 |
| 47 |
|
| 48 |
=cut |
| 49 |
|
| 50 |
#%# family=auto |
| 51 |
#%# capabilities=autoconf suggest |
| 52 |
|
| 53 |
use strict; |
| 54 |
|
| 55 |
my $ret = undef; |
| 56 |
if (! eval "require Net::Telnet;") {
|
| 57 |
$ret = "Net::Telnet not found"; |
| 58 |
} |
| 59 |
if (! eval "require URI::Escape;") {
|
| 60 |
$ret = "URI::Escape not found"; |
| 61 |
} |
| 62 |
|
| 63 |
use vars qw ($host $port $config); |
| 64 |
|
| 65 |
# Define connection settings, from plugin environment file or use defaults |
| 66 |
my $host = exists $ENV{'squeezecenter_host'} ? $ENV{'squeezecenter_host'} : "127.0.0.1";
|
| 67 |
my $port = exists $ENV{'squeezecenter_port'} ? $ENV{'squeezecenter_port'} : "9090";
|
| 68 |
|
| 69 |
# Argument handling: autoconf, suggest, update, config |
| 70 |
|
| 71 |
if (@ARGV) {
|
| 72 |
if ($ARGV[0] eq "autoconf") {
|
| 73 |
# autoconf for magically self-configuring the plugin |
| 74 |
if ($ret) {
|
| 75 |
print "no ($ret)"; |
| 76 |
exit 0; |
| 77 |
} |
| 78 |
my $conn = new Net::Telnet (Telnetmode => 0); |
| 79 |
$conn->open (Host => $host, |
| 80 |
Port => $port, |
| 81 |
Errmode => "return"); |
| 82 |
if ($conn->errmsg) {
|
| 83 |
print "no (No connection on $host port $port)"; |
| 84 |
exit 0; |
| 85 |
} else {
|
| 86 |
my $version = ""; |
| 87 |
my $line = ""; |
| 88 |
$conn->print("version ?");
|
| 89 |
$conn->print("exit");
|
| 90 |
while (($line = $conn->getline) and ($line !~ /exit/)) {
|
| 91 |
$version = $line if $line =~ /version/; |
| 92 |
} |
| 93 |
if ($version =~ /^version/) {
|
| 94 |
print "yes"; |
| 95 |
exit 0; |
| 96 |
} else {
|
| 97 |
print "no (socket responded but the server didn't respond as expected)"; |
| 98 |
exit 0; |
| 99 |
} |
| 100 |
} |
| 101 |
} elsif ($ARGV[0] eq "suggest") {
|
| 102 |
print "I am a multigraph plugin, and suggest is not required\n"; |
| 103 |
exit 0; |
| 104 |
} elsif ($ARGV[0] eq "update") {
|
| 105 |
# For scheduled inventory rescan, add this plugin to a cron job |
| 106 |
# with the argument "update" Adjust the interval to your own tempo |
| 107 |
# for adding/deleting music. This equals a "Look for new and |
| 108 |
# changed media files" rescan from the webUI. |
| 109 |
# |
| 110 |
# example: 5 * * * * /usr/share/munin/plugins/squeezebox update |
| 111 |
|
| 112 |
my $conn = new Net::Telnet (Telnetmode => 0); |
| 113 |
$conn->open (Host => $host, |
| 114 |
Port => $port, |
| 115 |
Errmode => "return"); |
| 116 |
if ($conn->errmsg) {
|
| 117 |
print $conn->errmsg, "\n";; |
| 118 |
exit 1; |
| 119 |
} else {
|
| 120 |
$conn->print("rescan");
|
| 121 |
$conn->print("exit");
|
| 122 |
exit 0; |
| 123 |
} |
| 124 |
} elsif ($ARGV[0] eq "config") {
|
| 125 |
# Sets $config value for using in the main execution cycle |
| 126 |
$config = 1; |
| 127 |
} |
| 128 |
} |
| 129 |
|
| 130 |
# We're keeping the socket open for all checks |
| 131 |
my $conn = new Net::Telnet (Telnetmode => 0); |
| 132 |
$conn->open (Host => $host, |
| 133 |
Port => $port); |
| 134 |
|
| 135 |
use URI::Escape; |
| 136 |
# use Encode qw (from_to); |
| 137 |
use Text::Iconv; |
| 138 |
my $converter = Text::Iconv->new("UTF-8", "LATIN1");
|
| 139 |
# $converted = $converter->convert("Text to convert");
|
| 140 |
|
| 141 |
# First all the simple readings |
| 142 |
foreach my $attr qw (albums artists genres songs) {
|
| 143 |
$conn->print ("info total ${attr} ?");
|
| 144 |
my $line = uri_unescape($conn->getline); |
| 145 |
if ($line =~ /^info total ${attr} (\d+)$/) {
|
| 146 |
my $number = $1; |
| 147 |
print "multigraph squeezebox_${attr}\n";
|
| 148 |
if ($config) {
|
| 149 |
print "graph_title Number of ${attr}\n";
|
| 150 |
print "graph_scale no\n"; |
| 151 |
print "graph_category Squeezebox\n"; |
| 152 |
print "${attr}.label ${attr}\n";
|
| 153 |
} else {
|
| 154 |
print "${attr}.value $number\n";
|
| 155 |
} |
| 156 |
} |
| 157 |
} |
| 158 |
|
| 159 |
# years |
| 160 |
$conn->print ("years");
|
| 161 |
if (uri_unescape($conn->getline) =~ /^years\s+count:(\d+)/) {
|
| 162 |
my $no_of_years = $1; |
| 163 |
$conn->print ("years 0 $no_of_years");
|
| 164 |
my @years = split (" ", uri_unescape($conn->getline));
|
| 165 |
print "multigraph squeezebox_years\n"; |
| 166 |
|
| 167 |
if ($config) {
|
| 168 |
# config run |
| 169 |
print "graph_title Albums per year\n"; |
| 170 |
print "graph_category Squeezebox\n"; |
| 171 |
print "graph_args --base 1000 -l 0\n"; |
| 172 |
foreach my $year (@years) {
|
| 173 |
if ($year =~ /year\:(\d+)/) {
|
| 174 |
print "y" . $1 . ".label $1\n"; |
| 175 |
print "y" . $1 . ".draw AREASTACK\n"; |
| 176 |
} |
| 177 |
} |
| 178 |
} else {
|
| 179 |
# regular run |
| 180 |
foreach my $year (@years) {
|
| 181 |
if ($year =~ /(year\:\d+)/) {
|
| 182 |
$conn->print ("albums 0 0 $1");
|
| 183 |
# albums 0 0 year:2007 count:13 |
| 184 |
my $line = uri_unescape ($conn->getline); |
| 185 |
if ($line =~ /^.*year\:(\d+) count\:(\d+)$/) {
|
| 186 |
print "y${1}.value ${2}\n";
|
| 187 |
} |
| 188 |
|
| 189 |
} |
| 190 |
} |
| 191 |
} |
| 192 |
} |
| 193 |
|
| 194 |
# mixer volume and signalstrength |
| 195 |
foreach my $attr ("signalstrength", "mixer volume") {
|
| 196 |
# The plugin reports as squeezebox_volume while the command is |
| 197 |
# "mixer volume". |
| 198 |
(my $attr_print = $attr) =~ s/mixer //g; |
| 199 |
print "multigraph squeezebox_${attr_print}\n";
|
| 200 |
if ($config) {
|
| 201 |
print "graph_title " . ucfirst ($attr) . "\n"; |
| 202 |
print "graph_category Squeezebox\n"; |
| 203 |
} |
| 204 |
$conn->print ("player count ?");
|
| 205 |
(my $no_of_players = uri_unescape ($conn->getline)) =~ s/player count\s+//; |
| 206 |
chomp $no_of_players; |
| 207 |
my $id; |
| 208 |
for ($id = 0; $id < $no_of_players; $id++) {
|
| 209 |
$conn->print ("player id ${id} ?");
|
| 210 |
(my $mac = uri_unescape ($conn->getline)) =~ s/player id \d+ //g; |
| 211 |
chomp ($mac); |
| 212 |
(my $mac_print = 'm' . $mac) =~ s/\://g; |
| 213 |
if ($config) {
|
| 214 |
$conn->print ("player name ${mac} ?");
|
| 215 |
(my $name = uri_unescape ($conn->getline)) =~ s/player name ${mac} //g;
|
| 216 |
chomp $name; |
| 217 |
print "${mac_print}.label ", $converter->convert($name), "\n";
|
| 218 |
} else {
|
| 219 |
$conn->print ("${mac} ${attr} ?");
|
| 220 |
(my $value = uri_unescape ($conn->getline)) =~ s/^.* //g; |
| 221 |
chomp $value; |
| 222 |
print "${mac_print}.value $value\n";
|
| 223 |
} |
| 224 |
} |
| 225 |
} |
| 226 |
|
