use v5.10.1;
-use DBI;
use Serial;
use Mojo::IOLoop;
use Mojo::IOLoop::Stream;
use Mojo::JSON qw(decode_json encode_json);
+use Debug;
+use SMGLog;
my $devname = "/dev/davis";
my $rain_mult = 0.1; # 0.1 or 0.2 mm or 0.01 inches
#$SIG{TERM} = $SIG{INT} = sub {Mojo::IOLoop->stop if Mojo::IOLoop->is_running && !$DB::VERSION};
+my $dlog = SMGLog->new("day");
+$dlog->mode('a');
+
my $s = do_open($devname);
start_loop();
-Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
+Mojo::IOLoop->recurring(0.1 => sub { $dlog->flushall });
-$s->close;
+Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
exit 0;
$d =~ s/([\%\x00-\x1f\x7f-\xff])/sprintf("%%%02X", ord($1))/eg;
# say "read added '$d' buf lth=" . length $buf if $dbg;
if ($state eq 'waitnl' && $buf =~ /[\cJ\cM]+/) {
- undef $tid;
+ Mojo::IOLoop->remove($tid);
undef $buf;
- $s->write("LOOP 1\n");
+ $s->write("LPS 1 1\n");
chgstate("waitloop");
} elsif ($state eq "waitloop") {
if ($buf =~ /\x06/) {
say "writing \\n" if $dbg;
$s->write("\n");
- $tid = Mojo::IOLoop->timer(0.6 => sub {say "writing \\n" if $dbg; $s->write("\n")});
+ $tid = Mojo::IOLoop->recurring(0.6 => sub {say "writing \\n" if $dbg; $s->write("\n")});
chgstate("waitnl");
}
$str->on(read=>sub {on_read(@_)});
$str->start;
- $rid = Mojo::IOLoop->recurring(2.5 => sub {start_loop() if !$state || $state eq "waitnl";});
+ $rid = Mojo::IOLoop->recurring(2.5 => sub {
+ start_loop() if !$state || $state eq "waitnl";
+ });
return $str;
}
+my $last_time;
+
sub process
{
my $blk = shift;
my $t;
my %h;
-
- #$h{'next_rec'} = unpack("s", substr $blk,5,2);
-
- $h{'Barometric_Trend'} = unpack("C", substr $blk,3,1);
- $h{'Barometric_Trend_txt'} = $bar_trend{$h{'Barometric_Trend'}};
+ # Common ones
+ $h{Pressure_Trend} = unpack("C", substr $blk,3,1);
+ $h{Pressure_Trend_txt} = $bar_trend{$h{'Pressure_Trend'}};
$t = unpack("s", substr $blk,7,2) / 1000;
- $h{'Barometric_Press_mb'} = sprintf("%.0f",$t*33.8637526);
-
+ $h{Pressure} = sprintf("%.0f",in2mb($t))+0;
$t = unpack("s", substr $blk,9,2) / 10;
- $h{'Air_Temp_Inside_c'} = sprintf("%.1f",($t - 32) * 5/9);
- my $tf = unpack("s", substr $blk,12,2) / 10;
- $h{'Air_Temp_Outside_c'} = sprintf("%.1f",($tf - 32) * 5/9);
-
- $h{'Wind_Speed_mph'} = unpack("C", substr $blk,14,1);
- $h{'Wind_Speed_mps'} = sprintf("%.1f",$h{'Wind_Speed_mph'}*0.44704);
- $h{'Wind_Speed_10min_Avg_mph'} = unpack("C", substr $blk,15,1);
- $h{'Wind_Speed_10min_Avg_mps'} = sprintf("%.1f",$h{'Wind_Speed_10min_Avg_mph'}*0.44704);
- $h{'Wind_Dir'} = unpack("s", substr $blk,16,2);
-
+ $h{Temp_In} = sprintf("%.1f", f2c($t))+0;
+
+ $t = unpack("s", substr $blk,12,2) / 10;
+ $h{Temp_Out} = sprintf("%.1f", f2c($t))+0;
- $h{'Humidity_Outside'} = unpack("C", substr $blk,33,1);
- $h{'Humidity_Inside'} = unpack("C", substr $blk,11,1);
- $h{'Dew_Point'} = dew_point($h{Air_Temp_Outside_c}, $h{'Humidity_Outside'});
+ $t = unpack("C", substr $blk,14,1);
+ $h{Wind} = sprintf("%.1f",mph2mps($t))+0;
+ $h{Dir} = unpack("s", substr $blk,16,2)+0;
- $h{'UV'} = unpack("C", substr $blk,43,1);
- $h{'Solar'} = unpack("s", substr $blk,44,2); # watt/m**2
- $h{'Rain_Rate'} = unpack("s", substr $blk,41,2) * $rain_mult;
- $h{'Rain_Day'} = unpack("s", substr $blk,50,2) * $rain_mult;
- $h{'Rain_Month'} = unpack("s", substr $blk,52,2) * $rain_mult;
- $h{'Rain_Year'} = unpack("s", substr $blk,54,2) * $rain_mult;
+ $h{'Humidity_Out'} = unpack("C", substr $blk,33,1)+0;
+ $h{'Humidity_In'} = unpack("C", substr $blk,11,1)+0;
- $h{'ET_Day'} = unpack("s", substr $blk,56,2)/1000;
- $h{'ET_Month'} = unpack("s", substr $blk,58,2)/100;
- $h{'ET_Year'} = unpack("s", substr $blk,60,2)/100;
+ $t = unpack("C", substr $blk,43,1)+0;
+ $h{'UV'} = $t unless $t >= 255;
+ $t = unpack("s", substr $blk,44,2)+0; # watt/m**2
+ $h{'Solar'} = $t unless $t >= 32767;
- #$h{'Alarms_Inside'} = unpack("b8", substr $blk,70,1);
- #$h{'Alarms_Rain'} = unpack("b8", substr $blk,70,1);
- #$h{'Alarms_Outside'} = unpack("b8", substr $blk,70,1);
+ $h{'Rain_Rate'} = sprintf("%0.1f",unpack("s", substr $blk,41,2) * $rain_mult)+0;
+ $h{'Rain_Day'} = sprintf("%0.1f", unpack("s", substr $blk,50,2) * $rain_mult)+0;
- $h{'Batt_TX_OK'} = (unpack("C", substr $blk,86,1)+0) ^ 1;
- $h{'Batt_Console'} = unpack("s", substr $blk,87,2) * 0.005859375;
+ # what sort of packet is it?
- $h{'Forecast_Icon'} = unpack("C", substr $blk,89,1);
- $h{'Forecast_Rule'} = unpack("C", substr $blk,90,1);
+ $t = unpack("C", substr $blk,4,1);
+ if ($t) {
- $h{'Sunrise'} = sprintf( "%04d", unpack("S", substr $blk,91,2) );
- $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/;
+ # Newer LOOP2 packet
+ $t = unpack("C", substr $blk,18,2);
+ $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;
+ $t = unpack("C", substr $blk,22,2);
+ $h{Wind_Gust_10} = sprintf("%.1f",mph2mps($t/10))+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;
- #my $nl = ord substr $blk,95,1;
- #my $cr = ord substr $blk,96,1;
+ } else {
+
+ # Older LOOP packet
+ $t = unpack("C", substr $blk,15,1);
+ $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;
+ $h{'Rain_Year'} = sprintf("%0.1f", unpack("s", substr $blk,54,2) * $rain_mult)+0;
+
+
+ $h{'Batt_TX_OK'} = (unpack("C", substr $blk,86,1)+0) ^ 1;
+ $h{'Batt_Console'} = sprintf("%0.2f", unpack("s", substr $blk,87,2) * 0.005859375)+0;
+ $h{'Forecast_Icon'} = unpack("C", substr $blk,89,1);
+ $h{'Forecast_Rule'} = unpack("C", substr $blk,90,1);
+
+ $h{'Sunrise'} = sprintf( "%04d", unpack("S", substr $blk,91,2) );
+ $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/;
+ }
my $crc = unpack "%n", substr($blk,97,2);
my $crc_calc = CRC_CCITT($blk);
if ($crc_calc==0) {
my $o = gen_hash_diff($last_reading, \%h);
$last_reading = \%h;
- if (time % 60 == 0) {
- my $oo = {t => time, r =>\%h};
- say encode_json($oo);
+ my $t = time;
+ my $j;
+ my $s;
+ if ($t >= $last_time + 60) {
+ $j = encode_json(\%h);
+ $s = qq|{"t":$t,"m":$j}|;
+ $last_time = $t;
} elsif ($o) {
- my $oo = {t => time, r =>$o};
- say encode_json($oo);
+ $j = encode_json($o);
+ $s = qq|{"t":$t,"r":$j}|;
+ }
+ if ($s) {
+ say $s;
+ $dlog->writenow($s);
}
} else {
say "CRC check failed for LOOP data!";
return 1;
}
- #delete @h{'crc', 'crc_calc', 'next_rec'};
- #delete($h{crc})||die"cant delete crc";
- #delete($h{crc_calc})||die"cant delete crc_calc";
- #delete($h{next_rec})||die"cant delete next_rec";
}
sub gen_hash_diff
# Accurate to 1 degree C for humidities > 50 %
# http://en.wikipedia.org/wiki/Dew_point
- my $dew_point = $temp - ( (100 - $rh)/5 );
+ my $dewpoint = $temp - ((100 - $rh) / 5);
+
+ # this is the more complete one (which doesn't work)
+ #my $a = 6.1121;
+ #my $b = 18.678;
+ #my $c = 257.14;
+ #my $ytrh = log(($rh/100) + ($b * $temp) / ($c + $temp));
+ #my $dewpoint = ($c * $ytrh) / ($b - $ytrh);
- return $dew_point;
+ return $dewpoint;
}
sub CRC_CCITT
return $crc;
}
+sub f2c
+{
+ return ($_[0] - 32) * 5/9;
+}
+
+sub mph2mps
+{
+ return $_[0] * 0.44704;
+}
+
+sub in2mb
+{
+ return $_[0] * 33.8637526;
+}