diff --git a/FHEM/14_SD_WS.pm b/FHEM/14_SD_WS.pm index 7222fb755..a0d8687a1 100644 --- a/FHEM/14_SD_WS.pm +++ b/FHEM/14_SD_WS.pm @@ -55,6 +55,7 @@ # 25.11.2023 Protokoll 117: neuer Sensor BRESSER Air Quality Sensor Art.No.: 7009970, Hersteller CCL Electronics LTD Model C3123A # 06.01.2024 neues Protokoll 131: BRESSER Blitzsensor Art.No.: 7009976, Hersteller CCL Electronics LTD Model C3129A # 03.09.2024 neues Protokoll 48: Funk-Thermometer JOKER TFA 30.3055, Temperatursender 30.3212 +# 09.01.2025 Protokoll 125: Ergänzung Empfang DCF-Daten WH31E/DNT000005 package main; @@ -119,7 +120,7 @@ sub SD_WS_Initialize { 'SD_WS_120.*' => { ATTR => 'event-min-interval:.*:300 event-on-change-reading:.*', FILTER => '%NAME', GPLOT => 'temp4hum4:Temp/Hum,', autocreateThreshold => '2:180'}, 'SD_WS_122_T.*' => { ATTR => 'event-min-interval:.*:60 event-on-change-reading:.*', FILTER => '%NAME', GPLOT => 'temp4:Temp,', autocreateThreshold => '10:180'}, 'SD_WS_123_T.*' => { ATTR => 'event-min-interval:.*:300 event-on-change-reading:.*', FILTER => '%NAME', GPLOT => 'temp4:Temp,', autocreateThreshold => '2:180'}, - 'SD_WS_125_.*' => { ATTR => 'event-min-interval:.*:300 event-on-change-reading:.*', FILTER => '%NAME', GPLOT => 'temp4hum4:Temp/Hum,', autocreateThreshold => '2:300'}, + 'SD_WS_125_TH.*' => { ATTR => 'event-min-interval:.*:300 event-on-change-reading:.*', FILTER => '%NAME', GPLOT => 'temp4hum4:Temp/Hum,', autocreateThreshold => '2:300'}, 'SD_WS_126_R.*' => { ATTR => 'event-min-interval:.*:300 event-on-change-reading:.*', FILTER => '%NAME', GPLOT => 'rain4:Rain,', autocreateThreshold => "2:180"}, 'SD_WS_129.*' => { ATTR => 'event-min-interval:.*:300 event-on-change-reading:.*', FILTER => '%NAME', GPLOT => 'temp4hum4:Temp/Hum,', autocreateThreshold => '3:180'}, 'SD_WS_131.*' => { ATTR => 'event-min-interval:.*:300 event-on-change-reading:.*', FILTER => '%NAME', GPLOT => q{}, autocreateThreshold => '2:180'}, @@ -218,6 +219,7 @@ sub SD_WS_Parse { my $bitData2; my $model; # wenn im elsif Abschnitt definiert, dann wird der Sensor per AutoCreate angelegt my $modelStat; # for FHEM statistics https://fhem.de/stats/statistics.html + my $state = ''; my $SensorTyp; my $id; my $bat; @@ -1625,38 +1627,66 @@ sub SD_WS_Parse { }, }, 125 => { - # Temperature and humidity sensor Fine Offset WH31, aka Ambient Weather, aka ecowitt - # ------------------------------------------------------------------------------------------ + # Temperature and humidity sensor Fine Offset WH31, aka Ambient Weather, aka ecowitt, DNT000005 + # --------------------------------------------------------------------------------------------- # Byte: 00 01 02 03 04 05 06 07 08 09 10 # Nibble: 01 23 45 67 89 01 23 45 67 89 01 # aa aa aa 2d d4 30 02 82 62 37 04 51 6C 00 02 00 # MN;D= 30 02 82 62 37 04 51 6C 00 02 00 ;R=63; Temp: 21.0 C Hum: 55%, Battery: ok, ID: 0x02 # FF II CT TT HH XX SS ?? ?? ?? ?? - # FF: Family code 0x31 = WH31e 0x37 = wh31b + # FF: Family code 0x30 = WH31e, 0x37 = wh31b, 0x30 = temph/hum DNT000005, 0x52 = time DNT000005 # II: ID (1 byte) - # C : 3bit Channel Number Bit 17-19, 1 Bit Battery bit 20 - # TT: 10 bits Temperature in C, scaled by 10, offset 400. Start at Bit 22 + # C : 3 bit Channel Number Bit 17-19 + # TT: 10 bits Temperature in C, scaled by 10, offset 400, start at bit 22, 1 bit battery bit 20 (0=ok, 1=low) # HH: Humidity in percent as two diget hex # XX: CRC8 of the preceding 5 bytes (Polynomial 0x31, Initial value 0x00, Input not reflected, Result not reflected) # SS: Sum-8 of the preceding 5 bytes # ??: Unknown Data - sensortype => 'WH31e, WH31b, DP50', + # --------------------------------------------------------------------------------------------- + # Byte: 00 01 02 03 04 05 06 07 08 09 10 + # Nibble: 01 23 45 67 89 01 23 45 67 89 01 + # aa aa aa 2d d4 52 97 12 25 01 09 09 55 40 B3 7B + # MN;D= 52 97 12 25 01 09 09 55 40 B3 7B ;R=39;A=1; Date: 25-01-09, Time: 09:55:40 + # FF II ?? YY MM DD hh mm ss XX SS + # YY: 8 bit BCD year + # MM: 8 bit BCD month + # DD: 8 bit BCD day + # hh: 8 bit BCD hour + # mm: 8 bit BCD minute + # ss: 8 bit BCD second + sensortype => 'WH31e, WH31b, DP50, DNT000005', model => 'SD_WS_125_TH', - prematch => sub {my ($rawData,undef) = @_; return 1 if ($rawData =~ /^(30|37)/); }, + prematch => sub {my ($rawData,undef) = @_; return 1 if ($rawData =~ /^(30|37|52)/); }, id => sub {my ($rawData,undef) = @_; return (substr($rawData,2,2));}, - channel => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,17,19) + 1);}, - bat => sub {my (undef,$bitData) = @_; return substr($bitData,20,1) eq '0' ? 'ok' : 'low';}, - temp => sub {my (undef,$bitData) = @_; + channel => sub {my ($rawData,$bitData) = @_; + return if ($rawData =~ /^(52)/); # time message + return (SD_WS_binaryToNumber($bitData,17,19) + 1); + }, + bat => sub {my ($rawData,$bitData) = @_; + return if ($rawData =~ /^(52)/); # time message + return substr($bitData,20,1) eq '0' ? 'ok' : 'low'; + }, + temp => sub {my ($rawData,$bitData) = @_; + return if ($rawData =~ /^(52)/); # time message my $temp = SD_WS_binaryToNumber($bitData,22,31); return FHEM::Core::Utils::Math::round(($temp - 400) / 10, 1); }, - hum => sub {my ($rawData,undef) = @_; return hex(substr($rawData,8,2)); }, + hum => sub {my ($rawData,undef) = @_; + return if ($rawData =~ /^(52)/); # time message + return hex(substr($rawData,8,2)) if ($rawData =~ /^(30|37)/); + }, + dcf => sub {my ($rawData,undef) = @_; + return if ($rawData =~ /^(30|37)/); # temp/hum message + return '20' . substr($rawData,6,2) . '-' . substr($rawData,8,2) . '-' . substr($rawData,10,2) . ' ' # date + . substr($rawData,12,2) . ':' . substr($rawData,14,2) . ':' . substr($rawData,16,2); # time + }, crcok => sub {my ($rawData,undef) = @_; + my $crcLength = 12; # temp/hum message + $crcLength = 20 if ($rawData =~ /^(52)/); # time message if (HAS_DigestCRC) { my $calc_crc8 = Digest::CRC->new(width => 8, poly=>0x31); - my $crc_digest = $calc_crc8->add( pack 'H*', substr( $rawData, 0, 12 ) )->digest; - if ($crc_digest) - { + my $crc_digest = $calc_crc8->add( pack 'H*', substr( $rawData, 0, $crcLength ) )->digest; + if ($crc_digest) { Log3 $name, 3, qq[$name: SD_WS_125 Parse msg $rawData - ERROR CRC8 $crc_digest shoud be 0]; return 0; } @@ -1664,16 +1694,15 @@ sub SD_WS_Parse { Log3 $name, 1, qq[$name: SD_WS_125 Parse msg $rawData - ERROR CRC not loaded, please install module Digest::CRC]; } my $checksum = 0; - for (my $i=0; $i < 11; $i += 2) { + for (my $i=0; $i < $crcLength - 1; $i += 2) { $checksum += hex(substr($rawData,$i,2)); } - $checksum -= hex(substr($rawData,12,2)); + $checksum -= hex(substr($rawData,$crcLength,2)); $checksum &= 0xFF; if ($checksum) { Log3 $name, 3, qq[$name: SD_WS_125 Parse msg $rawData - ERROR checksum $checksum != 0]; return 0; } - return 1; }, }, @@ -2208,6 +2237,12 @@ sub SD_WS_Parse { $deviceCode .= '_' . $channel if (defined $channel); } + ### Protocol 125 time message + if ($protocol eq "125" && defined $dcf) { + $deviceCode = 'SD_WS_125_DCF'; # time protocol for sensors without channel + $state = substr($rawData,2,2) . ': ' . $dcf; # ID: DATE TIME + } + my $def = $modules{SD_WS}{defptr}{$deviceCode}; $def = $modules{SD_WS}{defptr}{$deviceCode} if(!$def); @@ -2295,7 +2330,6 @@ sub SD_WS_Parse { } #my $state = (($temp > -60 && $temp < 70) ? "T: $temp":"T: xx") . (($hum > 0 && $hum < 100) ? " H: $hum":""); - my $state = ''; if (defined($temp)) { $state .= "T: $temp"; } @@ -2829,7 +2863,7 @@ sub SD_WS_WH2SHIFT { "x_fhem_maintainer_github": [ "Sidey79" ], - "version": "v1.1.4", + "version": "v1.1.5", "description": "The SD_WS module processes the messages from various environmental sensors received from an IO device (CUL, CUN, SIGNALDuino, SignalESP etc.)", "dynamic_config": 1, "keywords": [ diff --git a/FHEM/lib/SD_ProtocolData.pm b/FHEM/lib/SD_ProtocolData.pm index f4147a4e7..9ca14ce0f 100644 --- a/FHEM/lib/SD_ProtocolData.pm +++ b/FHEM/lib/SD_ProtocolData.pm @@ -2771,7 +2771,7 @@ package lib::SD_ProtocolData; sync => '2DD4', modulation => '2-FSK', regexMatch => qr/^9/, - register => ['0001','022E','0341','042D','05D4','0605','0780','0800','0D21','0E65','0F6A','1089','115C','1202','1322','14F8','1556','1916','1B43','1C68','2611'], + register => ['0001','022E','0341','042D','05D4','0605','0780','0800','0D21','0E65','0F6A','1089','115C','1202','1322','14F8','1556','1916','1B43','1C68'], rfmode => 'Lacrosse_mode1', clientmodule => 'LaCrosse', length_min => '10', @@ -2824,11 +2824,11 @@ package lib::SD_ProtocolData; comment => 'example: TX35-IT,TX35DTH-IT,30.3155WD,30.3156WD,EMT7110', id => '103', knownFreqs => '868.3', - datarate => '9579', + datarate => '9596', sync => '2DD4', modulation => '2-FSK', regexMatch => qr/^9/, - register => ['0001','022E','0341','042D','05D4','0605','0780','0800','0D21','0E65','0F6A','10C8','1182','1202','1322','14F8','1542','1916','1B43','1C68','2611'], + register => ['0001','022E','0341','042D','05D4','0605','0780','0800','0D21','0E65','0F6A','10C8','1183','1202','1322','14F8','1542','1916','1B43','1C68'], rfmode => 'Lacrosse_mode2', clientmodule => 'LaCrosse', length_min => '10', @@ -2920,6 +2920,7 @@ package lib::SD_ProtocolData; rfmode => 'Fine_Offset_WH51_434', clientmodule => 'SD_WS', length_min => '28', + length_max => '38', # WH68 - length_min => '32', length_max => '38', }, "107.1" => # Fine Offset WH51, ECOWITT WH51, MISOL/1, Froggit DP100 Soil Moisture Sensor use with FSK 868.35 MHz { @@ -2936,6 +2937,7 @@ package lib::SD_ProtocolData; rfmode => 'Fine_Offset_WH51_868', clientmodule => 'SD_WS', length_min => '28', + length_max => '38', # WH68 - length_min => '32', length_max => '38', }, "108" => ## BRESSER 5-in-1 Weather Center, Bresser Professional Rain Gauge, Fody E42, Fody E43 - elektron-bbs 2021-05-02 # https://github.com/RFD-FHEM/RFFHEM/issues/607 @@ -3141,6 +3143,7 @@ package lib::SD_ProtocolData; rfmode => 'Fine_Offset_WH57_434', clientmodule => 'SD_WS', length_min => '18', + length_max => '38', # WH68 - length_min => '32', length_max => '38', }, "116.1" => ## Thunder and lightning sensor Fine Offset WH57, aka Froggit DP60, aka Ambient Weather WH31L use with FSK 868.35 MHz { @@ -3157,6 +3160,7 @@ package lib::SD_ProtocolData; rfmode => 'Fine_Offset_WH57_868', clientmodule => 'SD_WS', length_min => '18', + length_max => '38', # WH68 - length_min => '32', length_max => '38', }, "117" => ## BRESSER 7-in-1 Weather Center (outdoor sensor) # https://forum.fhem.de/index.php/topic,78809.msg1196941.html#msg1196941 @ JensS 2021-12-30 @@ -3319,13 +3323,13 @@ package lib::SD_ProtocolData; # "124" reserved for => ## Remote control CasaFan FB-FNK Powerboat with 5 buttons for fan - "125" => ## Humidity and Temperaturesensor Ecowitt WH31, froggit DP50 / WH31A + "125" => ## Humidity and Temperaturesensor Ecowitt WH31/WH31E, froggit DP50 / WH31A, DNT000005 # Nordamerika: 915MHz; Europa: 868MHz, andere Regionen: 433MHz # https://github.com/RFD-FHEM/RFFHEM/pull/1161 @ sidey79 2023-04-01 - # SD_WS_125_TH_1 T: 21.0 H: 55 Battery: ok channel:1 MN;D=300282623704516C000200;R=56; - # SD_WS_125_TH_1 T: 16.7 H: 60 Battery: ok channel:2 MN;D=300292373CDA116C000200;R=229; + # SD_WS_125_TH_1 T: 21.0 H: 55 Battery: ok channel:1 MN;D=300282623704516C000200;R=56; + # SD_WS_125_TH_1 T: 16.7 H: 60 Battery: ok channel:2 MN;D=300292373CDA116C000200;R=229; # SD_WS_125_TH_3 T: 5.4 H: 52 Battery: ok channel:3 MN;D=30E0A1C634FEA96C000200;R=197; - + # SD_WS_125_DCF: 97: 2025-01-09 10:49:29 MN;D=52971025010910492909B3;R=33;A=2; { name => 'WH31', comment => 'Fine Offset | Ambient Weather WH31E Thermo-Hygrometer Sensor', @@ -3334,12 +3338,13 @@ package lib::SD_ProtocolData; datarate => '17.257', sync => '2DD4', modulation => '2-FSK', - regexMatch => qr/^(30|37)/, + regexMatch => qr/^(30|37|52)/, preamble => 'W125#', - register => ['0001','022E','0343','042D','05D4','060b','0780','0800','0D21','0E65','0FE8','10A9','115C','1202','1322','14F8','1543','1916','1B43','1C68'], + register => ['0001','022E','0342','042D','05D4','060b','0780','0800','0D21','0E65','0FE8','10A9','115C','1202','1322','14F8','1543','1916','1B43','1C68'], rfmode => 'Fine_Offset_WH31_868', clientmodule => 'SD_WS', - length_min => '18', + length_min => '22', + length_max => '38', # WH68 - length_min => '32', length_max => '38', }, "126" => ## Rainfall Sensor Ecowitt WH40 # https://github.com/RFD-FHEM/RFFHEM/pull/1164 @ sidey79 2023-04-03 @@ -3360,7 +3365,7 @@ package lib::SD_ProtocolData; rfmode => 'Fine_Offset_WH40_868', clientmodule => 'SD_WS', length_min => '22', - length_max => '28', + length_max => '38', # WH68 - length_min => '32', length_max => '38', }, "127" => ## Remote control with 14 buttons for ceiling fan # https://forum.fhem.de/index.php?topic=134121.0 @ Kai-Alfonso 2023-06-29 diff --git a/t/FHEM/14_SD_WS/testData.json b/t/FHEM/14_SD_WS/testData.json index d238c7204..c3e721f0a 100644 --- a/t/FHEM/14_SD_WS/testData.json +++ b/t/FHEM/14_SD_WS/testData.json @@ -2304,7 +2304,7 @@ "humidity" : 55, "state" : "T: 21.0 H: 55", "temperature" : "21.0", - "type" : "WH31e, WH31b, DP50", + "type" : "WH31e, WH31b, DP50, DNT000005", "batteryState" : "ok", "channel" : 1 }, @@ -2326,7 +2326,7 @@ "humidity" : 60, "state" : "T: 16.7 H: 60", "temperature" : "16.7", - "type" : "WH31e, WH31b, DP50", + "type" : "WH31e, WH31b, DP50, DNT000005", "batteryState" : "ok", "channel" : 2 }, @@ -2348,7 +2348,7 @@ "humidity" : 52, "state" : "T: 5.4 H: 52", "temperature" : "5.4", - "type" : "WH31e, WH31b, DP50", + "type" : "WH31e, WH31b, DP50, DNT000005", "batteryState" : "ok", "channel" : 3 },