mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-04-19 18:56:03 +00:00
14_SD_WS09.pm: updated module
WH2315 support added git-svn-id: https://svn.fhem.de/fhem/trunk@21622 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
4899d4ba0d
commit
609796307d
@ -1,5 +1,7 @@
|
|||||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||||
# Do not insert empty lines here, update check depends on it.
|
# Do not insert empty lines here, update check depends on it.
|
||||||
|
- bugfix: 14_SD_WS_09.pm: WindDirAverage
|
||||||
|
- feature: 14_SD_WS_09.pm: support for WH2315
|
||||||
- feature: 14_SD_UT.pm
|
- feature: 14_SD_UT.pm
|
||||||
new model Novy_840039
|
new model Novy_840039
|
||||||
new remote control xavax 00111939
|
new remote control xavax 00111939
|
||||||
|
@ -3,25 +3,30 @@
|
|||||||
#
|
#
|
||||||
# The purpose of this module is to support serval
|
# The purpose of this module is to support serval
|
||||||
# weather sensors like WS-0101 (Sender 868MHz ASK Epmfänger RX868SH-DV elv)
|
# weather sensors like WS-0101 (Sender 868MHz ASK Epmfänger RX868SH-DV elv)
|
||||||
# Sidey79 & pejonp 2015
|
|
||||||
#
|
#
|
||||||
# 22.09.2017: rainTotal --> rain_total
|
# 2015 Sidey79, pejonp
|
||||||
# 23.09.2017: windDirAverage SabineT https://forum.fhem.de/index.php/topic,75225.msg669950.html#msg669950
|
# 2019 Ralf9
|
||||||
|
# 2020 Sidey79, HomeAutoUser
|
||||||
#
|
#
|
||||||
|
# 20170922: rainTotal --> rain_total
|
||||||
|
# 20170923: windDirAverage - https://forum.fhem.de/index.php/topic,75225.msg669950.html#msg669950 @SabineT
|
||||||
|
# 20191003: UV/Solar Nachrichten WH2315 - https://forum.fhem.de/index.php/topic,67587.msg980092.html#msg980092 @Ralf
|
||||||
|
# 20200126: PERL WARNING - https://forum.fhem.de/index.php/topic,67587.msg982425.html#msg982425 @rob
|
||||||
|
# 20200127: Corrected line indents @HomeAutoUser
|
||||||
|
# 20200127: fix, WindDirAverage return undef --> return $windDirection_old @HomeAutoUser
|
||||||
|
# 20200127: revised commandref @HomeAutoUser
|
||||||
#
|
#
|
||||||
|
|
||||||
package main;
|
package main;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
#use Math::Round qw/nearest/;
|
|
||||||
|
|
||||||
# werden benötigt, aber im Programm noch extra abgetestet
|
# werden benötigt, aber im Programm noch extra abgetestet
|
||||||
#use Digest::CRC qw(crc);
|
#use Digest::CRC qw(crc);
|
||||||
#use Math::Trig;
|
#use Math::Trig;
|
||||||
|
|
||||||
sub SD_WS09_Initialize($)
|
sub SD_WS09_Initialize($) {
|
||||||
{
|
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
|
|
||||||
$hash->{Match} = "^P9#F[A-Fa-f0-9]+"; ## pos 7 ist aktuell immer 0xF
|
$hash->{Match} = "^P9#F[A-Fa-f0-9]+"; ## pos 7 ist aktuell immer 0xF
|
||||||
@ -39,18 +44,14 @@
|
|||||||
."$readingFnAttributes ";
|
."$readingFnAttributes ";
|
||||||
$hash->{AutoCreate} =
|
$hash->{AutoCreate} =
|
||||||
{ "SD_WS09.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.* windKorrektur:.*:0 verbose:5" , FILTER => "%NAME", GPLOT => "WH1080wind4:windSpeed/windGust,", autocreateThreshold => "2:180"} };
|
{ "SD_WS09.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.* windKorrektur:.*:0 verbose:5" , FILTER => "%NAME", GPLOT => "WH1080wind4:windSpeed/windGust,", autocreateThreshold => "2:180"} };
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#############################
|
#############################
|
||||||
sub SD_WS09_Define($$)
|
sub SD_WS09_Define($$) {
|
||||||
{
|
|
||||||
my ($hash, $def) = @_;
|
my ($hash, $def) = @_;
|
||||||
my @a = split("[ \t][ \t]*", $def);
|
my @a = split("[ \t][ \t]*", $def);
|
||||||
|
|
||||||
return "wrong syntax: define <name> SD_WS09 <code> ".int(@a)
|
return "wrong syntax: define <name> SD_WS09 <code> ".int(@a) if(int(@a) < 3 );
|
||||||
if(int(@a) < 3 );
|
|
||||||
|
|
||||||
$hash->{CODE} = $a[2];
|
$hash->{CODE} = $a[2];
|
||||||
$hash->{lastMSG} = "";
|
$hash->{lastMSG} = "";
|
||||||
@ -68,19 +69,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
sub SD_WS09_Undef($$)
|
sub SD_WS09_Undef($$) {
|
||||||
{
|
|
||||||
my ($hash, $name) = @_;
|
my ($hash, $name) = @_;
|
||||||
|
|
||||||
delete($modules{SD_WS09}{defptr}{$hash->{CODE}})
|
delete($modules{SD_WS09}{defptr}{$hash->{CODE}})
|
||||||
if(defined($hash->{CODE}) &&
|
if(defined($hash->{CODE}) &&
|
||||||
defined($modules{SD_WS09}{defptr}{$hash->{CODE}}));
|
defined($modules{SD_WS09}{defptr}{$hash->{CODE}}));
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
###################################
|
###################################
|
||||||
sub SD_WS09_Parse($$)
|
sub SD_WS09_Parse($$) {
|
||||||
{
|
|
||||||
my ($iohash, $msg) = @_;
|
my ($iohash, $msg) = @_;
|
||||||
my $name = $iohash->{NAME};
|
my $name = $iohash->{NAME};
|
||||||
my (undef ,$rawData) = split("#",$msg);
|
my (undef ,$rawData) = split("#",$msg);
|
||||||
@ -96,13 +95,13 @@
|
|||||||
my $deviceCode = 0;
|
my $deviceCode = 0;
|
||||||
my $model = "undef"; # 0xFFA -> WS0101/WH1080 alles andere -> CTW600
|
my $model = "undef"; # 0xFFA -> WS0101/WH1080 alles andere -> CTW600
|
||||||
my $modelid;
|
my $modelid;
|
||||||
my $windSpeed;
|
my $windSpeed = 0;
|
||||||
my $windSpeed_kmh;
|
my $windSpeed_kmh;
|
||||||
my $windSpeed_fts;
|
my $windSpeed_fts;
|
||||||
my $windSpeed_bft;
|
my $windSpeed_bft;
|
||||||
my $windSpeed_mph;
|
my $windSpeed_mph;
|
||||||
my $windSpeed_kn;
|
my $windSpeed_kn;
|
||||||
my $windguest;
|
my $windguest = 0;
|
||||||
my $windguest_kmh;
|
my $windguest_kmh;
|
||||||
my $windguest_fts;
|
my $windguest_fts;
|
||||||
my $windguest_bft;
|
my $windguest_bft;
|
||||||
@ -128,15 +127,33 @@
|
|||||||
my $rawData_merk;
|
my $rawData_merk;
|
||||||
my $wfaktor = 1;
|
my $wfaktor = 1;
|
||||||
my @windstat;
|
my @windstat;
|
||||||
|
my $syncpos;
|
||||||
|
|
||||||
my $syncpos= index($bitData,"11111110"); #7x1 1x0 preamble
|
if ($hlen < 20) { # WH3080 UV/Solar
|
||||||
|
$syncpos = index($bitData,"1111110111"); # FF7 UV/Solar
|
||||||
|
if ($syncpos >= 0 && $syncpos < 3) {
|
||||||
|
$model = "WH1080";
|
||||||
|
if ($syncpos < 2) {
|
||||||
|
$rawData = SD_WS09_SHIFT($iohash, $rawData);
|
||||||
|
Log3 $iohash, 4, "$name: SD_WS09_Parse_SHIFT_0 raw:$rawData";
|
||||||
|
}
|
||||||
|
if ($syncpos == 0) {
|
||||||
|
$rawData = SD_WS09_SHIFT($iohash, $rawData);
|
||||||
|
Log3 $iohash, 4, "$name: SD_WS09_Parse_SHIFT_1 raw:$rawData";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log3 $iohash, 4, "$name: SD_WS09_Parse WH1080 EXIT (sync no found): msg=$rawData length:".length($bitData);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$syncpos= index($bitData,"11111110"); #7x1 1x0 preamble
|
||||||
Log3 $iohash, 4, "$name: SD_WS09_Parse0 msg=$rawData Bin=$bitData syncp=$syncpos length:".length($bitData) ;
|
Log3 $iohash, 4, "$name: SD_WS09_Parse0 msg=$rawData Bin=$bitData syncp=$syncpos length:".length($bitData) ;
|
||||||
|
|
||||||
if ($syncpos ==-1 || length($bitData)-$syncpos < $minL2)
|
if ($syncpos ==-1 || length($bitData)-$syncpos < $minL2) {
|
||||||
{
|
|
||||||
Log3 $iohash, 4, "$name: SD_WS09_Parse EXIT: msg=$rawData syncp=$syncpos length:".length($bitData) ;
|
Log3 $iohash, 4, "$name: SD_WS09_Parse EXIT: msg=$rawData syncp=$syncpos length:".length($bitData) ;
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
my $crcwh1080 = AttrVal($iohash->{NAME},'WS09_CRCAUS',0);
|
my $crcwh1080 = AttrVal($iohash->{NAME},'WS09_CRCAUS',0);
|
||||||
Log3 $iohash, 4, "$name: SD_WS09_Parse CRC_AUS:$crcwh1080 " ;
|
Log3 $iohash, 4, "$name: SD_WS09_Parse CRC_AUS:$crcwh1080 " ;
|
||||||
@ -149,42 +166,50 @@
|
|||||||
1;
|
1;
|
||||||
};
|
};
|
||||||
|
|
||||||
if($rc) # test ob Digest::CRC geladen wurde
|
# test ob Digest::CRC geladen
|
||||||
{
|
if($rc) {
|
||||||
$rr2 = SD_WS09_CRCCHECK($rawData);
|
$rr2 = SD_WS09_CRCCHECK($rawData);
|
||||||
|
if ($model eq "WH1080") { # FF7 UV/Solar
|
||||||
|
if ($rr2 != 0) {
|
||||||
|
Log3 $iohash, 4, "$name: SD_WS09_Parse WH1080: sensorTyp: 7 UV/Solar, CRC_Error Exit: raw:$rawData CRC=$rr2";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if ($rr2 == 0 || (($rr2 == 49) && ($crcwh1080 == 2)) ) {
|
if ($rr2 == 0 || (($rr2 == 49) && ($crcwh1080 == 2)) ) {
|
||||||
# 1. OK
|
# 1. OK
|
||||||
$model = "WH1080";
|
$model = "WH1080";
|
||||||
Log3 $iohash, 4, "$name: SD_WS09_SHIFT_0 OK rwa:$rawData" ;
|
Log3 $iohash, 4, "$name: SD_WS09_Parse_SHIFT_0 OK raw:$rawData crc:$rr2";
|
||||||
} else {
|
} else {
|
||||||
# 1. nok
|
# 1. nok
|
||||||
$rawData = SD_WS09_SHIFT($rawData);
|
Log3 $iohash, 4, "$name: SD_WS09_Parse_SHIFT_1 NOK raw:$rawData crc:$rr2 -> shift";
|
||||||
Log3 $iohash, 4, "$name: SD_WS09_SHIFT_1 NOK rwa:$rawData" ;
|
$rawData = SD_WS09_SHIFT($iohash, $rawData);
|
||||||
$rr2 = SD_WS09_CRCCHECK($rawData);
|
$rr2 = SD_WS09_CRCCHECK($rawData);
|
||||||
if ($rr2 == 0 || (($rr2 == 49) && ($crcwh1080 == 2)) ) {
|
if ($rr2 == 0 || (($rr2 == 49) && ($crcwh1080 == 2)) ) {
|
||||||
# 2.ok
|
# 2.ok
|
||||||
$msg = $msg_vor.$rawData;
|
$msg = $msg_vor.$rawData;
|
||||||
$model = "WH1080";
|
$model = "WH1080";
|
||||||
Log3 $iohash, 4, "$name: SD_WS09_SHIFT_2 OK rwa:$rawData msg:$msg" ;
|
Log3 $iohash, 4, "$name: SD_WS09_Parse_SHIFT_2 OK raw:$rawData msg:$msg crc:$rr2";
|
||||||
} else {
|
} else {
|
||||||
# 2. nok
|
# 2. nok
|
||||||
$rawData = SD_WS09_SHIFT($rawData);
|
Log3 $iohash, 4, "$name: SD_WS09_Parse_SHIFT_3 NOK raw:$rawData crc:$rr2 -> shift";
|
||||||
Log3 $iohash, 4, "$name: SD_WS09_SHIFT_3 NOK rwa:$rawData" ;
|
$rawData = SD_WS09_SHIFT($iohash, $rawData);
|
||||||
$rr2 = SD_WS09_CRCCHECK($rawData);
|
$rr2 = SD_WS09_CRCCHECK($rawData);
|
||||||
if ($rr2 == 0 || (($rr2 == 49) && ($crcwh1080 == 2)) ) {
|
if ($rr2 == 0 || (($rr2 == 49) && ($crcwh1080 == 2)) ) {
|
||||||
# 3. ok
|
# 3. ok
|
||||||
$msg = $msg_vor.$rawData;
|
$msg = $msg_vor.$rawData;
|
||||||
$model = "WH1080";
|
$model = "WH1080";
|
||||||
Log3 $iohash, 4, "$name: SD_WS09_SHIFT_4 OK rwa:$rawData msg:$msg" ;
|
Log3 $iohash, 4, "$name: SD_WS09_Parse_SHIFT_4 OK raw:$rawData msg:$msg crc:$rr2";
|
||||||
} else {
|
} else {
|
||||||
# 3. nok
|
# 3. nok
|
||||||
$rawData = $rawData_merk;
|
$rawData = $rawData_merk;
|
||||||
$msg = $msg_vor.$rawData;
|
$msg = $msg_vor.$rawData;
|
||||||
Log3 $iohash, 4, "$name: SD_WS09_SHIFT_5 NOK rwa:$rawData msg:$msg" ;
|
Log3 $iohash, 4, "$name: SD_WS09_Parse_SHIFT_5 NOK raw:$rawData msg:$msg crc:$rr2";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
# Digest::CRC failed
|
||||||
Log3 $iohash, 1, "$name: SD_WS09 CRC_not_load: Modul Digest::CRC fehlt: cpan install Digest::CRC or sudo apt-get install libdigest-crc-perl" ;
|
Log3 $iohash, 1, "$name: SD_WS09 CRC_not_load: Modul Digest::CRC fehlt: cpan install Digest::CRC or sudo apt-get install libdigest-crc-perl" ;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -197,8 +222,10 @@
|
|||||||
if( $model eq "WH1080") {
|
if( $model eq "WH1080") {
|
||||||
$sensdata = substr($bitData,8);
|
$sensdata = substr($bitData,8);
|
||||||
$whid = substr($sensdata,0,4);
|
$whid = substr($sensdata,0,4);
|
||||||
|
Log3 $iohash, 5, "$name: SD_WS09_Parse_0 whid=$whid";
|
||||||
|
|
||||||
if( $whid == "1010" ){ # A Wettermeldungen
|
# A Wettermeldungen
|
||||||
|
if( $whid == "1010" ){
|
||||||
Log3 $iohash, 4, "$name: SD_WS09_Parse_1 msg=$sensdata length:".length($sensdata) ;
|
Log3 $iohash, 4, "$name: SD_WS09_Parse_1 msg=$sensdata length:".length($sensdata) ;
|
||||||
$model = "WH1080";
|
$model = "WH1080";
|
||||||
$id = SD_WS09_bin2dec(substr($sensdata,4,8));
|
$id = SD_WS09_bin2dec(substr($sensdata,4,8));
|
||||||
@ -215,7 +242,9 @@
|
|||||||
$rain = SD_WS09_bin2dec(substr($sensdata,52,12)) * 0.3;
|
$rain = SD_WS09_bin2dec(substr($sensdata,52,12)) * 0.3;
|
||||||
Log3 $iohash, 4, "$name: SD_WS09_Parse_4 ".$model." id:$id, Rain bit: ".substr($sensdata,52,12)." Dec: " . $rain ;
|
Log3 $iohash, 4, "$name: SD_WS09_Parse_4 ".$model." id:$id, Rain bit: ".substr($sensdata,52,12)." Dec: " . $rain ;
|
||||||
Log3 $iohash, 4, "$name: SD_WS09_Parse_5 ".$model." id:$id, bat:$bat, temp=$temp, hum=$hum, winddir=$windDirection:$windDirectionText wS=$windSpeed, wG=$windguest, rain=$rain";
|
Log3 $iohash, 4, "$name: SD_WS09_Parse_5 ".$model." id:$id, bat:$bat, temp=$temp, hum=$hum, winddir=$windDirection:$windDirectionText wS=$windSpeed, wG=$windguest, rain=$rain";
|
||||||
} elsif( $whid == "1011" ){ # B DCF-77 Zeitmeldungen vom Sensor
|
|
||||||
|
# B DCF-77 Zeitmeldungen vom Sensor
|
||||||
|
} elsif ( $whid == "1011" ) {
|
||||||
my $hrs1 = substr($sensdata,16,8);
|
my $hrs1 = substr($sensdata,16,8);
|
||||||
my $hrs;
|
my $hrs;
|
||||||
my $mins;
|
my $mins;
|
||||||
@ -236,7 +265,9 @@
|
|||||||
Log3 $iohash, 4, "$name: SD_WS09_Parse_8 Zeitmeldung2: id:$id, HH:mm:ss - ".$hrs.":".$mins.":".$sec ;
|
Log3 $iohash, 4, "$name: SD_WS09_Parse_8 Zeitmeldung2: id:$id, HH:mm:ss - ".$hrs.":".$mins.":".$sec ;
|
||||||
Log3 $iohash, 4, "$name: SD_WS09_Parse_9 Zeitmeldung3: id:$id, dd.mm.yy - ".$mday.".".$month.".".$year ;
|
Log3 $iohash, 4, "$name: SD_WS09_Parse_9 Zeitmeldung3: id:$id, dd.mm.yy - ".$mday.".".$month.".".$year ;
|
||||||
return $name;
|
return $name;
|
||||||
} elsif( $whid == "0111" ){ # 7 UV/Solar Meldungen vom Sensor
|
|
||||||
|
# 7 UV/Solar Meldungen vom Sensor
|
||||||
|
} elsif ( $whid == "0111" ) {
|
||||||
# Fine Offset (Solar Data) message BYTE offsets (within receive buffer)
|
# Fine Offset (Solar Data) message BYTE offsets (within receive buffer)
|
||||||
# Examples= FF 75 B0 55 00 97 8E 0E *CRC*OK*
|
# Examples= FF 75 B0 55 00 97 8E 0E *CRC*OK*
|
||||||
# =FF 75 B0 55 00 8F BE 92 *CRC*OK*
|
# =FF 75 B0 55 00 8F BE 92 *CRC*OK*
|
||||||
@ -260,8 +291,7 @@
|
|||||||
# es wird eine CTW600 angenommen
|
# es wird eine CTW600 angenommen
|
||||||
$syncpos= index($bitData,"11111110"); #7x1 1x0 preamble
|
$syncpos= index($bitData,"11111110"); #7x1 1x0 preamble
|
||||||
$wh = substr($bitData,0,8);
|
$wh = substr($bitData,0,8);
|
||||||
if ( $wh == "11111110" && length($bitData) > $minL1 )
|
if ( $wh == "11111110" && length($bitData) > $minL1 ) {
|
||||||
{
|
|
||||||
Log3 $iohash, 4, "$name: SD_WS09_Parse_11 CTW600 EXIT: msg=$bitData wh:$wh length:".length($bitData) ;
|
Log3 $iohash, 4, "$name: SD_WS09_Parse_11 CTW600 EXIT: msg=$bitData wh:$wh length:".length($bitData) ;
|
||||||
$sensdata = substr($bitData,$syncpos+8);
|
$sensdata = substr($bitData,$syncpos+8);
|
||||||
Log3 $iohash, 4, "$name: SD_WS09_Parse_12 CTW WH=$wh msg=$sensdata syncp=$syncpos length:".length($sensdata) ;
|
Log3 $iohash, 4, "$name: SD_WS09_Parse_12 CTW WH=$wh msg=$sensdata syncp=$syncpos length:".length($sensdata) ;
|
||||||
@ -304,8 +334,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
my $longids = AttrVal($iohash->{NAME},'longids',0);
|
my $longids = AttrVal($iohash->{NAME},'longids',0);
|
||||||
if ( ($longids ne "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/)))
|
if ( ($longids ne "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/))) {
|
||||||
{
|
|
||||||
$deviceCode=$model."_".$id;
|
$deviceCode=$model."_".$id;
|
||||||
Log3 $iohash,4, "$name: SD_WS09_Parse using longid: $longids model: $model";
|
Log3 $iohash,4, "$name: SD_WS09_Parse using longid: $longids model: $model";
|
||||||
} else {
|
} else {
|
||||||
@ -324,8 +353,7 @@
|
|||||||
$name = $hash->{NAME};
|
$name = $hash->{NAME};
|
||||||
Log3 $name, 4, "SD_WS09_Parse_20: $name ($rawData)";
|
Log3 $name, 4, "SD_WS09_Parse_20: $name ($rawData)";
|
||||||
|
|
||||||
if (!defined(AttrVal($name,"event-min-interval",undef)))
|
if (!defined(AttrVal($name,"event-min-interval",undef))) {
|
||||||
{
|
|
||||||
my $minsecs = AttrVal($iohash->{NAME},'minsecs',0);
|
my $minsecs = AttrVal($iohash->{NAME},'minsecs',0);
|
||||||
if($hash->{lastReceive} && (time() - $hash->{lastReceive} < $minsecs)) {
|
if($hash->{lastReceive} && (time() - $hash->{lastReceive} < $minsecs)) {
|
||||||
Log3 $hash, 4, "SD_WS09_Parse_End $deviceCode Dropped due to short time. minsecs=$minsecs";
|
Log3 $hash, 4, "SD_WS09_Parse_End $deviceCode Dropped due to short time. minsecs=$minsecs";
|
||||||
@ -334,8 +362,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
my $windkorr = AttrVal($name,'windKorrektur',0);
|
my $windkorr = AttrVal($name,'windKorrektur',0);
|
||||||
if ($windkorr != 0 )
|
if ($windkorr != 0 ) {
|
||||||
{
|
|
||||||
my $oldwinddir = $windDirection;
|
my $oldwinddir = $windDirection;
|
||||||
$windDirection = $windDirection + $windkorr;
|
$windDirection = $windDirection + $windkorr;
|
||||||
$windDirectionText = $winddir_name[$windDirection];
|
$windDirectionText = $winddir_name[$windDirection];
|
||||||
@ -397,8 +424,7 @@
|
|||||||
$def->{lastMSG} = $rawData;
|
$def->{lastMSG} = $rawData;
|
||||||
readingsBeginUpdate($hash);
|
readingsBeginUpdate($hash);
|
||||||
|
|
||||||
if($whid ne "0111")
|
if($whid ne "0111") {
|
||||||
{
|
|
||||||
#my $uowind = AttrVal($hash->{NAME},'Unit_of_Wind',0) ;
|
#my $uowind = AttrVal($hash->{NAME},'Unit_of_Wind',0) ;
|
||||||
my $uowind = AttrVal($name,'Unit_of_Wind',0) ;
|
my $uowind = AttrVal($name,'Unit_of_Wind',0) ;
|
||||||
my $windex = $uowind_index{$uowind};
|
my $windex = $uowind_index{$uowind};
|
||||||
@ -433,8 +459,8 @@
|
|||||||
readingsBulkUpdate($hash, "windDirectionDegree", $windDirectionDegree);
|
readingsBulkUpdate($hash, "windDirectionDegree", $windDirectionDegree);
|
||||||
readingsBulkUpdate($hash, "windDirectionText", $windDirectionText );
|
readingsBulkUpdate($hash, "windDirectionText", $windDirectionText );
|
||||||
}
|
}
|
||||||
if(($whid eq "0111") && ($model eq "WH1080"))
|
|
||||||
{
|
if (($whid eq "0111") && ($model eq "WH1080")) {
|
||||||
$state = "UV: $FOuvo Lux: $FOlux ";
|
$state = "UV: $FOuvo Lux: $FOlux ";
|
||||||
readingsBulkUpdate($hash, "id", $id) if ($id ne "");
|
readingsBulkUpdate($hash, "id", $id) if ($id ne "");
|
||||||
readingsBulkUpdate($hash, "state", $state);
|
readingsBulkUpdate($hash, "state", $state);
|
||||||
@ -442,13 +468,13 @@
|
|||||||
readingsBulkUpdate($hash, "UV", $FOuvo );
|
readingsBulkUpdate($hash, "UV", $FOuvo );
|
||||||
readingsBulkUpdate($hash, "Lux", $FOlux );
|
readingsBulkUpdate($hash, "Lux", $FOlux );
|
||||||
}
|
}
|
||||||
readingsEndUpdate($hash, 1); # Notify is done by Dispatch
|
|
||||||
|
|
||||||
|
readingsEndUpdate($hash, 1); # Notify is done by Dispatch
|
||||||
return $name;
|
return $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub SD_WS09_Attr(@)
|
###################################
|
||||||
{
|
sub SD_WS09_Attr(@) {
|
||||||
my @a = @_;
|
my @a = @_;
|
||||||
# Make possible to use the same code for different logical devices when they
|
# Make possible to use the same code for different logical devices when they
|
||||||
# are received through different physical devices.
|
# are received through different physical devices.
|
||||||
@ -461,6 +487,7 @@
|
|||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
sub SD_WS09_WindDirAverage($$$){
|
sub SD_WS09_WindDirAverage($$$){
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# übernommen von SabineT https://forum.fhem.de/index.php/topic,75225.msg669950.html#msg669950
|
# übernommen von SabineT https://forum.fhem.de/index.php/topic,75225.msg669950.html#msg669950
|
||||||
@ -488,6 +515,7 @@
|
|||||||
my ($hash, $ws, $wd) = @_;
|
my ($hash, $ws, $wd) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
Log3 $hash, 4, "SD_WS09_WindDirAverage --- OK ----" ;
|
Log3 $hash, 4, "SD_WS09_WindDirAverage --- OK ----" ;
|
||||||
|
|
||||||
my $rc = eval
|
my $rc = eval
|
||||||
{
|
{
|
||||||
require Math::Trig;
|
require Math::Trig;
|
||||||
@ -498,8 +526,7 @@
|
|||||||
if($rc) # test ob Math::Trig geladen wurde
|
if($rc) # test ob Math::Trig geladen wurde
|
||||||
{
|
{
|
||||||
Log3 $hash, 4, "SD_WS09_WindDirAverage Math::Trig:OK" ;
|
Log3 $hash, 4, "SD_WS09_WindDirAverage Math::Trig:OK" ;
|
||||||
}else
|
} else {
|
||||||
{
|
|
||||||
Log3 $hash, 1, "SD_WS09_WindDirAverage Math::Trig:fehlt : cpan install Math::Trig" ;
|
Log3 $hash, 1, "SD_WS09_WindDirAverage Math::Trig:fehlt : cpan install Math::Trig" ;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -507,6 +534,7 @@
|
|||||||
my $avtime = AttrVal($name,'WindDirAverageTime',0);
|
my $avtime = AttrVal($name,'WindDirAverageTime',0);
|
||||||
my $decay = AttrVal($name,'WindDirAverageDecay',0);
|
my $decay = AttrVal($name,'WindDirAverageDecay',0);
|
||||||
my $minspeed = AttrVal($name,'WindDirAverageMinSpeed',0);
|
my $minspeed = AttrVal($name,'WindDirAverageMinSpeed',0);
|
||||||
|
my $windDirection_old = $wd;
|
||||||
|
|
||||||
# default Werte für die optionalen Parameter, falls nicht beim Aufruf mit angegeben
|
# default Werte für die optionalen Parameter, falls nicht beim Aufruf mit angegeben
|
||||||
$avtime = 600 if (!(defined $avtime) || $avtime == 0 );
|
$avtime = 600 if (!(defined $avtime) || $avtime == 0 );
|
||||||
@ -554,9 +582,10 @@
|
|||||||
Log3 $hash,4,"SD_WS09_WindDirAverage_06 $name :Speed=".$ws." Dir=".round($wd,2)." Time=".$time." minspeed=".$minspeed." num=".$num;
|
Log3 $hash,4,"SD_WS09_WindDirAverage_06 $name :Speed=".$ws." Dir=".round($wd,2)." Time=".$time." minspeed=".$minspeed." num=".$num;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return undef;
|
return $windDirection_old; # old undef | different behavior dispatch <-> UnitTest´s ($ctime - $ltime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#-- output and average
|
#-- output and average
|
||||||
my ($anz, $sanz) = 0;
|
my ($anz, $sanz) = 0;
|
||||||
$num = int(@{$hash->{helper}{history}});
|
$num = int(@{$hash->{helper}{history}});
|
||||||
@ -586,22 +615,24 @@
|
|||||||
}
|
}
|
||||||
my $average = int((rad2deg(atan2($sumSin, $sumCos)) + 360) % 360);
|
my $average = int((rad2deg(atan2($sumSin, $sumCos)) + 360) % 360);
|
||||||
Log3 $hash,4,"SD_WS09_WindDirAverage_09 $name Mittelwert über $anz Werte ist $average, avspeed=".round($sumSpeed/$num,1) if ($num > 0);
|
Log3 $hash,4,"SD_WS09_WindDirAverage_09 $name Mittelwert über $anz Werte ist $average, avspeed=".round($sumSpeed/$num,1) if ($num > 0);
|
||||||
|
|
||||||
#-- undef zurückliefern, wenn die durchschnittliche Geschwindigkeit zu gering oder gar keine Werte verfügbar
|
#-- undef zurückliefern, wenn die durchschnittliche Geschwindigkeit zu gering oder gar keine Werte verfügbar
|
||||||
return undef if (($anz == 0) || ($sanz == 0));
|
return undef if (($anz == 0) || ($sanz == 0));
|
||||||
return undef if (($sumSpeed / $sanz) < $minspeed);
|
return undef if (($sumSpeed / $sanz) < $minspeed);
|
||||||
|
|
||||||
Log3 $hash,4,"SD_WS09_WindDirAverage_END $name Mittelwert=$average";
|
Log3 $hash,4,"SD_WS09_WindDirAverage_END $name Mittelwert=$average";
|
||||||
return $average;
|
return $average;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub SD_WS09_bin2dec($)
|
###################################
|
||||||
{
|
sub SD_WS09_bin2dec($) {
|
||||||
my $h = shift;
|
my $h = shift;
|
||||||
my $int = unpack("N", pack("B32",substr("0" x 32 . $h, -32)));
|
my $int = unpack("N", pack("B32",substr("0" x 32 . $h, -32)));
|
||||||
return sprintf("%d", $int);
|
return sprintf("%d", $int);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub SD_WS09_binflip($)
|
###################################
|
||||||
{
|
sub SD_WS09_binflip($) {
|
||||||
my $h = shift;
|
my $h = shift;
|
||||||
my $hlen = length($h);
|
my $hlen = length($h);
|
||||||
my $i = 0;
|
my $i = 0;
|
||||||
@ -613,6 +644,7 @@
|
|||||||
return $flip;
|
return $flip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
sub SD_WS09_BCD2bin($) {
|
sub SD_WS09_BCD2bin($) {
|
||||||
my $binary = shift;
|
my $binary = shift;
|
||||||
my $int = unpack("N", pack("B32", substr("0" x 32 . $binary, -32)));
|
my $int = unpack("N", pack("B32", substr("0" x 32 . $binary, -32)));
|
||||||
@ -620,22 +652,25 @@
|
|||||||
return $BCD;
|
return $BCD;
|
||||||
}
|
}
|
||||||
|
|
||||||
sub SD_WS09_SHIFT($){
|
###################################
|
||||||
my $rawData = shift;
|
sub SD_WS09_SHIFT($$){
|
||||||
|
my ($hash, $rawData) = @_;
|
||||||
|
my $name = $hash->{NAME};
|
||||||
my $hlen = length($rawData);
|
my $hlen = length($rawData);
|
||||||
my $blen = $hlen * 4;
|
my $blen = $hlen * 4;
|
||||||
my $bitData = unpack("B$blen", pack("H$hlen", $rawData));
|
my $bitData = unpack("B$blen", pack("H$hlen", $rawData));
|
||||||
my $bitData2 = '1'.unpack("B$blen", pack("H$hlen", $rawData));
|
my $bitData2 = '1'.$bitData;
|
||||||
my $bitData20 = substr($bitData2,0,length($bitData2)-1);
|
my $bitData20 = substr($bitData2,0,length($bitData2)-1);
|
||||||
$blen = length($bitData20);
|
$blen = length($bitData20);
|
||||||
$hlen = $blen / 4;
|
$hlen = $blen / 4;
|
||||||
$rawData = uc(unpack("H$hlen", pack("B$blen", $bitData20)));
|
$rawData = uc(unpack("H$hlen", pack("B$blen", $bitData20)));
|
||||||
$bitData = $bitData20;
|
$bitData = $bitData20;
|
||||||
Log3 "SD_WS09_SHIFT", 4, "SD_WS09_SHIFT_0 raw: $rawData length:".length($bitData) ;
|
#Log3 $hash, 4, "$name: SD_WS09_SHIFT_0 raw: $rawData length:".length($bitData);
|
||||||
Log3 "SD_WS09_SHIFT", 4, "SD_WS09_SHIFT_1 bitdata: $bitData" ;
|
Log3 $hash, 5, "$name: SD_WS09_SHIFT_1 bitdata: $bitData length:".length($bitData);
|
||||||
return $rawData;
|
return $rawData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
###################################
|
||||||
sub SD_WS09_CRCCHECK($) {
|
sub SD_WS09_CRCCHECK($) {
|
||||||
my $rawData = shift;
|
my $rawData = shift;
|
||||||
my $datacheck1 = pack( 'H*', substr($rawData,2,length($rawData)-2) );
|
my $datacheck1 = pack( 'H*', substr($rawData,2,length($rawData)-2) );
|
||||||
@ -651,25 +686,27 @@
|
|||||||
|
|
||||||
=pod
|
=pod
|
||||||
=item summary Supports weather sensors (WH1080/3080/CTW-600) protocl 9 from SIGNALduino
|
=item summary Supports weather sensors (WH1080/3080/CTW-600) protocl 9 from SIGNALduino
|
||||||
=item summary_DE Unterstuetzt Wettersensoren (WH1080/3080/CTW-600) mit Protokol 9 vom SIGNALduino
|
=item summary_DE Unterstuetzt Wettersensoren (WH1080/3080/CTW-600) / Protokol 9 vom SIGNALduino
|
||||||
=begin html
|
=begin html
|
||||||
|
|
||||||
<a name="SD_WS09"></a>
|
<a name="SD_WS09"></a>
|
||||||
<h3>Wether Sensors protocol #9</h3>
|
<h3>Wether Sensors protocol #9</h3>
|
||||||
<ul>
|
<ul>
|
||||||
The SD_WS09 module interprets temperature sensor messages received by a Device like CUL, CUN, SIGNALduino etc.<br>
|
The SD_WS09 module interprets temperature sensor messages received by a Device like CUL, CUN, SIGNALduino etc.<br><br>
|
||||||
Requires Perl-Modul Digest::CRC. <br>
|
Requires Perl-Modul Digest::CRC / Math::Trig <br>
|
||||||
<br>
|
<ul>
|
||||||
cpan install Digest::CRC or sudo apt-get install libdigest-crc-perl <br>
|
<li>cpan install Digest::CRC or <br>
|
||||||
<br>
|
sudo apt-get install libdigest-crc-perl </li>
|
||||||
|
<li>cpan install Math::Trig </li></ul><br>
|
||||||
<br>
|
<br>
|
||||||
<b>Known models:</b>
|
<b>Known models:</b>
|
||||||
<ul>
|
<ul>
|
||||||
<li>WS-0101 --> Model: WH1080</li>
|
<li>WS-0101 --> Model: WH1080</li>
|
||||||
<li>TFA 30.3189 / WH1080 --> Model: WH1080</li>
|
<li>TFA 30.3189 / WH1080 --> Model: WH1080</li>
|
||||||
<li>1073 (WS1080) --> Model: WH1080</li>
|
<li>1073 (WS1080) --> Model: WH1080</li>
|
||||||
|
<li>WH2315 --> Model: WH1080</li>
|
||||||
<li>WH3080 --> Model: WH1080</li>
|
<li>WH3080 --> Model: WH1080</li>
|
||||||
<li>CTW600 --> Model: CTW600 (??) </li>
|
<li>CTW600 --> Model: CTW600</li>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
New received device are add in fhem with autocreate.
|
New received device are add in fhem with autocreate.
|
||||||
@ -751,8 +788,8 @@
|
|||||||
<li>windDirectionAverage<br>
|
<li>windDirectionAverage<br>
|
||||||
As a result, the wind direction is returned, which are calculated from the current and past values
|
As a result, the wind direction is returned, which are calculated from the current and past values
|
||||||
via a kind of exponential mean value.
|
via a kind of exponential mean value.
|
||||||
The respective wind speed is additionally taken into account (higher speed means higher weighting)</li>
|
The respective wind speed is additionally taken into account (higher speed means higher weighting)</li><br>
|
||||||
<b>WH3080:</b>
|
<b>WH2315 / WH3080:</b>
|
||||||
<li>UV Index</li>
|
<li>UV Index</li>
|
||||||
<li>Lux</li>
|
<li>Lux</li>
|
||||||
|
|
||||||
@ -767,17 +804,18 @@
|
|||||||
<ul>
|
<ul>
|
||||||
Das SD_WS09 Module verarbeitet von einem IO Gerät (CUL, CUN, SIGNALDuino, etc.) empfangene Nachrichten von Temperatur-Sensoren.<br>
|
Das SD_WS09 Module verarbeitet von einem IO Gerät (CUL, CUN, SIGNALDuino, etc.) empfangene Nachrichten von Temperatur-Sensoren.<br>
|
||||||
<br>
|
<br>
|
||||||
Perl-Modul Digest::CRC erforderlich. <br>
|
Perl-Module Digest::CRC / Math::Trig erforderlich. <br>
|
||||||
|
<ul>
|
||||||
|
<li>cpan install Digest::CRC oder auch <br>
|
||||||
|
sudo apt-get install libdigest-crc-perl </li>
|
||||||
|
<li>cpan install Math::Trig </li></ul><br>
|
||||||
<br>
|
<br>
|
||||||
cpan install Digest::CRC oder auch <br>
|
<b>Unterstütze Modelle:</b>
|
||||||
sudo apt-get install libdigest-crc-perl <br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<b>Unterstütze Modelle:</b>
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>WS-0101 --> Model: WH1080</li>
|
<li>WS-0101 --> Model: WH1080</li>
|
||||||
<li>TFA 30.3189 / WH1080 --> Model: WH1080</li>
|
<li>TFA 30.3189 / WH1080 --> Model: WH1080</li>
|
||||||
<li>1073 (WS1080) --> Model: WH1080</li>
|
<li>1073 (WS1080) --> Model: WH1080</li>
|
||||||
|
<li>WH2315 --> Model: WH1080</li>
|
||||||
<li>WH3080 --> Model: WH1080</li>
|
<li>WH3080 --> Model: WH1080</li>
|
||||||
<li>CTW600 --> Model: CTW600</li>
|
<li>CTW600 --> Model: CTW600</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -789,7 +827,7 @@
|
|||||||
<b>Define</b>
|
<b>Define</b>
|
||||||
<ul>Die empfangenen Sensoren werden automatisch angelegt.<br>
|
<ul>Die empfangenen Sensoren werden automatisch angelegt.<br>
|
||||||
Die ID der angelegten Sensoren wird nach jedem Batteriewechsel geändert, welche der Sensor beim Einschalten zufällig vergibt.<br>
|
Die ID der angelegten Sensoren wird nach jedem Batteriewechsel geändert, welche der Sensor beim Einschalten zufällig vergibt.<br>
|
||||||
CRC Checksumme wird zur Zeit noch nicht überprüft, deshalb werden Sensoren bei denen die Luftfeuchte < 0 oder > 100 ist, nicht angelegt.<br>
|
CRC Checksumme wird zur Zeit noch nicht überprüft, deshalb werden Sensoren bei denen die Luftfeuchte < 0 oder > 100 ist, nicht angelegt.<br>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@ -825,14 +863,14 @@
|
|||||||
|
|
||||||
<a name="WindDirAverageTime"></a>
|
<a name="WindDirAverageTime"></a>
|
||||||
<li>WindDirAverageTime<br>
|
<li>WindDirAverageTime<br>
|
||||||
default ist 600s, Zeitspanne die für die Berechung berücksichtig werden soll
|
default ist 600s, Zeitspanne die für die Berechung berücksichtig werden soll
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
<a name="WindDirAverageMinSpeed"></a>
|
<a name="WindDirAverageMinSpeed"></a>
|
||||||
<li>WindDirAverageMinSpeed<br>
|
<li>WindDirAverageMinSpeed<br>
|
||||||
da bei sehr geringer Windgeschwindigkeit die Windrichtung üblicherweise nicht
|
da bei sehr geringer Windgeschwindigkeit die Windrichtung üblicherweise nicht
|
||||||
eindeutig ist, kann mit minspeed ein Schwellwert angegeben werden
|
eindeutig ist, kann mit minspeed ein Schwellwert angegeben werden
|
||||||
Ist die (gewichtetete) mittlere Geschwindigkeit < minspeed wird undef zurück geliefert
|
Ist die (gewichtetete) mittlere Geschwindigkeit < minspeed wird undef zurück geliefert
|
||||||
</li><br>
|
</li><br>
|
||||||
|
|
||||||
<a name="WindDirAverageDecay"></a>
|
<a name="WindDirAverageDecay"></a>
|
||||||
@ -845,7 +883,7 @@
|
|||||||
<a name="WS09_CRCAUS"></a>
|
<a name="WS09_CRCAUS"></a>
|
||||||
<li>WS09_CRCAUS<br>
|
<li>WS09_CRCAUS<br>
|
||||||
Wird im Signalduino-Modul (00_SIGNALduino.pm) gesetzt
|
Wird im Signalduino-Modul (00_SIGNALduino.pm) gesetzt
|
||||||
<br>0: CRC-Prüfung bei WH1080 CRC-Summe = 0
|
<br>0: CRC-Prüfung bei WH1080 CRC-Summe = 0
|
||||||
<br>2: CRC-Summe = 49 (x031) bei WH1080 wird als OK verarbeitet
|
<br>2: CRC-Summe = 49 (x031) bei WH1080 wird als OK verarbeitet
|
||||||
</li><br>
|
</li><br>
|
||||||
</ul><br>
|
</ul><br>
|
||||||
@ -861,11 +899,11 @@
|
|||||||
<li>windSpeed/windgust (Einheit siehe Unit_of_Wind) und windDirection (N-O-S-W)</li>
|
<li>windSpeed/windgust (Einheit siehe Unit_of_Wind) und windDirection (N-O-S-W)</li>
|
||||||
<li>Rain (mm)</li>
|
<li>Rain (mm)</li>
|
||||||
<li>windDirectionAverage
|
<li>windDirectionAverage
|
||||||
Als Ergebnis wird die Windrichtung zurück geliefert, die aus dem aktuellen und
|
Als Ergebnis wird die Windrichtung zurück geliefert, die aus dem aktuellen und
|
||||||
vergangenen Werten über eine Art exponentiellen Mittelwert berechnet werden.
|
vergangenen Werten über eine Art exponentiellen Mittelwert berechnet werden.
|
||||||
Dabei wird zusätzlich die jeweilige Windgeschwindigkeit mit berücksichtigt (höhere Geschwindigkeit
|
Dabei wird zusätzlich die jeweilige Windgeschwindigkeit mit berücksichtigt (höhere Geschwindigkeit
|
||||||
bedeutet höhere Gewichtung).</li>
|
bedeutet höhere Gewichtung).</li><br>
|
||||||
<b>WH3080:</b>
|
<b>WH2315 / WH3080:</b>
|
||||||
<li>UV Index</li>
|
<li>UV Index</li>
|
||||||
<li>Lux</li>
|
<li>Lux</li>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user