Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixed to work with newer MH and perl5. Added trending of barom the wm2 d... #369

Merged
merged 5 commits into from
Mar 27, 2014
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 130 additions & 11 deletions lib/Weather_daviswm2.pm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package Weather_daviswm2;
# $Date$
# $Revision$

use Tie::IxHash;
use strict;
use Weather_Common;
eval 'use Digest::mhCRC qw(crc16);';
Expand All @@ -20,6 +21,43 @@ for the Davis Weather Monitor II weather stations.
Matt Williams reworked it to interface correctly with mh and to make it a module
Jack Edin was heavily involved in testing and was the impedus behind the creation of this module.

1/27/2014
Sean Mathews <coder at f34r dot com>

sponsored by a close friend and fellow maker Jack Edin 1961-2012 RIP
Movie nights and project days will be missed.

added barometric tendency calculation. The wm2 has a visual indicator of the barometric trend but
it can not be accessed via the serial port protocol.

the barometric tendency indications based upon a given change over a one hour period.
http://www.erh.noaa.gov/box/glossary.htm
"Rising Rapidly" is indicated if the pressure increases > 2 mb (0.06")
"Rising Slowly" is indicated if the pressure increases >1 mb but < 2 mb (> 0.02" but < 0.06")
"Steady" is indicated if the pressure changes < 1 mb (< 0.02")
"Falling Slowly" is indicated if the pressure falls > 1 mb but < 2 mb (> 0.02" but < 0.06")
"Falling Rapidly" is indicated when the pressure decreases > 2 mb (>0.06")
"Unsteady" unknown lack of samples or last sample fluctuated by 0.03 or more

in order to still get some trends before I have a long enough sample time I have opted to use this
psudo code.
collect a sample and add to fifo array
expire any samples older than 1 hours from the sample we just took
if last > 0 and deviation from last > .03" ( last is 0 on startup )
report "Unsteady"
else
if the sample array has a minimum of 10 samples
find average oldest(head) 5 samples for oldest barom
find average newest(tail) 5 samples for current barom
report indicator based upon this calculation above
else
report ""






Note: You must enable this module by setting the following parameters in mh{.private}.ini.
Obviously you must point the port to the actual port to which the station is connected.
serial_daviswm2_port=COM10
Expand All @@ -33,13 +71,18 @@ our $loopCommand = join "", "LOOP", chr(255), chr(255), chr(13);
our $DavisWMII_port;
our $lastRainReading = undef;
our $lastRainReadingTime = undef;
my $barom_tendency = "";
my %barom_samples = undef;
my $barom_samples = undef;

$barom_samples = tie %barom_samples, 'Tie::IxHash';

sub startup{
my ($instance)=@_;
$DavisWMII_port = new Serial_Item(undef, undef, 'serial_daviswm2');
&requestData;
&::MainLoop_pre_add_hook(\&Weather_daviswm2::update,1);
&::trigger_set('&new_minute','&Weather_daviswm2::requestData','NoExpire','daviswm2 data request')
&::trigger_set('new_minute(1)','&Weather_daviswm2::requestData','NoExpire','daviswm2 data request')
unless &::trigger_get('daviswm2 data request');
}

Expand Down Expand Up @@ -93,7 +136,7 @@ sub process{
my @data = unpack('C*',$data);
my $gotheader = 0;

if ($::Debug{Weather}) {
if ($::Debug{weather}) {
my $debugInfo='daviswm2: Read from Davis WM II ';
for (@data) {
$debugInfo .= sprintf ("0x%x ",$_);
Expand All @@ -118,15 +161,15 @@ sub process{
$rain_rate);

# go through data until we have found a header
&::print_log ("daviswm2: looking for header") if $::Debug{Weather};
&::print_log ("daviswm2: looking for header") if $::Debug{weather};
my $headerByte;
while (defined($headerByte=shift(@data))) {
next if $headerByte != 1; # need a 1 at start of data
&::print_log ("daviswm2: found header, checking length and crc16 of remaining data") if $::Debug{Weather};
&::print_log ("daviswm2: found header, checking length and crc16 of remaining data") if $::Debug{weather};
$data=pack('C*',@data);
if (length($data) < 17) { # we need 17 bytes left to proceed
&::print_log("daviswm2: not enough bytes left to process") if $::Debug{Weather};
return $headerByte.$data; # need to return the header byte as well
&::print_log("daviswm2: not enough bytes left to process") if $::Debug{weather};
return chr($headerByte).$data; # need to return the header byte as well
}
($indoor_temp,
$outdoor_temp,
Expand All @@ -139,7 +182,7 @@ sub process{
$not_used,
$crc16)=unpack('vvCvvCCvvn', $data);
if (Digest::mhCRC::crc16(substr($data,0,15)) != $crc16) {
&::print_log ("daviswm2: wrong crc16, looking again for header") if $::Debug{Weather};
&::print_log ("daviswm2: wrong crc16, looking again for header") if $::Debug{weather};
next;
}
# remove the 17 bytes that we just processed, we'll use the remainder as our return value
Expand All @@ -149,20 +192,94 @@ sub process{

# return because we didn't find a header :-(
if ($headerByte != 1) {
&::print_log ("daviswm2: ran out of bytes and didn't find a header") if $::Debug{Weather};
&::print_log ("daviswm2: ran out of bytes and didn't find a header") if $::Debug{weather};
# don't use $data as return value as it only has a valid
# value if a good header/packet is found
return '';
}

&::print_log ("daviswm2: found a header with the right checksum") if $::Debug{Weather};
&::print_log ("daviswm2: found a header with the right checksum") if $::Debug{weather};

# correct reading from reported to actual (just moving the decimal point)
$indoor_temp/=10.0;
$outdoor_temp/=10.0;
$barometer/=1000.0;
$total_rain/=10.0;


# barometric trend analysis
my $btr_current_sample_time = time;

## save our barometric reading
$barom_samples{$btr_current_sample_time} = $barometer;

&::print_log ("daviswm2: barometric samples") if $::Debug{weather};

## do the analysis on our dataset
my $btr_tmp_counter = 0;
my $btr_sum_head = 0.0;
my $btr_sum_tail = 0.0;
my ( $btr_datetime, $btr_barom , $btr_exflag, @btr_expire_list );
while (( $btr_datetime, $btr_barom ) = each %barom_samples ) {

# If the sample is older then 1 hour add to our remove list
my $datediff = $btr_current_sample_time - $btr_datetime;
if ( $datediff > 3600 ) { # 3600s = 1 hour
push ( @btr_expire_list, $btr_datetime );
$btr_exflag = "*" if $::Debug{weather};
} else {
$btr_exflag = " " if $::Debug{weather};
}
if ( $barom_samples->Length >= 10 ) {
if ( $btr_tmp_counter < 5 ) {
$btr_sum_head += $btr_barom;
$btr_exflag .= "T" if $::Debug{weather};
} else {
if ( $btr_tmp_counter >= $barom_samples->Length - 5 ) {
$btr_sum_tail += $btr_barom;
$btr_exflag .= "H" if $::Debug{weather};
}
}
}
if ( $::Debug{weather} ) {
&::print_log ("daviswm2: " . localtime($btr_datetime) . " -> $btr_barom $btr_exflag $datediff" );
}
$btr_tmp_counter++;
}

## calculate our average over 5 samples
$btr_sum_head /= 5.0;
$btr_sum_tail /= 5.0;

## calculate our difference
my $btr_diff = $btr_sum_tail - $btr_sum_head;

## fetch last sample
my $btr_last_diff = abs($barometer - $barom_samples->Values( $barom_samples->Length - 2 ));
my $btr_last_value = $barom_samples->Values( $barom_samples->Length - 2 );

&::print_log ("daviswm2: last value($btr_last_value) diff($btr_last_diff)" ) if $::Debug{weather};

## calculate tendency
if ( $btr_last_diff >= .03 or $barom_samples->Length < 15 ) {
&::print_log ("daviswm2: unsteading reading $btr_last_diff $btr_last_value" ) if $::Debug{weather};
$barom_tendency = "unsteady";
} else {
$barom_tendency = "rising rapidly" if $btr_diff > 0.06;
$barom_tendency = "rising slowly" if $btr_diff > 0.02 and $btr_diff < 0.06;
$barom_tendency = "steady" if abs($btr_diff) < 0.02;
$barom_tendency = "falling rapidly" if $btr_diff < -0.06;
$barom_tendency = "falling slowly" if $btr_diff < -0.02 and $btr_diff > -0.06;
}

&::print_log ("daviswm2: head($btr_sum_head) tail($btr_sum_tail)") if $::Debug{weather};

## remove expired values
foreach ( @btr_expire_list ) {
$barom_samples->DELETE($_);
}


# calculate sea level pressure
my $barometer_sea=convert_local_barom_to_sea_in($barometer);

Expand Down Expand Up @@ -241,8 +358,9 @@ sub process{
$$wptr{HumidOutdoor}=$outdoor_humidity;
$$wptr{RainTotal}=$total_rain;
$$wptr{RainRate}=$rain_rate;

if ($::Debug{Weather}) {
$$wptr{BaromDelta}=$barom_tendency;

if ($::Debug{weather}) {
foreach my $key qw(
TempIndoor
TempOutdoor
Expand All @@ -252,6 +370,7 @@ sub process{
WindAvgDir
Barom
BaromSea
BaromDelta
HumidIndoor
HumidOutdoor
RainTotal
Expand Down