X-Git-Url: http://gb7djk.dxcluster.net/gitweb/gitweb.cgi?a=blobdiff_plain;f=loop.pl;h=02a463a7d3f1569eda6f6065b4a6cf4e1007e2ad;hb=9b87b2428a5050fb2fd2803d0d568ca916365738;hp=7abba2d70408881c61ace5f86599da67f4d3e8ea;hpb=6e03f8c08e990182830f8a8d9b240445af94a55a;p=dweather.git diff --git a/loop.pl b/loop.pl index 7abba2d..02a463a 100755 --- a/loop.pl +++ b/loop.pl @@ -33,7 +33,8 @@ my $nlcount; my $state = "ready"; my $buf; my $dbg; -my $ser; # the serial port Mojo::IOLoop::Stream +our $ser; # the serial port Mojo::IOLoop::Stream +our $ob; # the Serial Port filehandle my $last_min_h; my $last_hour_h; @@ -96,7 +97,7 @@ $bar_trend{60} = "Rising Rapidly"; our $ending = 0; -$SIG{TERM} = $SIG{INT} = sub {++$ending; Mojo::IOLoop->stop;}; +$SIG{TERM} = $SIG{INT} = sub {$ending = 1; Mojo::IOLoop->stop;}; $SIG{HUP} = 'IGNORE'; @@ -164,18 +165,22 @@ dbg sprintf("last5days = %d last10mins = %d", scalar @last5daysh, scalar @last10 sysopen(R, $randomfn, 0) or die "cannot open $randomfn $!\n"; my $rs; -sysread(R, $rs, 32) or die "not enough randomness available\n"; +sysread(R, $rs, 8) or die "not enough randomness available\n"; close R; app->secrets([qw(Here's something that's really seakrett), $rs]); our $dlog = SMGLog->new("day"); +$did = Mojo::IOLoop->recurring(1 => sub {$dlog->flushall}); + dbg "before next tick"; Mojo::IOLoop->next_tick(sub { loop() }); dbg "before app start"; app->start; dbg "after app start"; +doclose(); + write_ld(); $dataf->close if $dataf; undef $dataf; @@ -185,7 +190,7 @@ undef $dataf; cycle_loop_data_files(); dbg '***'; -dbg "*** ending $0"; +dbg "*** ending $0 (\$ending = $ending)"; dbg '***'; exit 0; @@ -197,9 +202,8 @@ sub loop dbg "last_min: " . scalar gmtime($ld->{last_min}); dbg "last_hour: " . scalar gmtime($ld->{last_hour}); - $did = Mojo::IOLoop->recurring(1 => sub {$dlog->flushall}); - - do_reopen($devname); + $ser = doopen($devname); + start_loop() if $ser; } @@ -243,8 +247,7 @@ sub start_loop undef $tid; $tid = Mojo::IOLoop->recurring(0.6 => sub { if (++$nlcount > 10) { - dbg "\\n count > 10, closing connection" if isdbg 'chan'; - do_reopen($devname); + doclose(); return; } dbg "writing $nlcount \\n" if isdbg 'state'; @@ -259,47 +262,68 @@ sub chgstate $state = $_[0]; } -sub do_reopen -{ - my $name = shift; - dbg "do reopen on '$name' ending $ending"; - unless ($ending) { - $ser = do_open($name); - start_loop(); - chgstate(''); - $nlcount = 0; - Mojo::IOLoop->start unless Mojo::IOLoop->is_running; - } -} +my $closing; -sub do_open +sub doopen { my $name = shift; - $ser->close if $ser; - undef $ser; - - my $ob = Serial->new($name, 19200) || die "$name $!\n"; + $ob = Serial->new($name, 19200) || die "$name $!\n"; dbg "streaming $name fileno(" . fileno($ob) . ")" if isdbg 'chan'; my $ser = Mojo::IOLoop::Stream->new($ob); - $ser->on(error=>sub {dbg "serial $_[1]"; do_reopen($name) unless $ending}); - $ser->on(close=>sub {dbg "serial closing"; do_reopen($name) unless $ending}); - $ser->on(timeout=>sub {dbg "serial timeout";}); + $ser->on(error=>sub {dbg "error serial $_[1]"; doclose();}); + $ser->on(close=>sub {dbg "event close"; doclose();}); + $ser->on(timeout=>sub {dbg "event serial timeout"; doclose();}); $ser->on(read=>sub {on_read(@_)}); $ser->start; + $rid = Mojo::IOLoop->recurring($poll_interval => sub { + start_loop() if !$state; + }); + + chgstate(''); + $nlcount = 0; + + return $ser; +} + +sub doclose +{ + return if $closing++; + + dbg "serial port closing" if $ser || $ob; + if ($ser) { + $ser->stop; + $ser->close; + undef $ser; + } + if ($ob) { + $ob->close(); + undef $ob; + } Mojo::IOLoop->remove($tid) if $tid; undef $tid; Mojo::IOLoop->remove($rid) if $rid; undef $rid; - $rid = Mojo::IOLoop->recurring($poll_interval => sub { - start_loop() if !$state; - }); + + if (Mojo::IOLoop->is_running && $ending == 0) { + Mojo::IOLoop->delay( + sub { + my $delay = shift; + Mojo::IOLoop->timer(5 => $delay->begin); + dbg "Waiting 5 seconds before opening serial port"; + }, + + sub { + dbg "Opening Serial port"; + $ser = doopen($devname); + $closing = 0; + } + )->wait; + } chgstate(''); $nlcount = 0; - - return $ser; } my @min; @@ -324,7 +348,7 @@ sub process # Common ones $tmp = unpack("s", substr $blk,7,2) / 1000; - $h{Pressure} = nearest(1, in2mb($tmp)); + $h{Pressure} = nearest(0.1, in2mb($tmp)); $tmp = unpack("s", substr $blk,9,2) / 10; $h{Temp_In} = nearest(0.1, f2c($tmp)); @@ -397,22 +421,31 @@ sub process my $ts = time; my $s; my $dayno = int($ts/86400); + my $writeld; + my $cycledata; + if ($dayno > $ld->{last_day}) { - $ld->{Temp_Out_Max} = $ld->{Temp_Out_Min} = $temp; - $ld->{Temp_Out_Max_T} = $ld->{Temp_Out_Min_T} = clocktime($ts, 0); + $ld->{Temp_Out_Max} = $ld->{Temp_Out_Min} = $ld->{Wind_Max} = $temp; + $ld->{Temp_Out_Max_T} = $ld->{Temp_Out_Min_T} = $ld->{Wind_Max_T} = clocktime($ts, 0); $ld->{last_day} = $dayno; - write_ld(); - cycle_loop_data_files(); + ++$writeld; + ++$cycledata; } if ($temp > $ld->{Temp_Out_Max}) { - $ld->{Temp_Out_Max} = $temp; - $ld->{Temp_Out_Max_T} = clocktime($ts, 0); - write_ld(); + $h{Temp_Out_Max} = $ld->{Temp_Out_Max} = $temp; + $h{Temp_Out_Max_T} = $ld->{Temp_Out_Max_T} = clocktime($ts, 0); + ++$writeld; } if ($temp < $ld->{Temp_Out_Min}) { - $ld->{Temp_Out_Min} = $temp; - $ld->{Temp_Out_Min_T} = clocktime($ts, 0); - write_ld(); + $h{Temp_Out_Min} = $ld->{Temp_Out_Min} = $temp; + $h{Temp_Out_Min_T} = $ld->{Temp_Out_Min_T} = clocktime($ts, 0); + ++$writeld; + } + + if ($wind->{w} > $ld->{Wind_Max}) { + $h{Wind_Max} = $ld->{Wind_Max} = $wind->{w}; + $h{Wind_Max_T} = $ld->{Wind_Max_T} = clocktime($ts, 0); + ++$writeld; } if ($ts >= $ld->{last_hour} + 1800) { @@ -426,11 +459,6 @@ sub process $h{Sunrise} =~ s/(\d{2})(\d{2})/$1:$2/; $h{Sunset} = sprintf( "%04d", unpack("S", substr $blk,93,2) ); $h{Sunset} =~ s/(\d{2})(\d{2})/$1:$2/; - $h{Temp_Out_Max} = $ld->{Temp_Out_Max}; - $h{Temp_Out_Min} = $ld->{Temp_Out_Min}; - $h{Temp_Out_Max_T} = $ld->{Temp_Out_Max_T}; - $h{Temp_Out_Min_T} = $ld->{Temp_Out_Min_T}; - if ($loop_count) { # i.e not the first my $a = wind_average(scalar @{$ld->{wind_hour}} ? @{$ld->{wind_hour}} : {w => $h{Wind}, d => $h{Dir}}); @@ -443,8 +471,15 @@ sub process $h{Dir_1m} = nearest(1, $a->{d}); ($h{Rain_1m}, $h{Rain_1h}, $h{Rain_24h}) = calc_rain($rain); + } $ld->{last_rain_min} = $ld->{last_rain_hour} = $rain; + $h{Temp_Out_Max} = $ld->{Temp_Out_Max}; + $h{Temp_Out_Max_T} = $ld->{Temp_Out_Max_T}; + $h{Temp_Out_Min} = $ld->{Temp_Out_Min}; + $h{Temp_Out_Min_T} = $ld->{Temp_Out_Min_T}; + $h{Wind_Max} = $ld->{Wind_Max}; + $h{Wind_Max_T} = $ld->{Wind_Max_T}; $last_hour_h = {%h}; $s = genstr($ts, 'h', \%h); @@ -460,7 +495,7 @@ sub process push @last5daysh, $s; shift @last5daysh if @last5daysh > 5*24; } - write_ld(); + ++$writeld; } elsif ($ts >= $ld->{last_min} + 60) { my $a = wind_average(@{$ld->{wind_min}}); @@ -476,11 +511,12 @@ sub process ($h{Rain_1m}, $h{Rain_1h}, $h{Rain_24h}) = calc_rain($rain); } $ld->{last_rain_min} = $rain; - $h{Temp_Out_Max} = $ld->{Temp_Out_Max}; - $h{Temp_Out_Min} = $ld->{Temp_Out_Min}; $h{Temp_Out_Max_T} = $ld->{Temp_Out_Max_T}; + $h{Temp_Out_Min} = $ld->{Temp_Out_Min}; $h{Temp_Out_Min_T} = $ld->{Temp_Out_Min_T}; + $h{Wind_Max} = $ld->{Wind_Max}; + $h{Wind_Max_T} = $ld->{Wind_Max_T}; $last_min_h = {%h}; $s = genstr($ts, 'm', \%h); @@ -490,7 +526,7 @@ sub process @{$ld->{wind_min}} = (); output_str($s, 1) if $s; - write_ld(); + ++$writeld; } else { my $o = gen_hash_diff($ld->{last_h}, \%h); @@ -509,6 +545,8 @@ sub process output_str($s, 0) if $s; } $ld->{last_h} = \%h; + write_ld() if $writeld; + cycle_loop_data_files() if $cycledata; ++$loop_count; } else { dbg "CRC check failed for LOOP data!";