############################################## ############################################## # $Id: 14_SD_WS07.pm 8958 2015-10-12 $ # # The purpose of this module is to support serval eurochron # weather sensors like eas8007 which use the same protocol # Sidey79 & Ralf9 2015 # package main; use strict; use warnings; #use Data::Dumper; sub SD_WS07_Initialize($) { my ($hash) = @_; $hash->{Match} = "^P7#[A-Fa-f0-9]{6}F[A-Fa-f0-9]{2}"; ## pos 7 ist aktuell immer 0xF $hash->{DefFn} = "SD_WS07_Define"; $hash->{UndefFn} = "SD_WS07_Undef"; $hash->{ParseFn} = "SD_WS07_Parse"; $hash->{AttrFn} = "SD_WS07_Attr"; $hash->{AttrList} = "IODev do_not_notify:1,0 ignore:0,1 showtime:1,0 " . "$readingFnAttributes "; $hash->{AutoCreate} = { "SD_WS07.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:180"} }; } ############################# sub SD_WS07_Define($$) { my ($hash, $def) = @_; my @a = split("[ \t][ \t]*", $def); return "wrong syntax: define SD_WS07 ".int(@a) if(int(@a) < 3 ); $hash->{CODE} = $a[2]; $hash->{lastMSG} = ""; $hash->{bitMSG} = ""; $modules{SD_WS07}{defptr}{$a[2]} = $hash; $hash->{STATE} = "Defined"; my $name= $hash->{NAME}; return undef; } ##################################### sub SD_WS07_Undef($$) { my ($hash, $name) = @_; delete($modules{SD_WS07}{defptr}{$hash->{CODE}}) if(defined($hash->{CODE}) && defined($modules{SD_WS07}{defptr}{$hash->{CODE}})); return undef; } ################################### sub SD_WS07_Parse($$) { my ($iohash, $msg) = @_; #my $rawData = substr($msg, 2); my $name = $iohash->{NAME}; my (undef ,$rawData) = split("#",$msg); #$protocol=~ s/^P(\d+)/$1/; # extract protocol my $model = "SD_WS07"; my $hlen = length($rawData); my $blen = $hlen * 4; my $bitData = unpack("B$blen", pack("H$hlen", $rawData)); Log3 $name, 4, "SD_WS07_Parse $model ($msg) length: $hlen"; # 4 8 9 12 24 28 36 # 0011 0110 1 010 000100000010 1111 00111000 0000 eas8007 # 0111 0010 1 010 000010111100 1111 00000000 0000 other device from anfichtn # ID Bat CHN TMP ?? HUM #my $hashumidity = FALSE; ## Todo: Change decoding per model into a foreach #foreach $key (keys %models) { # .... #} my $bitData2 = substr($bitData,0,8) . ' ' . substr($bitData,8,1) . ' ' . substr($bitData,9,3); $bitData2 = $bitData2 . ' ' . substr($bitData,12,12) . ' ' . substr($bitData,24,4) . ' ' . substr($bitData,28,8); Log3 $iohash, 5, $model . ' converted to bits: ' . $bitData2; my $id = substr($rawData,0,2); my $bat = int(substr($bitData,8,1)) eq "1" ? "ok" : "low"; my $channel = oct("0b" . substr($bitData,9,3)) + 1; my $temp = oct("0b" . substr($bitData,12,12)); my $bit24bis27 = oct("0b".substr($bitData,24,4)); my $hum = oct("0b" . substr($bitData,28,8)); if ($hum==0) { $model=$model."_T"; } else { $model=$model."_TH"; } if ($hum > 100) { return undef; # Eigentlich müsste sowas wie ein skip rein, damit ggf. später noch weitre Sensoren dekodiert werden können. } if ($temp > 700 && $temp < 3840) { return undef; } elsif ($temp >= 3840) { # negative Temperaturen, muß noch ueberprueft und optimiert werden $temp -= 4095; } $temp /= 10; Log3 $iohash, 4, "$model decoded protocolid: 7 sensor id=$id, channel=$channel, temp=$temp, hum=$hum, bat=$bat" ; my $deviceCode; my $longids = AttrVal($iohash->{NAME},'longids',0); if ( ($longids != 0) && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/))) { $deviceCode=$model."_".$id.$channel; Log3 $iohash,4, "$name using longid: $longids model: $model"; } else { $deviceCode = $model . "_" . $channel; } #print Dumper($modules{SD_WS07}{defptr}); my $def = $modules{SD_WS07}{defptr}{$iohash->{NAME} . "." . $deviceCode}; $def = $modules{SD_WS07}{defptr}{$deviceCode} if(!$def); if(!$def) { Log3 $iohash, 1, 'SD_WS07: UNDEFINED sensor ' . $model . ' detected, code ' . $deviceCode; return "UNDEFINED $deviceCode SD_WS07 $deviceCode"; } #Log3 $iohash, 3, 'SD_WS07: ' . $def->{NAME} . ' ' . $id; my $hash = $def; $name = $hash->{NAME}; Log3 $name, 5, "SD_WS07: $name ($rawData)"; if (!defined(AttrVal($hash->{NAME},"event-min-interval",undef))) { my $minsecs = AttrVal($iohash->{NAME},'minsecs',0); if($hash->{lastReceive} && (time() - $hash->{lastReceive} < $minsecs)) { Log3 $hash, 4, "$deviceCode Dropped due to short time. minsecs=$minsecs"; return ""; } } $def->{lastMSG} = $rawData; $def->{bitMSG} = $bitData2; my $state = "T: $temp". ($hum>0 ? " H: $hum":""); readingsBeginUpdate($hash); readingsBulkUpdate($hash, "state", $state); readingsBulkUpdate($hash, "temperature", $temp) if ($temp ne""); readingsBulkUpdate($hash, "humidity", $hum) if ($hum ne "" && $hum != 0 ); readingsBulkUpdate($hash, "battery", $bat) if ($bat ne ""); readingsBulkUpdate($hash, "channel", $channel) if ($channel ne ""); readingsEndUpdate($hash, 1); # Notify is done by Dispatch return $name; } sub SD_WS07_Attr(@) { my @a = @_; # Make possible to use the same code for different logical devices when they # are received through different physical devices. return if($a[0] ne "set" || $a[2] ne "IODev"); my $hash = $defs{$a[1]}; my $iohash = $defs{$a[3]}; my $cde = $hash->{CODE}; delete($modules{SD_WS07}{defptr}{$cde}); $modules{SD_WS07}{defptr}{$iohash->{NAME} . "." . $cde} = $hash; return undef; } 1; =pod =begin html

Wether Sensors protocol #7

=end html =begin html_DE

SD_WS07

=end html_DE =cut