mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 06:39:11 +00:00
14_SD_WS.pm: New sensors
Temperature/hydro EuroChron EFTH-800 Raingauge TFA Drop Sensor TFA 30.3228.02, FT007T temperature sensor git-svn-id: https://svn.fhem.de/fhem/trunk@21621 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
322e23da0c
commit
4899d4ba0d
11
fhem/CHANGED
11
fhem/CHANGED
@ -1,5 +1,16 @@
|
||||
# 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.
|
||||
- feature: 14_SD_UT.pm
|
||||
new model Novy_840039
|
||||
new remote control xavax 00111939
|
||||
new remote control with 4 buttons for diesel heating
|
||||
- change: 14_SD_UT.pm
|
||||
model Novy_840039, rename button text power_button to power_on_off
|
||||
remove sort option
|
||||
- bugfix: 14_SD_UT.pm
|
||||
fix UTClock for all models
|
||||
TR-502MSV bugfix, ident was only 8 bit, must be 12 bit long
|
||||
RC_10 button set all work after renaming the device
|
||||
- featire: SD_ProtocolData.pm v1.1.7
|
||||
new protocol 97 Momento remote control for wireless digital picture frame
|
||||
new protocol 58 Weather F007-T
|
||||
|
@ -5,6 +5,7 @@
|
||||
# weather sensors which use various protocol
|
||||
# Sidey79 & Ralf9 2016 - 2017
|
||||
# Joerg 2017
|
||||
# elektron-bbs 2018 -
|
||||
# 17.04.2017 WH2 (TFA 30.3157 nur Temp, Hum = 255),es wird das Perlmodul Digest:CRC benoetigt fuer CRC-Pruefung benoetigt
|
||||
# 29.05.2017 Test ob Digest::CRC installiert
|
||||
# 22.07.2017 WH2 angepasst
|
||||
@ -22,6 +23,9 @@
|
||||
# 02.05.2019 neues Protokoll 94: Atech wireless weather station (vermutlicher Name: WS-308)
|
||||
# 14.06.2019 neuer Sensor TECVANCE TV-4848 - Protokoll 84 angepasst (prematch)
|
||||
# 09.11.2019 neues Protokoll 53: Lidl AURIOL AHFL 433 B2 IAN 314695
|
||||
# 29.12.2019 neues Protokoll 27: Temperatur-/Feuchtigkeitssensor EuroChron EFTH-800
|
||||
# 09.02.2020 neues Protokoll 54: Regenmesser TFA Drop
|
||||
# 22.02.2020 Protokoll 58: neuer Sensor TFA 30.3228.02, FT007T Thermometer Sensor
|
||||
|
||||
package main;
|
||||
|
||||
@ -31,6 +35,7 @@ use warnings;
|
||||
# use Data::Dumper;
|
||||
|
||||
# Forward declarations
|
||||
sub SD_WS_LFSR_digest8_reflect($$$$);
|
||||
sub SD_WS_bin2dec($);
|
||||
sub SD_WS_binaryToNumber;
|
||||
sub SD_WS_WH2CRCCHECK($);
|
||||
@ -56,11 +61,14 @@ sub SD_WS_Initialize($)
|
||||
"BresserTemeo.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:180"},
|
||||
"SD_WH2.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:90"},
|
||||
"SD_WS71_T.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4:Temp,", autocreateThreshold => "2:180"},
|
||||
"SD_WS_27_TH_.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "3:180"},
|
||||
"SD_WS_33_T_.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.* model:other", FILTER => "%NAME", GPLOT => "temp4:Temp,", autocreateThreshold => "2:180"},
|
||||
"SD_WS_33_TH_.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.* model:other", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:180"},
|
||||
"SD_WS_38_T_.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4:Temp,", autocreateThreshold => "3:180"},
|
||||
"SD_WS_51_TH.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "3:180"},
|
||||
"SD_WS_53_TH.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "3:180"},
|
||||
"SD_WS_54_R.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "rain4:Rain,", autocreateThreshold => "3:180"},
|
||||
"SD_WS_58_T_.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4:Temp,", autocreateThreshold => "2:90"},
|
||||
"SD_WS_58_TH.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:90"},
|
||||
"SD_WS_84_TH_.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:120"},
|
||||
"SD_WS_85_THW_.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "4:120"},
|
||||
@ -89,7 +97,7 @@ sub SD_WS_Define($$)
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
###################################
|
||||
sub SD_WS_Undef($$)
|
||||
{
|
||||
my ($hash, $name) = @_;
|
||||
@ -117,6 +125,7 @@ sub SD_WS_Parse($$)
|
||||
my $SensorTyp;
|
||||
my $id;
|
||||
my $bat;
|
||||
my $batChange;
|
||||
my $sendmode;
|
||||
my $channel;
|
||||
my $rawTemp;
|
||||
@ -126,6 +135,9 @@ sub SD_WS_Parse($$)
|
||||
my $trend;
|
||||
my $trendTemp;
|
||||
my $trendHum;
|
||||
my $rain_total;
|
||||
my $rawRainCounter;
|
||||
my $sendCounter;
|
||||
my $beep;
|
||||
|
||||
my %decodingSubs = (
|
||||
@ -172,6 +184,53 @@ sub SD_WS_Parse($$)
|
||||
hum => sub {return undef;},
|
||||
bat => sub {return undef;},
|
||||
},
|
||||
27 =>
|
||||
{
|
||||
# Protokollbeschreibung: Temperatur-/Feuchtigkeitssensor EuroChron EFTH-800
|
||||
# -----------------------------------------------------------------------------------
|
||||
# 0 4 | 8 12 | 16 20 | 24 28 | 32 36 | 40 44
|
||||
# 0000 1001 | 0001 0110 | 0001 0000 | 0000 0000 | 0100 1001 | 0100 0000
|
||||
# ?ccc iiii | iiii iiii | bstt tttt | tttt ???? | hhhh hhhh | xxxx xxxx
|
||||
# c: 3 bit channel valid channels are 0-7 (stands for channel 1-8)
|
||||
# i: 12 bit random id (changes on power-loss)
|
||||
# b: 1 bit battery indicator (0=>OK, 1=>LOW)
|
||||
# s: 1 bit sign temperature (0=>negative, 1=>positive)
|
||||
# t: 10 bit unsigned temperature, scaled by 10
|
||||
# h: 8 bit relative humidity percentage (BCD)
|
||||
# x: 8 bit CRC8
|
||||
# ?: unknown (Bit 0, 28-31 always 0 ???)
|
||||
# The sensor sends two messages at intervals of about 57-58 seconds
|
||||
sensortype => 'EFTH-800',
|
||||
model => 'SD_WS_27_TH',
|
||||
prematch => sub {my $rawData = shift; return 1 if ($rawData =~ /^[0-9A-F]{7}0[0-9]{2}[0-9A-F]{2}$/); }, # prematch 113C49A 0 47 AE
|
||||
channel => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,1,3) + 1 ); },
|
||||
id => sub {my (undef,$bitData) = @_; return substr($rawData,1,3); },
|
||||
bat => sub {my (undef,$bitData) = @_; return substr($bitData,16,1) eq "0" ? "ok" : "low";},
|
||||
temp => sub {my (undef,$bitData) = @_; return substr($bitData,17,1) eq "0" ? ((SD_WS_binaryToNumber($bitData,18,27) - 1024) / 10.0) : (SD_WS_binaryToNumber($bitData,18,27) / 10.0);},
|
||||
hum => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,32,35) * 10) + (SD_WS_binaryToNumber($bitData,36,39));},
|
||||
crcok => sub {my $rawData = shift;
|
||||
my $rc = eval
|
||||
{
|
||||
require Digest::CRC;
|
||||
Digest::CRC->import();
|
||||
1;
|
||||
};
|
||||
if ($rc) {
|
||||
my $datacheck1 = pack( 'H*', substr($rawData,0,10) );
|
||||
my $crcmein1 = Digest::CRC->new(width => 8, poly => 0x31);
|
||||
my $rr3 = $crcmein1->add($datacheck1)->hexdigest;
|
||||
Log3 $name, 4, "$name: SD_WS_27 Parse msg $rawData, CRC $rr3";
|
||||
if (hex($rr3) == hex(substr($rawData,-2))) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
Log3 $name, 1, "$name: SD_WS_27 Parse msg $rawData - ERROR CRC not load, please install modul Digest::CRC";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} ,
|
||||
33 =>
|
||||
{
|
||||
# Protokollbeschreibung: Conrad Temperatursensor S522 fuer Funk-Thermometer S521B
|
||||
@ -329,40 +388,108 @@ sub SD_WS_Parse($$)
|
||||
temp => sub {my (undef,$bitData) = @_; return substr($bitData,12,1) eq "1" ? ((SD_WS_binaryToNumber($bitData,12,23) - 4096) / 10.0) : (SD_WS_binaryToNumber($bitData,12,23) / 10.0);},
|
||||
hum => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,24,30) );},
|
||||
},
|
||||
58 =>
|
||||
{
|
||||
sensortype => 'TFA 30.3208.0',
|
||||
model => 'SD_WS_58_TH',
|
||||
prematch => sub {my $msg = shift; return 1 if ($msg =~ /^45[0-9A-F]{11}/); }, # prematch
|
||||
54 => {
|
||||
# TFA Drop Rainmeter 30.3233.01
|
||||
# ----------------------------------------------------------------------------------
|
||||
# 0 8 16 24 32 40 48 56 64 - 01234567890123456
|
||||
# 00111101 10011100 01000011 00001010 00011011 10101010 00000001 10001001 1000 - 3D9C430A1BAA01898
|
||||
# 00111101 10011100 01000011 00000110 00011000 10101010 00000001 00110100 0000 - 3D9C430618AA01340
|
||||
# PPPPIIII IIIIIIII IIIIIIII BCUUXXXU RRRRRRRR FFFFFFFF SSSSSSSS MMMMMMMM KKKK
|
||||
# P: 4 bit message prefix, always 0x3
|
||||
# I: 20 bit Sensor ID
|
||||
# B: 1 bit Battery indicator, 0 if battery OK, 1 if battery is low.
|
||||
# C: 1 bit Device reset, set to 1 briefly after battery insert.
|
||||
# X: 3 bit Transmission counter, rolls over.
|
||||
# R: 8 bit LSB of 16-bit little endian rain counter
|
||||
# F: 8 bit Fixed to 0xaa
|
||||
# S: 8 bit MSB of 16-bit little endian rain counter
|
||||
# M: 8 bit Checksum, compute with reverse Galois LFSR with byte reflection, generator 0x31 and key 0xf4.
|
||||
# K: 4 bit Unknown, either b1011 or b0111. - Distribution: 50:50 ???
|
||||
# U: Unknown
|
||||
# The rain counter starts at 65526 to indicate 0 tips of the bucket. The counter rolls over at 65535 to 0, which corresponds to 9 and 10 tips of the bucket.
|
||||
# Each tip of the bucket corresponds to 0.254mm of rain.
|
||||
# After battery insertion, the sensor will transmit 7 messages in rapid succession, one message every 3 seconds. After the first message,
|
||||
# the remaining 6 messages have bit 1 of byte 3 set to 1. This could be some sort of reset indicator.
|
||||
# For these 6 messages, the transmission counter does not increase. After the full 7 messages, one regular message is sent after 30s.
|
||||
# Afterwards, messages are sent every 45s.
|
||||
sensortype => 'TFA 30.3233.01',
|
||||
model => 'SD_WS_54_R',
|
||||
prematch => sub {my $rawData = shift; return 1 if ($rawData =~ /^3[0-9A-F]{9}AA[0-9A-F]{4,5}$/); }, # prematch 3 E2E390CF9 AA FF8A0
|
||||
id => sub {my ($rawData,undef) = @_; return substr($rawData,1,5); },
|
||||
bat => sub {my (undef,$bitData) = @_; return substr($bitData,24,1) eq "0" ? "ok" : "low";},
|
||||
batChange => sub {my (undef,$bitData) = @_; return substr($bitData,25,1);},
|
||||
sendCounter => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,28,30));},
|
||||
rawRainCounter => sub {my (undef,$bitData) = @_;
|
||||
my $rawRainCounterMessage = SD_WS_binaryToNumber($bitData,32,39) + SD_WS_binaryToNumber($bitData,48,55) * 256;
|
||||
if ($rawRainCounterMessage > 65525) {
|
||||
return $rawRainCounterMessage - 65526;
|
||||
} else {
|
||||
return $rawRainCounterMessage + 10;
|
||||
}
|
||||
},
|
||||
rain_total => sub {my (undef,$bitData) = @_;
|
||||
my $rawRainCounterMessage = SD_WS_binaryToNumber($bitData,32,39) + SD_WS_binaryToNumber($bitData,48,55) * 256;
|
||||
if ($rawRainCounterMessage > 65525) {
|
||||
return ($rawRainCounterMessage - 65526) * 0.254;
|
||||
} else {
|
||||
return ($rawRainCounterMessage + 10) * 0.254;
|
||||
}
|
||||
},
|
||||
crcok => sub {my $rawData = shift;
|
||||
my $checksum = SD_WS_LFSR_digest8_reflect(7, 0x31, 0xf4, $rawData );
|
||||
if ($checksum == hex(substr($rawData,14,2))) {
|
||||
return 1;
|
||||
} else {
|
||||
Log3 $name, 3, "$name: SD_WS_54 Parse msg $msg - ERROR checksum $checksum != " . hex(substr($rawData,14,2));
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
},
|
||||
58 => {
|
||||
# TFA 30.3208.02, TFA 30.3228.02, TFA 30.3229.02, Froggit FT007xx, Ambient Weather F007-xx, Renkforce FT007xx
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
# 0 4 8 12 16 20 24 28 32 36 40 44 48
|
||||
# 0100 0101 1100 0110 1001 0011 1100 1010 0011 0100 1100 0111 0000
|
||||
# yyyy yyyy iiii iiii bccc tttt tttt tttt hhhh hhhh ssss ssss ????
|
||||
# y 8 bit sensor type (45=>TH, 46=>T)
|
||||
# i: 8 bit random id (changes on power-loss)
|
||||
# b: 1 bit battery indicator (0=>OK, 1=>LOW)
|
||||
# c: 3 bit channel (valid channels are 1-8)
|
||||
# t: 12 bit temperature (Farenheit: subtract 400 and divide by 10, Celsius: subtract 720 and multiply by 0.0556)
|
||||
# h: 8 bit humidity (only type 45, type 46 changes between 10 and 15)
|
||||
# s: 8 bit check
|
||||
# ?: 4 bit unknown
|
||||
# frames sent every ~1 min (varies by channel), map of channel id to transmission interval: 1: 53s, 2: 57s, 3: 59s, 4: 61s, 5: 67s, 6: 71s, 7: 73s, 8: 79s
|
||||
sensortype => 'TFA 30.3208.02, FT007xx',
|
||||
model => 'SD_WS_58_T',
|
||||
# prematch => sub {my $msg = shift; return 1 if ($msg =~ /^45[0-9A-F]{11}/); }, # prematch
|
||||
prematch => sub {my $msg = shift; return 1 if ($msg =~ /^4[5|6][0-9A-F]{11}/); }, # prematch, 45=FT007TH/TFA 30.3208.02, 46=FT007T/TFA 30.3228.02
|
||||
crcok => sub { my $msg = shift;
|
||||
my @buff = split(//,substr($msg,index($msg,"45"),10));
|
||||
my $crc_check = substr($msg,index($msg,"45")+10,2);
|
||||
# my @buff = split(//,substr($msg,index($msg,"45"),10));
|
||||
# my $idx = index($msg,"45");
|
||||
my @buff = split(//,substr($msg,0,10));
|
||||
my $crc_check = substr($msg,10,2);
|
||||
my $mask = 0x7C;
|
||||
my $checksum = 0x64;
|
||||
my $data;
|
||||
my $nibbleCount;
|
||||
for ( $nibbleCount=0; $nibbleCount < scalar @buff; $nibbleCount+=2)
|
||||
{
|
||||
for ( $nibbleCount=0; $nibbleCount < scalar @buff; $nibbleCount+=2) {
|
||||
my $bitCnt;
|
||||
if ($nibbleCount+1 <scalar @buff)
|
||||
{
|
||||
if ($nibbleCount+1 <scalar @buff) {
|
||||
$data = hex($buff[$nibbleCount].$buff[$nibbleCount+1]);
|
||||
} else {
|
||||
$data = hex($buff[$nibbleCount]);
|
||||
}
|
||||
for ( my $bitCnt= 7; $bitCnt >= 0 ; $bitCnt-- )
|
||||
{
|
||||
for ( my $bitCnt= 7; $bitCnt >= 0 ; $bitCnt-- ) {
|
||||
my $bit;
|
||||
# Rotate mask right
|
||||
$bit = $mask & 1;
|
||||
$mask = ($mask >> 1 ) | ($mask << 7) & 0xFF;
|
||||
if ( $bit )
|
||||
{
|
||||
if ( $bit ) {
|
||||
$mask ^= 0x18 & 0xFF;
|
||||
}
|
||||
# XOR mask into checksum if data bit is 1
|
||||
if ( $data & 0x80 )
|
||||
{
|
||||
if ( $data & 0x80 ) {
|
||||
$checksum ^= $mask & 0xFF;
|
||||
}
|
||||
$data <<= 1 & 0xFF;
|
||||
@ -371,6 +498,7 @@ sub SD_WS_Parse($$)
|
||||
if ($checksum == hex($crc_check)) {
|
||||
return 1;
|
||||
} else {
|
||||
Log3 $name, 3, "$name: SD_WS_58 Parse msg $msg - ERROR checksum $checksum != " . hex($crc_check);
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
@ -378,7 +506,7 @@ sub SD_WS_Parse($$)
|
||||
bat => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,16) eq "1" ? "low" : "ok";}, # bat?
|
||||
channel => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,17,19) + 1 ); }, # channel
|
||||
temp => sub {my (undef,$bitData) = @_; return round((SD_WS_binaryToNumber($bitData,20,31)-720)*0.0556,1); }, # temp
|
||||
hum => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,32,39)); }, # hum
|
||||
hum => sub {my ($rawData,$bitData) = @_; return substr($rawData,1,1) eq "5" ? (SD_WS_binaryToNumber($bitData,32,39)) : 0;}, # hum
|
||||
} ,
|
||||
84 =>
|
||||
{
|
||||
@ -812,8 +940,7 @@ sub SD_WS_Parse($$)
|
||||
elsif (defined($decodingSubs{$protocol})) # durch den hash decodieren
|
||||
{
|
||||
$SensorTyp=$decodingSubs{$protocol}{sensortype};
|
||||
if (!$decodingSubs{$protocol}{prematch}->( $rawData ))
|
||||
{
|
||||
if (!$decodingSubs{$protocol}{prematch}->( $rawData )) {
|
||||
Log3 $iohash, 4, "$name: SD_WS_Parse $rawData protocolid $protocol ($SensorTyp) - ERROR prematch" ;
|
||||
return "";
|
||||
}
|
||||
@ -823,16 +950,18 @@ sub SD_WS_Parse($$)
|
||||
return "";
|
||||
}
|
||||
$id=$decodingSubs{$protocol}{id}->( $rawData,$bitData );
|
||||
#my $temphex=$decodingSubs{$protocol}{temphex}->( $rawData,$bitData );
|
||||
$temp=$decodingSubs{$protocol}{temp}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{temp}));
|
||||
$hum=$decodingSubs{$protocol}{hum}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{hum}));
|
||||
$windspeed=$decodingSubs{$protocol}{windspeed}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{windspeed}));
|
||||
$channel=$decodingSubs{$protocol}{channel}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{channel}));
|
||||
$model = $decodingSubs{$protocol}{model};
|
||||
$bat = $decodingSubs{$protocol}{bat}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{bat}));
|
||||
|
||||
$batChange = $decodingSubs{$protocol}{batChange}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{batChange}));
|
||||
$rawRainCounter = $decodingSubs{$protocol}{rawRainCounter}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{rawRainCounter}));
|
||||
$rain_total = $decodingSubs{$protocol}{rain_total}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{rain_total}));
|
||||
$sendCounter = $decodingSubs{$protocol}{sendCounter}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{sendCounter}));
|
||||
$beep = $decodingSubs{$protocol}{beep}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{beep}));
|
||||
if ($model eq "SD_WS_33_T") { # for SD_WS_33 discrimination T - TH
|
||||
if ($model eq "SD_WS_33_T" || $model eq "SD_WS_58_T") { # for SD_WS_33 or SD_WS_58 discrimination T - TH
|
||||
$model = $decodingSubs{$protocol}{model}."H" if $hum != 0; # for models with Humidity
|
||||
}
|
||||
$sendmode = $decodingSubs{$protocol}{sendmode}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{sendmode}));
|
||||
@ -854,7 +983,8 @@ sub SD_WS_Parse($$)
|
||||
my $longids = AttrVal($ioname,'longids',0);
|
||||
if (($longids ne "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/)))
|
||||
{
|
||||
$deviceCode = $model . '_' . $id . $channel; # old form of longid
|
||||
$deviceCode = $model . '_' . $id; # for sensors without channel
|
||||
$deviceCode .= $channel if (defined $channel); # old form of longid
|
||||
if (!defined($modules{SD_WS}{defptr}{$deviceCode})) {
|
||||
$deviceCode = $model . '_' . $id; # for sensors without channel
|
||||
$deviceCode .= '_' . $channel if (defined $channel); # new form of longid
|
||||
@ -958,7 +1088,9 @@ sub SD_WS_Parse($$)
|
||||
$state .= " " if (length($state) > 0);
|
||||
$state .= "W: $windspeed"
|
||||
}
|
||||
|
||||
if (defined($rain_total)) {
|
||||
$state .= "R: $rain_total"
|
||||
}
|
||||
### protocol 33 has different bits per sensor type
|
||||
if ($protocol eq "33") {
|
||||
if (AttrVal($name,'model',0) eq "S522") { # Conrad S522
|
||||
@ -980,6 +1112,7 @@ sub SD_WS_Parse($$)
|
||||
readingsBulkUpdate($hash, "humidity", $hum) if (defined($hum) && ($hum > 0 && $hum < 100 )) ;
|
||||
readingsBulkUpdate($hash, "windspeed", $windspeed) if (defined($windspeed)) ;
|
||||
readingsBulkUpdate($hash, "batteryState", $bat) if (defined($bat) && length($bat) > 0) ;
|
||||
readingsBulkUpdate($hash, "batteryChanged", $batChange) if (defined($batChange) && length($batChange) > 0 && $batChange eq "1") ;
|
||||
readingsBulkUpdate($hash, "channel", $channel, 0) if (defined($channel)&& length($channel) > 0);
|
||||
readingsBulkUpdate($hash, "trend", $trend) if (defined($trend) && length($trend) > 0);
|
||||
readingsBulkUpdate($hash, "temperatureTrend", $trendTemp) if (defined($trendTemp) && length($trendTemp) > 0);
|
||||
@ -987,6 +1120,9 @@ sub SD_WS_Parse($$)
|
||||
readingsBulkUpdate($hash, "sendmode", $sendmode) if (defined($sendmode) && length($sendmode) > 0);
|
||||
readingsBulkUpdate($hash, "type", $SensorTyp, 0) if (defined($SensorTyp));
|
||||
readingsBulkUpdate($hash, "beep", $beep) if (defined($beep));
|
||||
readingsBulkUpdate($hash, "rawRainCounter", $rawRainCounter) if (defined($rawRainCounter));
|
||||
readingsBulkUpdate($hash, "rain_total", $rain_total) if (defined($rain_total));
|
||||
readingsBulkUpdate($hash, "sendCounter", $sendCounter) if (defined($sendCounter));
|
||||
readingsEndUpdate($hash, 1); # Notify is done by Dispatch
|
||||
|
||||
return $name;
|
||||
@ -1008,6 +1144,34 @@ sub SD_WS_Attr(@)
|
||||
return undef;
|
||||
}
|
||||
|
||||
# Pruefsummenberechnung "reverse Galois LFSR with byte reflection"
|
||||
# Wird nur fuer TFA Drop Protokoll benoetigt
|
||||
# TFA Drop Protokoll benoetigt als gen 0x31, als key 0xf4
|
||||
|
||||
sub SD_WS_LFSR_digest8_reflect($$$$)
|
||||
{
|
||||
my ($bytes, $gen, $key, $rawData) = @_;
|
||||
my $sum = 0;
|
||||
my $k = 0;
|
||||
my $i = 0;
|
||||
my $data = 0;
|
||||
for ( $k = $bytes - 1; $k >= 0; $k = $k - 1 ) {
|
||||
$data = hex(substr($rawData, $k*2, 2));
|
||||
for ( $i = 0; $i < 8; $i = $i + 1 ) {
|
||||
if ( ($data >> $i) & 0x01) {
|
||||
$sum = $sum^$key;
|
||||
}
|
||||
if ( $key & 0x80 ) {
|
||||
$key = ( $key << 1) ^ $gen;
|
||||
} else {
|
||||
$key = ( $key << 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
$sum = $sum & 0xff;
|
||||
return $sum;
|
||||
}
|
||||
|
||||
sub SD_WS_bin2dec($)
|
||||
{
|
||||
my $h = shift;
|
||||
@ -1067,11 +1231,15 @@ sub SD_WS_WH2SHIFT($){
|
||||
<li>Bresser 7009994</li>
|
||||
<li>BresserTemeo</li>
|
||||
<li>Conrad S522</li>
|
||||
<li>EuroChron EFTH-800 (temperature and humidity sensor)</li>
|
||||
<li>NC-3911, NC-3912 refrigerator thermometer</li>
|
||||
<li>Opus XT300</li>
|
||||
<li>PV-8644 infactory Poolthermometer</li>
|
||||
<li>Renkforce E0001PA</li>
|
||||
<li>Regenmesser DROP TFA 47.3005.01 mit Regensensor TFA 30.3233.01</li>
|
||||
<li>TECVANCE TV-4848</li>
|
||||
<li>Thermometer TFA 30.3228.02, TFA 30.3229.02, FT007T, FT007TP, F007T, F007TP</li>
|
||||
<li>Thermo-Hygrometer TFA 30.3208.02, FT007TH, F007TH</li>
|
||||
<li>TX-EZ6 for Weatherstation TZS First Austria</li>
|
||||
<li>WH2 (TFA Dostmann/Wertheim 30.3157 (sold in Germany), Agimex Rosenborg 66796 (sold in Denmark),ClimeMET CM9088 (Sold in UK)</li>
|
||||
<li>Weatherstation Auriol IAN 283582 Version 06/2017 (Lidl), Modell-Nr.: HG02832D</li>
|
||||
@ -1094,12 +1262,14 @@ sub SD_WS_WH2SHIFT($){
|
||||
Some devices may not support all readings, so they will not be presented<br>
|
||||
</ul>
|
||||
<ul>
|
||||
<li>batteryChanged (1)</li>
|
||||
<li>batteryState (low or ok)</li>
|
||||
<li>channel (number of channel</li>
|
||||
<li>humidity (humidity (1-100 % only if available)</li>
|
||||
<li>humidityTrend (consistent, rising, falling)</li>
|
||||
<li>sendmode (automatic or manual)</li>
|
||||
<li>state (T: H: W:)</li>
|
||||
<li>rain_total (l/m²))</li>
|
||||
<li>state (T: H: W: R:)</li>
|
||||
<li>temperature (°C)</li>
|
||||
<li>temperatureTrend (consistent, rising, falling)</li>
|
||||
<li>type (type of sensor)</li>
|
||||
@ -1164,11 +1334,15 @@ sub SD_WS_WH2SHIFT($){
|
||||
<li>Bresser 7009994</li>
|
||||
<li>BresserTemeo</li>
|
||||
<li>Conrad S522</li>
|
||||
<li>EuroChron EFTH-800 (Temperatur- und Feuchtigkeitssensor)</li>
|
||||
<li>NC-3911, NC-3912 digitales Kuehl- und Gefrierschrank-Thermometer</li>
|
||||
<li>Opus XT300</li>
|
||||
<li>PV-8644 infactory Poolthermometer</li>
|
||||
<li>Regenmesser DROP TFA 47.3005.01 mit Regensensor TFA 30.3233.01</li>
|
||||
<li>Renkforce E0001PA</li>
|
||||
<li>TECVANCE TV-4848</li>
|
||||
<li>Temperatur-Sensor TFA 30.3228.02, TFA 30.3229.02, FT007T, FT007TP, F007T, F007TP</li>
|
||||
<li>Temperatur/Feuchte-Sensor TFA 30.3208.02, FT007TH, F007TH</li>
|
||||
<li>TX-EZ6 fuer Wetterstation TZS First Austria</li>
|
||||
<li>WH2 (TFA Dostmann/Wertheim 30.3157 (Deutschland), Agimex Rosenborg 66796 (Denmark), ClimeMET CM9088 (UK)</li>
|
||||
<li>Wetterstation Auriol IAN 283582 Version 06/2017 (Lidl), Modell-Nr.: HG02832D</li>
|
||||
@ -1191,12 +1365,14 @@ sub SD_WS_WH2SHIFT($){
|
||||
<b>Generierte Readings:</b><br><br>
|
||||
<ul>(verschieden, je nach Typ des Sensors)</ul>
|
||||
<ul>
|
||||
<li>batteryChanged (1)</li>
|
||||
<li>batteryState (low oder ok)</li>
|
||||
<li>channel (Sensor-Kanal)</li>
|
||||
<li>humidity (Luftfeuchte (1-100 %)</li>
|
||||
<li>humidityTrend (gleichbleibend, steigend, fallend)</li>
|
||||
<li>rain_total (l/m²))</li>
|
||||
<li>sendmode (Der Sendemodus, automatic oder manuell mittels Taster am Sender)</li>
|
||||
<li>state (T: H: W:)</li>
|
||||
<li>state (T: H: W: R:)</li>
|
||||
<li>temperature (°C)</li>
|
||||
<li>temperatureTrend (gleichbleibend, steigend, fallend)</li>
|
||||
<li>type (Sensortyp)</li>
|
||||
|
Loading…
Reference in New Issue
Block a user