]>
Git — Sourcephile - julm/air-duino.git/blob - collect.pl
2 # Licence: WTFPLv2 <http://www.wtfpl.net/txt/copying/>
3 # Copyright 2015: Julien Moutinho <julm+air@autogeree.net>
7 use DateTime
::Duration
;
9 use Device
::SerialPort
qw( 0.07 );
13 use Log
::Log4perl
qw(:easy);
15 #use Data::Dumper qw(Dumper);
17 my $step = 30; # NOTE: sampling interval in seconds
20 #Log::Log4perl->easy_init(
22 # , category => 'rrdtool'
27 ( time_zone
=> 'local'
28 #, locale => $config{locale}
29 ); # ->set_time_zone('floating');
30 my $dir = File
::Spec-
>catdir(dirname
($0), 'rrd', (sprintf '%0d', $now->year()));
31 my $file = File
::Spec-
>catfile($dir, (sprintf '%02d.rrd', $now->month()));
32 File
::Path
::make_path
($dir);
33 my $rrd = RRDTool
::OO-
>new(file
=> $file);
35 my $one_month = DateTime
::Duration-
>new(months
=> 1, end_of_month
=> 'limit');
36 my $month_begin = $now->clone->truncate(to
=> 'month');
37 my $month_end = $month_begin->clone->add_duration($one_month);
38 my $month_seconds = $month_end->epoch() - $month_begin->epoch();
42 { name
=> "temperature"
46 , heartbeat
=> 2 * $step # seconds
53 , heartbeat
=> 2 * $step # seconds
60 , heartbeat
=> 2 * $step # seconds
67 , heartbeat
=> 2 * $step # seconds
70 { name
=> "co_ch4_lpg"
74 , heartbeat
=> 2 * $step # seconds
79 , rows
=> $month_seconds / $step
80 , xff
=> 0.99 # ignore unknowns values (U)
88 my $dev = Device
::SerialPort-
>new($file);
89 $dev->baudrate(9600); # MUST: match *uino Serial.begin()
90 #$dev->buffers(4096, 4096); # NOTE: no-op on POSIX
92 $dev->dtr_active(1); # NOTE: reset the *uino on serial connection
93 $dev->handshake('none');
95 $dev->read_char_time(0); # NOTE: don't wait for each character
96 $dev->read_const_time(1000); # NOTE: 1 second per unfulfilled "read" call
103 my $rrd = rrd_init
();
104 my $dev = dev_init
($ARGV[0]);
107 my $read_timeout = 60;
108 my $timeout = $read_timeout;
113 my $curr_day = (localtime)[3];
114 if ($curr_day == 1) {
115 # NOTE: month changed, change RRD
116 # FIXME: avoid to check that every second...
119 my ($count, $saw) = $dev->read(1);
120 # NOTE: this could have read up to 255 chars (max for portability)
121 # but reading only 1 char at a time
122 # enables to add a more accurate timestamp.
123 if (defined $count and $count > 0) {
125 #print STDERR "saw: $buffer\n";
126 my @lines = split /\r?\n/, $buffer;
129 # NOTE: process only ended lines
130 $buffer = pop @lines;
131 #print STDERR "buffer: $buffer\n";
133 #print STDERR "line: $_\n";
135 = $_ =~ m/^loop=[0-9]+;up=[0-9]+;temp=([0-9]+.[0-9]+)?;humi=([0-9]+.[0-9]+)?;air=([0-9]+)?;dust=([0-9]+.[0-9]+)?;fire=([0-9]+.[0-9]+)?$/;
137 for ($i = 0; $i < @fields; $i++) {
138 if (defined $fields[$i] && $fields[$i] ne '') {
139 $collect[$i] = $fields[$i];
141 elsif (not (exists $collect[$i])) {
142 $collect[$i] = undef;
145 #print STDERR "collect: ".Dumper(\@collect)."\n";
146 if ($time >= $last_time + $step && @collect == 5) {
149 , values => [join (':', map { defined $_ ? $_ : 'U' } @collect)]
155 # print STDOUT ($time, ";", $_, "\n");
159 $timeout = $read_timeout;
166 die "Connection timeout (after ${read_timeout}s)\n";