Skip to content

Commit

Permalink
SD_WS_125_DCF
Browse files Browse the repository at this point in the history
Protocol 125 supplemented by decoding of the DCF message.
  • Loading branch information
elektron-bbs committed Jan 20, 2025
1 parent 2faa734 commit d4c3c31
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 34 deletions.
74 changes: 54 additions & 20 deletions FHEM/14_SD_WS.pm
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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'},
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1625,55 +1627,82 @@ 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;
}
} else {
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;
},
},
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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";
}
Expand Down Expand Up @@ -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": [
Expand Down
27 changes: 16 additions & 11 deletions FHEM/lib/SD_ProtocolData.pm
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -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
{
Expand All @@ -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
Expand Down Expand Up @@ -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
{
Expand All @@ -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
Expand Down Expand Up @@ -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',
Expand All @@ -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
Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions t/FHEM/14_SD_WS/testData.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
Expand All @@ -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
},
Expand All @@ -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
},
Expand Down

0 comments on commit d4c3c31

Please sign in to comment.