root / plugins / squeezebox / squeezebox_multi @ e5ce7492
Historique | Voir | Annoter | Télécharger (5,99 ko)
| 1 | 3716785b | Bjorn Ruberg | #!/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 | } |
