From 959446c006dd22ac38f8d09998e866c338b480cd Mon Sep 17 00:00:00 2001 From: Dirk Koopman Date: Sun, 13 Jul 2014 13:41:23 +0100 Subject: [PATCH] start hardening the looping Try to restart the serial port after it closes. --- Serial.pm | 8 +++-- loop.pl | 92 ++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 75 insertions(+), 25 deletions(-) diff --git a/Serial.pm b/Serial.pm index 26b9c2e..fdfb9e0 100644 --- a/Serial.pm +++ b/Serial.pm @@ -31,7 +31,7 @@ sub new # get my attributes $$self->{ORIGTERM} = POSIX::Termios->new(); - my $term = $$self->{TERM} = POSIX::Termios->new(); + my $term = POSIX::Termios->new(); $$self->{ORIGTERM}->getattr(fileno($self)); $term->getattr(fileno($self)); my ($speed) = grep {/^\d+$/} @_; @@ -65,6 +65,8 @@ sub new $term->setcflag($cflag); $term->setlflag($lflag); $term->setoflag($oflag); $term->setiflag($iflag); $term->setattr(fileno($self), TCSANOW); + $$self->{TERM} = $term; + return $self; } @@ -79,13 +81,13 @@ sub setattr { my $self = shift; my $attr = shift || $$self->{TERM}; - $attr->setattr(fileno($self), &POSIX::TCSANOW); + $attr->setattr(fileno($self), &POSIX::TCSANOW) if fileno($self); } sub close { my $self = shift; - $self->setattr(delete $$self->{ORIGTERM}); + $self->setattr(delete $$self->{ORIGTERM}) if fileno($self) && $$self->{ORIGTERM}; $self->SUPER::close; } diff --git a/loop.pl b/loop.pl index 8a33ba7..cbdeefd 100755 --- a/loop.pl +++ b/loop.pl @@ -11,7 +11,7 @@ use Debug; use SMGLog; my $devname = "/dev/davis"; -my $rain_mult = 0.1; # 0.1 or 0.2 mm or 0.01 inches +my $rain_mult = 0.2; # 0.1 or 0.2 mm or 0.01 inches my $tid; my $rid; my $count; @@ -67,6 +67,13 @@ $bar_trend{60} = "Rising Rapidly"; #$SIG{TERM} = $SIG{INT} = sub {Mojo::IOLoop->stop if Mojo::IOLoop->is_running && !$DB::VERSION}; +dbginit(); +if (@ARGV) { + dbgadd(@ARGV); +} +dbgadd('chan'); + + my $dlog = SMGLog->new("day"); $dlog->mode('a'); @@ -84,7 +91,7 @@ sub on_read my ($str, $d) = @_; $buf .= $d; $d =~ s/([\%\x00-\x1f\x7f-\xff])/sprintf("%%%02X", ord($1))/eg; -# say "read added '$d' buf lth=" . length $buf if $dbg; + dbg "read added '$d' buf lth=" . length $buf if isdbg('raw'); if ($state eq 'waitnl' && $buf =~ /[\cJ\cM]+/) { Mojo::IOLoop->remove($tid); undef $buf; @@ -97,7 +104,7 @@ sub on_read } } elsif ($state eq 'waitlooprec') { if (length $buf >= 99) { - say "got loop record\n" if $dbg; + dbg "got loop record\n" if isdbg('chan'); chgstate(''); process($buf); @@ -108,17 +115,17 @@ sub on_read sub start_loop { - say "writing \\n" if $dbg; + dbg "writing \\n" if isdbg('chan'); $s->write("\n"); - $tid = Mojo::IOLoop->recurring(0.6 => sub {say "writing \\n" if $dbg; $s->write("\n")}); + $tid = Mojo::IOLoop->recurring(0.6 => sub {dbg "writing \\n" if isdbg('chan'); $s->write("\n")}); chgstate("waitnl"); } sub chgstate { - say "state '$state' -> '$_[0]'" if $dbg; + dbg "state '$state' -> '$_[0]'" if isdbg('chan'); $state = $_[0]; } @@ -127,13 +134,13 @@ sub do_open { my $name = shift; my $ob = Serial->new($name, 19200) || die "$name $!\n"; - say "streaming $name fileno(", fileno($ob), ")" if $dbg; + dbg "streaming $name fileno(", fileno($ob), ")" if isdbg('chan'); my $str = Mojo::IOLoop::Stream->new($ob); - $str->on(error=>sub {say "serial $_[1]"; undef $s; Mojo::IOLoop->reset;}); + $str->on(error=>sub {dbg "serial $_[1]"; undef $s; Mojo::IOLoop->reset;}); - $str->on(close=>sub {say "serial closing"; undef $s; Mojo::IOLoop->reset;}); - $str->on(timeout=>sub {say "serial timeout";}); + $str->on(close=>sub {dbg "serial closing"; undef $s; Mojo::IOLoop->reset;}); + $str->on(timeout=>sub {dbg "serial timeout";}); $str->on(read=>sub {on_read(@_)}); $str->start; @@ -144,14 +151,18 @@ sub do_open return $str; } -my $last_time; +our $last_min = time; +our $last_hour = time; + +my @min; +my @hour; sub process { my $blk = shift; my $loo = substr $blk,0,3; unless ( $loo eq 'LOO') { - say "Block invalid loo -> $loo" if $dbg; return; + dbg "Block invalid loo -> $loo" if isdbg('chan'); return; } my $t; @@ -173,6 +184,8 @@ sub process $h{Wind} = sprintf("%.1f",mph2mps($t))+0; $h{Dir} = unpack("s", substr $blk,16,2)+0; + my $wind = {w => $h{Wind}, d => $h{Dir}}; + push @min, $wind; $h{'Humidity_Out'} = unpack("C", substr $blk,33,1)+0; $h{'Humidity_In'} = unpack("C", substr $blk,11,1)+0; @@ -192,13 +205,13 @@ sub process # Newer LOOP2 packet $t = unpack("C", substr $blk,18,2); - $h{Wind_Avg_10} = sprintf("%.1f",mph2mps($t/10))+0; +# $h{Wind_Avg_10} = sprintf("%.1f",mph2mps($t/10))+0; $t = unpack("C", substr $blk,20,2); - $h{Wind_Avg_2} = sprintf("%.1f",mph2mps($t/10))+0; +# $h{Wind_Avg_2} = sprintf("%.1f",mph2mps($t/10))+0; $t = unpack("C", substr $blk,22,2); - $h{Wind_Gust_10} = sprintf("%.1f",mph2mps($t/10))+0; +# $h{Wind_Gust_10} = sprintf("%.1f",mph2mps($t/10))+0; - $h{Dir_Avg_10} = unpack("C", substr $blk,24,2)+0; +# $h{Dir_Avg_10} = unpack("C", substr $blk,24,2)+0; $t = unpack("C", substr $blk,30,2); $h{Dew_Point} = sprintf("%0.1f", f2c($t))+0; @@ -206,7 +219,7 @@ sub process # Older LOOP packet $t = unpack("C", substr $blk,15,1); - $h{Wind_Avg_10} = sprintf("%.1f",mph2mps($t))+0; +# $h{Wind_Avg_10} = sprintf("%.1f",mph2mps($t))+0; $h{'Dew_Point'} = sprintf("%0.1f", dew_point($h{Temp_Out}, $h{'Humidity_Out'}))+0; $h{'Rain_Month'} = sprintf("%0.1f", unpack("s", substr $blk,52,2) * $rain_mult)+0; @@ -233,21 +246,38 @@ sub process my $t = time; my $j; my $s; - if ($t >= $last_time + 60) { + if ($t >= $last_min + 60) { + my $a = average(@min); + push @hour, $a; + + $h{Wind_1m} = sprintf("%0.1f", $a->{w})+0; + $h{Dir_1m} = sprintf("%0.0f", $a->{d})+0; + $j = encode_json(\%h); $s = qq|{"t":$t,"m":$j}|; - $last_time = $t; + $last_min = $t; + if ($t >= $last_hour + 3600) { + my $a = average(@hour); + + delete $h{Wind_1m}; + delete $h{Dir_1m}; + $h{Wind_1h} = sprintf("%0.1f", $a->{w})+0; + $h{Dir_1h} = sprintf("%0.0f", $a->{d})+0; + + $j = encode_json(\%h); + $s = qq|{"t":$t,"h":$j}|; + $last_hour = $t; + } } elsif ($o) { $j = encode_json($o); $s = qq|{"t":$t,"r":$j}|; } if ($s) { - say $s; + dbg $s; $dlog->writenow($s); } } else { - say "CRC check failed for LOOP data!"; - return 1; + dbg "CRC check failed for LOOP data!"; } } @@ -325,3 +355,21 @@ sub in2mb { return $_[0] * 33.8637526; } + +sub average +{ + my %out; + my $count; + + foreach my $r (@_) { + while (my ($k, $v) = each %$r) { + $out{$k} += $v; + } + ++$count; + } + while (my ($k, $v) = each %out) { + $out{$k} /= $count; + } + + return \%out; +} -- 2.43.0