Projet

Général

Profil

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

root / plugins / amr / amr.pl @ 2ecac880

Historique | Voir | Annoter | Télécharger (5,4 ko)

1 9860b097 Antoine Beaupré
#! /usr/bin/perl
2
3
#  Copyright (C) 2014 Antoine Beaupré <anarcat@anarc.at>
4
#  Copyright (C) 2008 Joey Schulze <joey@infodrom.org>
5
#
6
#  This program is free software; you can redistribute it and/or modify
7
#  it under the terms of the GNU General Public License as published by
8
#  the Free Software Foundation; version 2 dated June, 1991.
9
#
10
#  This program is distributed in the hope that it will be useful,
11
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
#  GNU General Public License for more details.
14
#
15
#  You should have received a copy of the GNU General Public License
16
#  along with this program;  if not, write to the Free Software
17
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
18
19
# Munin plugin to monitor power usage in smart meters in the 900MHz ISM band
20
21
# Inspired by the postfix_mailstats plugin from munin-contrib
22
23
# Supported configuration:
24
#
25
#   [amr]
26
#   user root
27
#   group adm
28
#   env.logdir /var/log
29
#   env.logfile rtlamr.log
30
31
use strict;
32
use warnings;
33
34
use Munin::Plugin;
35
36
my $LOGDIR  = $ENV{'logdir'}  || '/var/log';
37
my $LOGFILE = $ENV{'logfile'} || 'rtlamr.log';
38
my $unit    = $ENV{'unit'}    || 'J';
39
if ($unit ne 'J' and $unit ne 'Wh')
40
{
41
    print "invalid unit, reverting to Joule";
42
    $unit = 'J';
43
}
44
my $logfile = $LOGDIR .'/'. $LOGFILE;
45
46
# station id => power consumption (in kWh)
47
my %stations;
48
# number of signals sent per station
49
my %signals;
50 2ecac880 Antoine Beaupré
my $count;
51 9860b097 Antoine Beaupré
52
sub autoconf
53
{
54
    if (-d $LOGDIR) {
55
	if (-f $logfile) {
56
            print "yes\n";
57
            exit 0;
58
	} else {
59
	    print "no (logfile not found)\n";
60
	}
61
    } else {
62
	print "no (could not find logdir)\n";
63
    }
64
    exit 1;
65
}
66
67
sub config
68
{
69
    print "multigraph amr_power\n";
70
    print "graph_title Power consumption\n";
71
    print "graph_args --base 1000 -l 0\n";
72
    print "graph_vlabel Watt\n";
73
    print "graph_total  Total\n";
74
    print "graph_category AMR\n";
75
76 2ecac880 Antoine Beaupré
    $count = 0;
77 9860b097 Antoine Beaupré
    foreach my $station (sort keys %stations) {
78
	my $name = clean_fieldname('station power ' . $station);
79 2ecac880 Antoine Beaupré
	printf "%s.label station %d\n", $name, $count;
80 9860b097 Antoine Beaupré
	printf "%s.type COUNTER\n", $name;
81 2ecac880 Antoine Beaupré
        if ($count++) {
82
            printf "%s.draw STACK\n", $name;
83 9860b097 Antoine Beaupré
        }
84
        else {
85 2ecac880 Antoine Beaupré
            printf "%s.draw AREA\n", $name;
86 9860b097 Antoine Beaupré
        }
87
	printf "%s.min 0\n", $name;
88
    }
89
90
    print "multigraph amr_meter\n";
91
    print "graph_title Meter reading\n";
92
    print "graph_args --base 1000 -l 0\n";
93
    print "graph_vlabel kWh\n";
94
    print "graph_scale  no\n";
95
    print "graph_category AMR\n";
96
97 2ecac880 Antoine Beaupré
    $count = 0;
98 9860b097 Antoine Beaupré
    foreach my $station (sort keys %stations) {
99
	my $name = clean_fieldname('station meter ' . $station);
100 2ecac880 Antoine Beaupré
	printf "%s.label station %d\n", $name, $count++;
101 9860b097 Antoine Beaupré
	printf "%s.type GAUGE\n", $name;
102
	printf "%s.min 0\n", $name;
103
    }
104
105
    print "multigraph amr_stations\n";
106
    print "graph_title Known AMR stations\n";
107
    print "graph_args --base 1000 -l 0\n";
108
    print "graph_vlabel stations\n";
109
    print "graph_category AMR\n";
110
    print "stations.label number of stations\n";
111
112
    print "multigraph amr_signals\n";
113
    print "graph_title Number of signals received\n";
114
    print "graph_args --base 1000 -l 0\n";
115
    print "graph_vlabel signals / \${graph_period}\n";
116
    print "graph_period minute\n";
117
    print "graph_category AMR\n";
118 2ecac880 Antoine Beaupré
    $count = 0;
119 9860b097 Antoine Beaupré
    foreach my $station (sort keys %stations) {
120
	my $name = clean_fieldname('station signals ' . $station);
121 2ecac880 Antoine Beaupré
	printf "%s.label station %d\n", $name, $count++;
122 9860b097 Antoine Beaupré
	printf "%s.type ABSOLUTE\n", $name;
123
    }
124
125
    exit 0;
126
}
127
128
sub parse
129
{
130
    my $logfile = shift;
131
    my $pos = shift;
132
133
    my ($log,$rotated) = tail_open $logfile, $pos;
134
135
    while (<$log>) {
136
        # \d protects us against HTML injection here, be careful when changing
137
	if (m,SCM:{ID:(\d+) +.* +Consumption: +(\d+) +,) {
138
	    $stations{$1} = $2;
139
            $signals{$1}++;
140
	}
141
    }
142
    return tail_close $log;
143
}
144
145
need_multigraph();
146
autoconf if $#ARGV > -1 && $ARGV[0] eq "autoconf";
147
148
my @state_vector = restore_state;
149
my $pos = shift @state_vector || 0;
150
%stations = @state_vector;
151
152
$pos = parse $logfile, $pos;
153
if ($#ARGV > -1 && $ARGV[0] eq "config") {
154
    config;
155
    # don't save position on config so next run will reparse it
156
}
157
else {
158
    # this may not scale so well with large graphs, and is useful only
159
    # for debugging, when you want to run this repeatedly without
160
    # loosing data
161
    # this will also mean that stations that disappear will remain forever
162
    save_state $pos, %stations;
163
}
164
165
print "multigraph amr_power\n";
166
foreach my $station (sort keys %stations) {
167
    # the number from the counter is "Wh over 5 minutes", we want to
168
    # give munin joules so he can generate watts by dividing by the period
169
    # 1 Wh = W * 3600 s
170
    #      = 3600 s * J / s
171
    #      = 3.6 kJ
172
    my $power = $stations{$station} * 3600;
173
    if ($unit eq 'Wh') {
174
        # since we want absolute, we'll multiply our result by 300, the assumed time period
175
        $power = $stations{$station} * 300;
176
    }
177
    printf "%s.value %d\n", clean_fieldname('station power ' . $station), $power;
178
}
179
180
print "multigraph amr_meter\n";
181
foreach my $station (sort keys %stations) {
182
    printf "%s.value %d\n", clean_fieldname('station meter ' . $station), $stations{$station};
183
}
184
185
print "multigraph amr_stations\n";
186
printf "stations.value %d\n", scalar keys %stations;
187
188
print "multigraph amr_signals\n";
189
foreach my $station (sort keys %signals) {
190
    printf "%s.value %d\n", clean_fieldname('station signals ' . $station), $signals{$station};
191
}