start hardening the looping
authorDirk Koopman <djk@tobit.co.uk>
Sun, 13 Jul 2014 12:41:23 +0000 (13:41 +0100)
committerDirk Koopman <djk@tobit.co.uk>
Sun, 13 Jul 2014 12:41:23 +0000 (13:41 +0100)
Try to restart the serial port after it closes.

Serial.pm
loop.pl

index 26b9c2e49697092ed0bf0823c8e836e3faf5df97..fdfb9e055b9e609f07686e36c16ef14cbfd38b3d 100644 (file)
--- 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 8a33ba72ce797146e6b6c81e7c1de65c4c35687e..cbdeefd8ab1912ab97a016ae14a43e3d1f5389e6 100755 (executable)
--- 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;
+}