mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 06:39:11 +00:00
14_SD_WS.pm: new sensors E0001PA,S522,TX-EZ6,other
- reading sendmode humidityTrend, temperatureTrend, - windspeed, batteryState added - attr max-deviation-temp and -hum added git-svn-id: https://svn.fhem.de/fhem/trunk@18674 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
1a5b5ab5b0
commit
5fa74a5eb2
@ -1,5 +1,9 @@
|
||||
# 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_WS: support sensors E0001PA,S522,TX-EZ6,other
|
||||
reading sendmode humidityTrend, temperatureTrend,
|
||||
windspeed, batteryState added
|
||||
attr max-deviation-temp and -hum added
|
||||
- changed: 14_SD_WS07: attr correction-xxx to offset-xxx renamed!
|
||||
- feature: 14_SD_WS07: new negation-batt attribute
|
||||
Temp only sensors supported
|
||||
|
@ -9,6 +9,14 @@
|
||||
# 29.05.2017 Test ob Digest::CRC installiert
|
||||
# 22.07.2017 WH2 angepasst
|
||||
# 21.08.2017 WH2 Abbruch wenn kein "FF" am Anfang
|
||||
# 18.08.2018 Protokoll 51 - prematch auf genau 10 Nibbles angepasst, Protokoll 33 - prematch auf genau 11 Nibbles angepasst
|
||||
# 21.08.2018 Modelauswahl hinzugefuegt, da 3 versch. Typen SD_WS_33 --> Batterie-Bit Positionen unterschiedlich (34,35,36)
|
||||
# 11.09.2018 Plotanlegung korrigiert | doc | temp check war falsch positioniert
|
||||
# 16.09.2018 neues Protokoll 84: Funk Wetterstation Auriol IAN 283582 Version 06/2017 (Lidl), Modell-Nr.: HG02832D
|
||||
# 31.09.2018 neues Protokoll 85: Kombisensor TFA 30.3222.02 fuer Wetterstation TFA 35.1140.01
|
||||
# 09.12.2018 neues Protokoll 89: Temperatur-/Feuchtesensor TFA 30.3221.02 fuer Wetterstation TFA 35.1140.01
|
||||
# 06.01.2019 Protokoll 33: Temperatur-/Feuchtesensor TX-EZ6 fuer Wetterstation TZS First Austria hinzugefuegt
|
||||
|
||||
package main;
|
||||
|
||||
|
||||
@ -28,23 +36,28 @@ sub SD_WS_Initialize($)
|
||||
$hash->{ParseFn} = "SD_WS_Parse";
|
||||
$hash->{AttrFn} = "SD_WS_Attr";
|
||||
$hash->{AttrList} = "IODev do_not_notify:1,0 ignore:0,1 showtime:1,0 " .
|
||||
"$readingFnAttributes ";
|
||||
"model:E0001PA,S522,TX-EZ6,other " .
|
||||
"max-deviation-temp:1,2,3,4,5,6,7,8,9,10,15,20,25,30,35,40,45,50 ".
|
||||
"max-deviation-hum:1,2,3,4,5,6,7,8,9,10,15,20,25,30,35,40,45,50 ".
|
||||
"$readingFnAttributes ";
|
||||
$hash->{AutoCreate} =
|
||||
{
|
||||
"SD_WS37_TH.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:180"},
|
||||
"SD_WS50_SM.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:180"},
|
||||
"BresserTemeo.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:180"},
|
||||
"SD_WS51_TH.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:180"},
|
||||
"SD_WS58_TH.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:90"},
|
||||
"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 => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:180"},
|
||||
"SD_WS_51_TH.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:180"},
|
||||
"SD_WS_58_TH.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:90"},
|
||||
"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_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_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"},
|
||||
"SD_WS_89_TH.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "3:180"},
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#############################
|
||||
sub SD_WS_Define($$)
|
||||
{
|
||||
@ -80,25 +93,27 @@ sub SD_WS_Parse($$)
|
||||
my ($iohash, $msg) = @_;
|
||||
#my $rawData = substr($msg, 2);
|
||||
my $name = $iohash->{NAME};
|
||||
my $ioname = $iohash->{NAME};
|
||||
my ($protocol,$rawData) = split("#",$msg);
|
||||
$protocol=~ s/^[WP](\d+)/$1/; # extract protocol
|
||||
|
||||
|
||||
my $dummyreturnvalue= "Unknown, please report";
|
||||
my $hlen = length($rawData);
|
||||
my $blen = $hlen * 4;
|
||||
my $bitData = unpack("B$blen", pack("H$hlen", $rawData));
|
||||
my $bitData2;
|
||||
|
||||
my $model; # wenn im elsif Abschnitt definiert, dann wird der Sensor per AutoCreate angelegt
|
||||
my $SensorTyp;
|
||||
my $id;
|
||||
my $bat;
|
||||
my $sendmode;
|
||||
my $channel;
|
||||
my $rawTemp;
|
||||
my $temp;
|
||||
my $hum;
|
||||
my $windspeed;
|
||||
my $trend;
|
||||
my $trendTemp;
|
||||
my $trendHum;
|
||||
|
||||
my %decodingSubs = (
|
||||
50 => # Protocol 50
|
||||
@ -146,23 +161,50 @@ sub SD_WS_Parse($$)
|
||||
},
|
||||
33 =>
|
||||
{
|
||||
sensortype => 's014/TFA 30.3200/TCM/Conrad',
|
||||
model => 'SD_WS_33_TH',
|
||||
prematch => sub {my $msg = shift; return 1 if ($msg =~ /^[0-9A-F]{10,11}/); }, # prematch
|
||||
crcok => sub {return SD_WS_binaryToNumber($bitData,36,39)+1; }, # crc currently not calculated
|
||||
# Protokollbeschreibung: Conrad Temperatursensor S522 fuer Funk-Thermometer S521B
|
||||
# ------------------------------------------------------------------------
|
||||
# 0 4 | 8 12 | 16 20 | 24 28 | 32 36 40
|
||||
# 1111 1100 | 0001 0110 | 0001 0000 | 0011 0111 | 0100 1001 01
|
||||
# iiii iiii | iixx cctt | tttt tttt | tthh hhhh | hhxx bgxx xx
|
||||
# i: 10 bit random id (changes on power-loss) - Bit 0 + 1 every 0 ???
|
||||
# b: battery indicator (0=>OK, 1=>LOW)
|
||||
# g: battery changed (1=>changed) - muss noch genauer getestet werden! ????
|
||||
# c: Channel (MSB-first, valid channels are 0x00-0x02 -> 1-3)
|
||||
# t: Temperature (MSB-first, BCD, 12 bit unsigned fahrenheit offset by 90 and scaled by 10)
|
||||
# h: always 0
|
||||
# x: unknown
|
||||
|
||||
# Protokollbeschreibung: renkforce Temperatursensor E0001PA fuer Funk-Wetterstation E0303H2TPR (Conrad)
|
||||
# ------------------------------------------------------------------------
|
||||
# 0 4 | 8 12 | 16 20 | 24 28 | 32 36 40
|
||||
# iiii iiii | iixx cctt | tttt tttt | tthh hhhh | hhsb xxxx xx
|
||||
# h: Humidity (MSB-first, BCD, 8 bit relative humidity percentage)
|
||||
# s: sendmode (1=>Test push, send manual 0=>automatic send)
|
||||
# i: | c: | t: | h: | b: | x: same like S522
|
||||
|
||||
# Protokollbeschreibung: Temperatur-/Fechtesensor TX-EZ6 fuer Wetterstation TZS First Austria
|
||||
# ------------------------------------------------------------------------
|
||||
# 0 4 | 8 12 | 16 20 | 24 28 | 32 36 40
|
||||
# iiii iiii | iiHH cctt | tttt tttt | tthh hhhh | hhsb TTxx xx
|
||||
# H: Humidity trend, 00 = equal, 01 = up, 10 = down
|
||||
# T: Temperature trend, 00 = equal, 01 = up, 10 = down
|
||||
# i: | c: | t: | h: | s: | b: | x: same like E0001PA
|
||||
|
||||
sensortype => 's014/TFA 30.3200/TCM/S522/E0001PA/TX-EZ6',
|
||||
model => 'SD_WS_33_T',
|
||||
prematch => sub {my $msg = shift; return 1 if ($msg =~ /^[0-9A-F]{11}$/); }, # prematch
|
||||
crcok => sub {return 1;}, # crc currently not calculated
|
||||
id => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,0,9); }, # id
|
||||
# sendmode => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,10,11) eq "1" ? "manual" : "auto"; }
|
||||
temp => sub {my (undef,$bitData) = @_; return (((SD_WS_binaryToNumber($bitData,22,25)*256 + SD_WS_binaryToNumber($bitData,18,21)*16 + SD_WS_binaryToNumber($bitData,14,17)) *10 -12200) /18)/10; }, #temp
|
||||
temp => sub {my (undef,$bitData) = @_; return round(((SD_WS_binaryToNumber($bitData,22,25)*256 + SD_WS_binaryToNumber($bitData,18,21)*16 + SD_WS_binaryToNumber($bitData,14,17)) - 1220) * 5 / 90.0 , 1); }, #temp
|
||||
hum => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,30,33)*16 + SD_WS_binaryToNumber($bitData,26,29)); }, #hum
|
||||
channel => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,12,13)+1 ); }, #channel
|
||||
bat => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,34) eq "0" ? "ok" : "low";},
|
||||
# sync => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,35,35) eq "1" ? "true" : "false");},
|
||||
bat => sub {my (undef,$bitData) = @_; return substr($bitData,34,1) eq "0" ? "ok" : "low";}, # other or modul orginal
|
||||
} ,
|
||||
51 =>
|
||||
{
|
||||
sensortype => 'Lidl Wetterstation 2759001/IAN114324',
|
||||
sensortype => 'Auriol IAN 275901 / IAN 114324',
|
||||
model => 'SD_WS_51_TH',
|
||||
prematch => sub {my $msg = shift; return 1 if ($msg =~ /^[0-9A-F]{10}/); }, # prematch
|
||||
prematch => sub {my $msg = shift; return 1 if ($msg =~ /^[0-9A-F]{10}$/); }, # prematch
|
||||
crcok => sub {return 1; }, # crc is unknown
|
||||
id => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,0,12); }, # random id?
|
||||
# sendmode => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,10,11) eq "1" ? "manual" : "auto"; }
|
||||
@ -170,12 +212,12 @@ sub SD_WS_Parse($$)
|
||||
hum => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,28,31)*10) + (SD_WS_binaryToNumber($bitData,32,35)); }, #hum
|
||||
channel => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,36,39) ); }, #channel
|
||||
bat => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,13) eq "1" ? "low" : "ok";},
|
||||
trend => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,15,16) eq "01" ? "rising" : SD_WS_binaryToNumber($bitData,14,15) eq "00" ? "neutral" : "rising";},
|
||||
trend => sub {my (undef,$bitData) = @_; return ('neutral', 'rising', 'falling', 'what?')[SD_WS_binaryToNumber($bitData,14,15)];},
|
||||
# sync => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,35,35) eq "1" ? "true" : "false");},
|
||||
} ,
|
||||
58 =>
|
||||
{
|
||||
sensortype => 'TFA 3032080',
|
||||
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
|
||||
crcok => sub { my $msg = shift;
|
||||
@ -224,10 +266,113 @@ sub SD_WS_Parse($$)
|
||||
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
|
||||
} ,
|
||||
84 =>
|
||||
{
|
||||
# Protokollbeschreibung: Funk Wetterstation Auriol IAN 283582 (Lidl)
|
||||
# ------------------------------------------------------------------------
|
||||
# 0 4 | 8 12 | 16 20 | 24 28 | 32 36
|
||||
# 1111 1100 | 0001 0110 | 0001 0000 | 0011 0111 | 0100 1001
|
||||
# iiii iiii | hhhh hhhh | bscc tttt | tttt tttt | ???? ????
|
||||
# i: 8 bit id (?) - no change after battery change, i have seen two IDs: 0x03 and 0xfe
|
||||
# h: 8 bit relative humidity percentage
|
||||
# b: 1 bit battery indicator (0=>OK, 1=>LOW)
|
||||
# s: 1 bit sendmode 1=manual (button pressed) 0=auto
|
||||
# c: 2 bit channel valid channels are 0-2 (1-3)
|
||||
# t: 12 bit signed temperature scaled by 10
|
||||
# ?: unknown
|
||||
# Sensor sends approximately every 30 seconds
|
||||
sensortype => 'Auriol IAN 283582',
|
||||
model => 'SD_WS_84_TH',
|
||||
prematch => sub {my $msg = shift; return 1 if ($msg =~ /^[0-9A-F]{4}[01245689ACDE]{1}[0-9A-F]{5}$/); }, # valid channel only 0-2
|
||||
id => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,0,7); },
|
||||
hum => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,8,15); },
|
||||
bat => sub {my (undef,$bitData) = @_; return substr($bitData,16,1) eq "0" ? "ok" : "low";},
|
||||
sendmode => sub {my (undef,$bitData) = @_; return substr($bitData,17,1) eq "1" ? "manual" : "auto"; },
|
||||
channel => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,18,19)+1 ); },
|
||||
temp => sub { my (undef,$bitData) = @_;
|
||||
my $tempraw = SD_WS_binaryToNumber($bitData,20,31);
|
||||
$tempraw -= 4096 if ($tempraw > 1023); # negative
|
||||
$tempraw /= 10.0;
|
||||
return $tempraw;
|
||||
},
|
||||
crcok => sub {return 1;}, # crc test method is so far unknown
|
||||
} ,
|
||||
85 =>
|
||||
{
|
||||
# Protokollbeschreibung: Kombisensor TFA 30.3222.02 fuer Wetterstation TFA 35.1140.01
|
||||
# -----------------------------------------------------------------------------------
|
||||
# 0 4 | 8 12 | 16 20 | 24 28 | 32 36 | 40 44 | 48 52 | 56 60 | 64
|
||||
# 0000 1001 | 0001 0110 | 0001 0000 | 0000 0111 | 0100 1001 | 0100 0000 | 0100 1001 | 0100 1001 | 1
|
||||
# ???? iiii | iiii iiii | iiii iiii | b??? ??yy | tttt tttt | tttt ???? | hhhh hhhh | ???? ???? | ? message 1
|
||||
# ???? iiii | iiii iiii | iiii iiii | b?cc ??yy | wwww wwww | wwww ???? | 0000 0000 | ???? ???? | ? message 2
|
||||
# i: 20 bit random id (changes on power-loss)
|
||||
# b: 1 bit battery indicator (0=>OK, 1=>LOW)
|
||||
# c: 2 bit channel valid channels are (always 00 stands for channel 1)
|
||||
# y: 2 bit typ, 01 - thermo/hygro (message 1), 10 - wind (message 2)
|
||||
# t: 12 bit unsigned temperature, offset 500, scaled by 10 - if message 1
|
||||
# h: 8 bit relative humidity percentage - if message 1
|
||||
# w: 12 bit unsigned windspeed, scaled by 10 - if message 2
|
||||
# ?: unknown
|
||||
# The sensor sends at intervals of about 30 seconds
|
||||
sensortype => 'TFA 30.3222.02',
|
||||
model => 'SD_WS_85_THW',
|
||||
prematch => sub {my $msg = shift; return 1 if ($msg =~ /^[0-9A-F]{16}/); }, # min 16 nibbles
|
||||
crcok => sub {return 1;}, # crc test method is so far unknown
|
||||
id => sub {my (undef,$bitData) = @_; return substr($rawData,1,5); }, # 0952CF012B1021DF0
|
||||
bat => sub {my (undef,$bitData) = @_; return substr($bitData,24,1) eq "0" ? "ok" : "low";},
|
||||
channel => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,26,27) + 1 ); }, # unknown
|
||||
temp => sub {my (undef,$bitData) = @_;
|
||||
if (substr($bitData,30,2) eq "01") { # message 1 thermo/hygro
|
||||
return ((SD_WS_binaryToNumber($bitData,32,43) - 500) / 10.0);
|
||||
} else {
|
||||
return undef;
|
||||
}
|
||||
},
|
||||
hum => sub {my (undef,$bitData) = @_;
|
||||
if (substr($bitData,30,2) eq "01") { # message 1 thermo/hygro
|
||||
return SD_WS_binaryToNumber($bitData,48,55);
|
||||
} else {
|
||||
return undef;
|
||||
}
|
||||
},
|
||||
windspeed => sub {my (undef,$bitData) = @_;
|
||||
if (substr($bitData,30,2) eq "10") { # message 2 windspeed
|
||||
return (SD_WS_binaryToNumber($bitData,32,43) / 10.0);
|
||||
} else {
|
||||
return undef;
|
||||
}
|
||||
},
|
||||
} ,
|
||||
89 =>
|
||||
{
|
||||
# Protokollbeschreibung: Temperatur-/Feuchtesensor TFA 30.3221.02 fuer Wetterstation TFA 35.1140.01
|
||||
# -------------------------------------------------------------------------------------------------
|
||||
# 0 4 | 8 12 | 16 20 | 24 28 | 32 36
|
||||
# 0000 1001 | 0001 0110 | 0001 0000 | 0000 0111 | 0100 1001
|
||||
# iiii iiii | bscc tttt | tttt tttt | hhhh hhhh | ???? ????
|
||||
# i: 8 bit random id (changes on power-loss)
|
||||
# b: 1 bit battery indicator (0=>OK, 1=>LOW)
|
||||
# s: 1 bit sendmode (0=>auto, 1=>manual)
|
||||
# c: 2 bit channel valid channels are 0-2 (1-3)
|
||||
# t: 12 bit unsigned temperature, offset 500, scaled by 10
|
||||
# h: 8 bit relative humidity percentage
|
||||
# ?: 8 bit unknown
|
||||
# The sensor sends 3 repetitions at intervals of about 60 seconds
|
||||
sensortype => 'TFA 30.3221.02',
|
||||
model => 'SD_WS_89_TH',
|
||||
prematch => sub {my $msg = shift; return 1 if ($msg =~ /^[0-9A-F]{2}[01245689ACDE]{1}[0-9A-F]{7}$/); }, # valid channel only 0-2
|
||||
id => sub {my (undef,$bitData) = @_; return substr($rawData,0,2); },
|
||||
bat => sub {my (undef,$bitData) = @_; return substr($bitData,8,1) eq "0" ? "ok" : "low";},
|
||||
sendmode => sub {my (undef,$bitData) = @_; return substr($bitData,9,1) eq "1" ? "manual" : "auto"; },
|
||||
channel => sub {my (undef,$bitData) = @_; return (SD_WS_binaryToNumber($bitData,10,11) + 1); },
|
||||
temp => sub {my (undef,$bitData) = @_; return ((SD_WS_binaryToNumber($bitData,12,23) - 500) / 10.0); },
|
||||
hum => sub {my (undef,$bitData) = @_; return SD_WS_binaryToNumber($bitData,24,31); },
|
||||
crcok => sub {return 1;}, # crc test method is so far unknown
|
||||
} ,
|
||||
);
|
||||
|
||||
|
||||
Log3 $name, 4, "SD_WS_Parse: Protocol: $protocol, rawData: $rawData";
|
||||
Log3 $name, 4, "$name: SD_WS_Parse Protocol: $protocol, rawData: $rawData";
|
||||
|
||||
if ($protocol eq "37") { # Bresser 7009994
|
||||
# Protokollbeschreibung:
|
||||
@ -250,7 +395,7 @@ sub SD_WS_Parse($$)
|
||||
$SensorTyp = "Bresser 7009994";
|
||||
my $checksum = (SD_WS_binaryToNumber($bitData,0,7) + SD_WS_binaryToNumber($bitData,8,15) + SD_WS_binaryToNumber($bitData,16,23) + SD_WS_binaryToNumber($bitData,24,31)) & 0xFF;
|
||||
if ($checksum != SD_WS_binaryToNumber($bitData,32,39)) {
|
||||
Log3 $name, 3, "$name: SD_WS37 ERROR - checksum $checksum != ".SD_WS_binaryToNumber($bitData,32,39);
|
||||
Log3 $name, 4, "$name: SD_WS37 ERROR - checksum $checksum != ".SD_WS_binaryToNumber($bitData,32,39);
|
||||
return "";
|
||||
} else {
|
||||
Log3 $name, 4, "$name: SD_WS37 checksum ok $checksum = ".SD_WS_binaryToNumber($bitData,32,39);
|
||||
@ -288,7 +433,7 @@ sub SD_WS_Parse($$)
|
||||
my $binvalue = $bitData;
|
||||
|
||||
if (length($binvalue) != 72) {
|
||||
Log3 $iohash, 4, "SD_WS_Parse BresserTemeo: length error (72 bits expected)!!!";
|
||||
Log3 $iohash, 4, "$name: SD_WS_Parse BresserTemeo length error (72 bits expected)!!!";
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -296,15 +441,15 @@ sub SD_WS_Parse($$)
|
||||
if ($protocol eq "44")
|
||||
{
|
||||
$binvalue = "0".$binvalue;
|
||||
Log3 $iohash, 4, "SD_WS_Parse BresserTemeo: Humidity <= 79 Flag";
|
||||
Log3 $iohash, 4, "$name: SD_WS_Parse BresserTemeo Humidity <= 79 Flag";
|
||||
}
|
||||
else
|
||||
{
|
||||
$binvalue = "1".$binvalue;
|
||||
Log3 $iohash, 4, "SD_WS_Parse BresserTemeo: Humidity > 79 Flag";
|
||||
Log3 $iohash, 4, "$name: SD_WS_Parse BresserTemeo Humidity > 79 Flag";
|
||||
}
|
||||
|
||||
Log3 $iohash, 4, "SD_WS_Parse BresserTemeo: new bin $binvalue";
|
||||
Log3 $iohash, 4, "$name: SD_WS_Parse BresserTemeo new bin $binvalue";
|
||||
|
||||
my $checksumOkay = 1;
|
||||
|
||||
@ -315,14 +460,14 @@ sub SD_WS_Parse($$)
|
||||
|
||||
if ($checkHum1 != $hum1Dec || $checkHum2 != $hum2Dec)
|
||||
{
|
||||
Log3 $iohash, 4, "SD_WS_Parse BresserTemeo: checksum error in Humidity";
|
||||
Log3 $iohash, 4, "$name: SD_WS_Parse BresserTemeo checksum error in Humidity";
|
||||
}
|
||||
else
|
||||
{
|
||||
$hum = $hum1Dec.$hum2Dec;
|
||||
if ($hum < 1 || $hum > 100)
|
||||
{
|
||||
Log3 $iohash, 4, "SD_WS_Parse BresserTemeo: Humidity Error. Humidity=$hum";
|
||||
Log3 $iohash, 4, "$name: SD_WS_Parse BresserTemeo Humidity Error. Humidity=$hum";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@ -334,16 +479,15 @@ sub SD_WS_Parse($$)
|
||||
my $checkTemp2 = SD_WS_binaryToNumber($binvalue, 56, 59) ^ 0b1111;
|
||||
my $checkTemp3 = SD_WS_binaryToNumber($binvalue, 60, 63) ^ 0b1111;
|
||||
$temp = $temp1Dec.$temp2Dec.".".$temp3Dec;
|
||||
|
||||
$temp +=0; # remove leading zeros
|
||||
if ($checkTemp1 != $temp1Dec || $checkTemp2 != $temp2Dec || $checkTemp3 != $temp3Dec)
|
||||
{
|
||||
Log3 $iohash, 4, "SD_WS_Parse BresserTemeo: checksum error in Temperature";
|
||||
Log3 $iohash, 4, "$name: SD_WS_Parse BresserTemeo checksum error in Temperature";
|
||||
$checksumOkay = 0;
|
||||
}
|
||||
|
||||
if ($temp > 60)
|
||||
{
|
||||
Log3 $iohash, 4, "SD_WS_Parse BresserTemeo: Temperature Error. temp=$temp";
|
||||
Log3 $iohash, 4, "$name: SD_WS_Parse BresserTemeo Temperature Error. temp=$temp";
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -352,7 +496,7 @@ sub SD_WS_Parse($$)
|
||||
|
||||
if ($sign != $checkSign)
|
||||
{
|
||||
Log3 $iohash, 4, "SD_WS_Parse BresserTemeo: checksum error in Sign";
|
||||
Log3 $iohash, 4, "$name: SD_WS_Parse BresserTemeo checksum error in Sign";
|
||||
$checksumOkay = 0;
|
||||
}
|
||||
else
|
||||
@ -368,7 +512,7 @@ sub SD_WS_Parse($$)
|
||||
|
||||
if ($bat != $checkBat)
|
||||
{
|
||||
Log3 $iohash, 4, "SD_WS_Parse BresserTemeo: checksum error in Bat";
|
||||
Log3 $iohash, 4, "$name: SD_WS_Parse BresserTemeo checksum error in Bat";
|
||||
$bat = undef;
|
||||
}
|
||||
else
|
||||
@ -383,18 +527,18 @@ sub SD_WS_Parse($$)
|
||||
|
||||
if ($channel != $checkChannel || $id != $checkId)
|
||||
{
|
||||
Log3 $iohash, 4, "SD_WS_Parse BresserTemeo: checksum error in Channel or Id";
|
||||
Log3 $iohash, 4, "$name: SD_WS_Parse BresserTemeo checksum error in Channel or Id";
|
||||
$checksumOkay = 0;
|
||||
}
|
||||
|
||||
if ($checksumOkay == 0)
|
||||
{
|
||||
Log3 $iohash, 4, "SD_WS_Parse BresserTemeo: checksum error!!! These Values seem incorrect: temp=$temp, channel=$channel, id=$id";
|
||||
Log3 $iohash, 4, "$name:SD_WS_Parse BresserTemeo checksum error!!! These Values seem incorrect: temp=$temp, channel=$channel, id=$id";
|
||||
return "";
|
||||
}
|
||||
|
||||
$id = sprintf('%02X', $id); # wandeln nach hex
|
||||
Log3 $iohash, 4, "$name SD_WS_Parse: model=$model, temp=$temp, hum=$hum, channel=$channel, id=$id, bat=$bat";
|
||||
Log3 $iohash, 4, "$name: SD_WS_Parse model=$model, temp=$temp, hum=$hum, channel=$channel, id=$id, bat=$bat";
|
||||
|
||||
} elsif ($protocol eq "64") # WH2
|
||||
{
|
||||
@ -499,7 +643,7 @@ sub SD_WS_Parse($$)
|
||||
}
|
||||
|
||||
$bitData = unpack("B$blen", pack("H$hlen", $rawData));
|
||||
Log3 $iohash, 4, "$name converted to bits: WH2 " . $bitData;
|
||||
Log3 $iohash, 4, "$name: converted to bits WH2 " . $bitData;
|
||||
$model = "SD_WS_WH2";
|
||||
$SensorTyp = "WH2";
|
||||
$id = SD_WS_bin2dec(substr($bitData,$vorpre + 4,6));
|
||||
@ -516,10 +660,10 @@ sub SD_WS_Parse($$)
|
||||
# Temp negativ
|
||||
$temp = -(SD_WS_bin2dec(substr($bitData,$vorpre + 13,11))) / 10;
|
||||
}
|
||||
Log3 $iohash, 4, "$name decoded protocolid: $protocol ($SensorTyp) sensor id=$id, Data:".substr($bitData,$vorpre + 12,12)." temp=$temp";
|
||||
Log3 $iohash, 4, "$name: decoded protocolid $protocol ($SensorTyp) sensor id=$id, Data:".substr($bitData,$vorpre + 12,12)." temp=$temp";
|
||||
$hum = SD_WS_bin2dec(substr($bitData,$vorpre + 24,8)); # TFA 30.3157 nur Temp, Hum = 255
|
||||
Log3 $iohash, 4, "$name SD_WS_WH2_8: $protocol ($SensorTyp) sensor id=$id, Data:".substr($bitData,$vorpre + 24,8)." hum=$hum";
|
||||
Log3 $iohash, 4, "$name SD_WS_WH2_9: $protocol ($SensorTyp) sensor id=$id, channel=$channel, temp=$temp, hum=$hum";
|
||||
Log3 $iohash, 4, "$name: SD_WS_WH2_8 $protocol ($SensorTyp) sensor id=$id, Data:".substr($bitData,$vorpre + 24,8)." hum=$hum";
|
||||
Log3 $iohash, 4, "$name: SD_WS_WH2_9 $protocol ($SensorTyp) sensor id=$id, channel=$channel, temp=$temp, hum=$hum";
|
||||
|
||||
}
|
||||
|
||||
@ -528,55 +672,61 @@ sub SD_WS_Parse($$)
|
||||
$SensorTyp=$decodingSubs{$protocol}{sensortype};
|
||||
if (!$decodingSubs{$protocol}{prematch}->( $rawData ))
|
||||
{
|
||||
Log3 $iohash, 4, "$name decoded protocolid: $protocol ($SensorTyp) prematch error" ;
|
||||
Log3 $iohash, 4, "$name: SD_WS_Parse $rawData protocolid $protocol ($SensorTyp) prematch error" ;
|
||||
return "";
|
||||
}
|
||||
my $retcrc=$decodingSubs{$protocol}{crcok}->( $rawData );
|
||||
if (!$retcrc) {
|
||||
Log3 $iohash, 4, "$name decoded protocolid: $protocol ($SensorTyp) crc error: $retcrc";
|
||||
Log3 $iohash, 4, "$name: SD_WS_Parse $rawData protocolid $protocol ($SensorTyp) crc error: $retcrc";
|
||||
return "";
|
||||
}
|
||||
$id=$decodingSubs{$protocol}{id}->( $rawData,$bitData );
|
||||
#my $temphex=$decodingSubs{$protocol}{temphex}->( $rawData,$bitData );
|
||||
|
||||
$temp=$decodingSubs{$protocol}{temp}->( $rawData,$bitData );
|
||||
$hum=$decodingSubs{$protocol}{hum}->( $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 );
|
||||
$model = $decodingSubs{$protocol}{model};
|
||||
$bat = $decodingSubs{$protocol}{bat}->( $rawData,$bitData );
|
||||
$trend = $decodingSubs{$protocol}{trend}->( $rawData,$bitData ) if (defined($decodingSubs{$protocol}{trend}));
|
||||
|
||||
Log3 $iohash, 4, "$name decoded protocolid: $protocol ($SensorTyp) sensor id=$id, channel=$channel, temp=$temp, hum=$hum, bat=$bat";
|
||||
|
||||
$bat = $decodingSubs{$protocol}{bat}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{bat}));
|
||||
if ($model eq "SD_WS_33_T") { # for SD_WS_33 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}));
|
||||
$trend = $decodingSubs{$protocol}{trend}->( $rawData,$bitData ) if (exists($decodingSubs{$protocol}{trend}));
|
||||
#Use of uninitialized value $temp
|
||||
#Log3 $iohash, 4, "$name: decoded protocolid $protocol ($SensorTyp) sensor id=$id, channel=$channel, temp=$temp, hum=$hum, bat=$bat";
|
||||
Log3 $iohash, 4, "$name: decoded protocolid $protocol ($SensorTyp) sensor id=$id";
|
||||
}
|
||||
else {
|
||||
Log3 $iohash, 2, "SD_WS_WH2: unknown message, please report. converted to bits: $bitData";
|
||||
Log3 $iohash, 2, "$name: SD_WS_Parse unknown message, please report. converted to bits: $bitData";
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
if (!defined($model)) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $deviceCode;
|
||||
|
||||
my $longids = AttrVal($iohash->{NAME},'longids',0);
|
||||
my $longids = AttrVal($ioname,'longids',0);
|
||||
if (($longids ne "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/)))
|
||||
{
|
||||
$deviceCode = $model . '_' . $id . $channel;
|
||||
Log3 $iohash,4, "$name using longid: $longids model: $model";
|
||||
$deviceCode = $model . '_' . $id . $channel; # old form of longid
|
||||
if (!defined($modules{SD_WS}{defptr}{$deviceCode})) {
|
||||
$deviceCode = $model . '_' . $id . '_' . $channel; # new form of longid
|
||||
}
|
||||
Log3 $iohash,4, "$name: using longid for $longids device $deviceCode";
|
||||
} else {
|
||||
$deviceCode = $model . "_" . $channel;
|
||||
}
|
||||
|
||||
#print Dumper($modules{SD_WS}{defptr});
|
||||
|
||||
my $def = $modules{SD_WS}{defptr}{$iohash->{NAME} . "." . $deviceCode};
|
||||
my $def = $modules{SD_WS}{defptr}{$ioname . "." . $deviceCode};
|
||||
$def = $modules{SD_WS}{defptr}{$deviceCode} if(!$def);
|
||||
|
||||
if(!$def) {
|
||||
Log3 $iohash, 1, 'SD_WS: UNDEFINED sensor ' . $model . ' detected, code ' . $deviceCode;
|
||||
Log3 $iohash, 1, "$name: SD_WS_Parse UNDEFINED sensor $model detected, code $deviceCode";
|
||||
return "UNDEFINED $deviceCode SD_WS $deviceCode";
|
||||
}
|
||||
|
||||
@ -584,16 +734,65 @@ sub SD_WS_Parse($$)
|
||||
$name = $hash->{NAME};
|
||||
return "" if(IsIgnored($name));
|
||||
|
||||
Log3 $name, 4, "SD_WS: $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";
|
||||
if (defined $temp) {
|
||||
if ($temp < -30 || $temp > 70) {
|
||||
Log3 $iohash, 3, "$ioname: SD_WS_Parse $deviceCode - ERROR temperature $temp";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
if (defined $hum) {
|
||||
if ($hum > 100) {
|
||||
Log3 $iohash, 3, "$ioname: SD_WS_Parse $deviceCode - ERROR humidity $hum";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
# Sanity checks
|
||||
if($def) {
|
||||
my $timeSinceLastUpdate = abs(ReadingsAge($name, "state", 0));
|
||||
# temperature
|
||||
if (defined($temp) && defined(ReadingsVal($name, "temperature", undef))) {
|
||||
my $diffTemp = 0;
|
||||
my $oldTemp = ReadingsVal($name, "temperature", undef);
|
||||
my $maxdeviation = AttrVal($name, "max-deviation-temp", 1); # default 1 K
|
||||
if ($temp > $oldTemp) {
|
||||
$diffTemp = ($temp - $oldTemp);
|
||||
} else {
|
||||
$diffTemp = ($oldTemp - $temp);
|
||||
}
|
||||
$diffTemp = sprintf("%.1f", $diffTemp);
|
||||
Log3 $name, 4, "$ioname: $name old temp $oldTemp, age $timeSinceLastUpdate, new temp $temp, diff temp $diffTemp";
|
||||
my $maxDiffTemp = $timeSinceLastUpdate / 60 + $maxdeviation; # maxdeviation + 1.0 Kelvin/Minute
|
||||
$maxDiffTemp = sprintf("%.1f", $maxDiffTemp + 0.05); # round 0.1
|
||||
Log3 $name, 4, "$ioname: $name max difference temperature $maxDiffTemp K";
|
||||
if ($diffTemp > $maxDiffTemp) {
|
||||
Log3 $name, 3, "$ioname: $name ERROR - Temp diff too large (old $oldTemp, new $temp, diff $diffTemp)";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
# humidity
|
||||
if (defined($hum) && defined(ReadingsVal($name, "humidity", undef))) {
|
||||
my $diffHum = 0;
|
||||
my $oldHum = ReadingsVal($name, "humidity", undef);
|
||||
my $maxdeviation = AttrVal($name, "max-deviation-hum", 1); # default 1 %
|
||||
if ($hum > $oldHum) {
|
||||
$diffHum = ($hum - $oldHum);
|
||||
} else {
|
||||
$diffHum = ($oldHum - $hum);
|
||||
}
|
||||
$diffHum = sprintf("%.1f", $diffHum);
|
||||
Log3 $name, 4, "$ioname: $name old hum $oldHum, age $timeSinceLastUpdate, new hum $hum, diff hum $diffHum";
|
||||
my $maxDiffHum = $timeSinceLastUpdate / 60 + $maxdeviation; # $maxdeviation + 1.0 %/Minute
|
||||
$maxDiffHum = sprintf("%1.f", $maxDiffHum + 0.5); # round 1
|
||||
Log3 $name, 4, "$ioname: $name max difference humidity $maxDiffHum %";
|
||||
if ($diffHum > $maxDiffHum) {
|
||||
Log3 $name, 3, "$ioname: $name ERROR - Hum diff too large (old $oldHum, new $hum, diff $diffHum)";
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log3 $name, 4, "$ioname: SD_WS_Parse $name ($rawData)";
|
||||
|
||||
$hash->{lastReceive} = time();
|
||||
$hash->{lastMSG} = $rawData;
|
||||
@ -603,17 +802,46 @@ sub SD_WS_Parse($$)
|
||||
$hash->{bitMSG} = $bitData;
|
||||
}
|
||||
|
||||
my $state = (($temp > -60 && $temp < 70) ? "T: $temp":"T: xx") . (($hum > 0 && $hum < 100) ? " H: $hum":"");
|
||||
#my $state = (($temp > -60 && $temp < 70) ? "T: $temp":"T: xx") . (($hum > 0 && $hum < 100) ? " H: $hum":"");
|
||||
my $state = "";
|
||||
if (defined($temp)) {
|
||||
$state .= "T: $temp"
|
||||
}
|
||||
if (defined($hum) && ($hum > 0 && $hum < 100)) {
|
||||
$state .= " H: $hum"
|
||||
}
|
||||
if (defined($windspeed)) {
|
||||
$state .= " " if (length($state) > 0);
|
||||
$state .= "W: $windspeed"
|
||||
}
|
||||
|
||||
### protocol 33 has different bits per sensor type
|
||||
if ($protocol eq "33") {
|
||||
if (AttrVal($name,'model',0) eq "S522") { # Conrad S522
|
||||
$bat = substr($bitData,36,1) eq "0" ? "ok" : "low";
|
||||
} elsif (AttrVal($name,'model',0) eq "E0001PA") { # renkforce E0001PA
|
||||
$bat = substr($bitData,35,1) eq "0" ? "ok" : "low";
|
||||
$sendmode = substr($bitData,34,1) eq "1" ? "manual" : "auto";
|
||||
} elsif (AttrVal($name,'model',0) eq "TX-EZ6") { # TZS First Austria TX-EZ6
|
||||
$bat = substr($bitData,35,1) eq "0" ? "ok" : "low";
|
||||
$sendmode = substr($bitData,34,1) eq "1" ? "manual" : "auto";
|
||||
$trendTemp = ('consistent', 'rising', 'falling', 'unknown')[SD_WS_binaryToNumber($bitData,10,11)];
|
||||
$trendHum = ('consistent', 'rising', 'falling', 'unknown')[SD_WS_binaryToNumber($bitData,36,37)];
|
||||
}
|
||||
}
|
||||
|
||||
readingsBeginUpdate($hash);
|
||||
readingsBulkUpdate($hash, "state", $state);
|
||||
readingsBulkUpdate($hash, "temperature", $temp) if (defined($temp)&& ($temp > -60 && $temp < 70 ));
|
||||
readingsBulkUpdate($hash, "temperature", $temp) if (defined($temp) && ($temp > -60 && $temp < 70 ));
|
||||
readingsBulkUpdate($hash, "humidity", $hum) if (defined($hum) && ($hum > 0 && $hum < 100 )) ;
|
||||
readingsBulkUpdate($hash, "battery", $bat) if (defined($bat) && length($bat) > 0) ;
|
||||
readingsBulkUpdate($hash, "windspeed", $windspeed) if (defined($windspeed)) ;
|
||||
readingsBulkUpdate($hash, "batteryState", $bat) if (defined($bat) && length($bat) > 0) ;
|
||||
readingsBulkUpdate($hash, "batteryState", $bat) if (defined($bat) && length($bat) > 0) ;
|
||||
readingsBulkUpdate($hash, "channel", $channel) 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);
|
||||
readingsBulkUpdate($hash, "humidityTrend", $trendHum) if (defined($trendHum) && length($trendHum) > 0);
|
||||
readingsBulkUpdate($hash, "sendmode", $sendmode) if (defined($sendmode) && length($sendmode) > 0);
|
||||
readingsEndUpdate($hash, 1); # Notify is done by Dispatch
|
||||
|
||||
return $name;
|
||||
@ -649,7 +877,6 @@ sub SD_WS_binaryToNumber
|
||||
my $fbit=shift;
|
||||
my $lbit=$fbit;
|
||||
$lbit=shift if @_;
|
||||
|
||||
return oct("0b".substr($binstr,$fbit,($lbit-$fbit)+1));
|
||||
}
|
||||
|
||||
@ -688,52 +915,88 @@ sub SD_WS_WH2SHIFT($){
|
||||
<a name="SD_WS"></a>
|
||||
<h3>Weather Sensors various protocols</h3>
|
||||
<ul>
|
||||
The SD_WS module interprets temperature sensor messages received by a Device like CUL, CUN, SIGNALduino etc.<br>
|
||||
<br>
|
||||
The SD_WS module processes the messages from various environmental sensors received from an IO device (CUL, CUN, SIGNALDuino, SignalESP etc.).<br><br>
|
||||
<b>Known models:</b>
|
||||
<ul>
|
||||
<li>Bresser 7009994</li>
|
||||
<li>Opus XT300</li>
|
||||
<li>BresserTemeo</li>
|
||||
<li>WH2 (TFA Dostmann/Wertheim 30.3157(Temperature only!) (sold in Germany), Agimex Rosenborg 66796 (sold in Denmark),ClimeMET CM9088 (Sold in UK)</li>
|
||||
<li>Conrad S522</li>
|
||||
<li>Opus XT300</li>
|
||||
<li>PV-8644 infactory Poolthermometer</li>
|
||||
</ul>
|
||||
<br>
|
||||
New received device are add in fhem with autocreate.
|
||||
<br><br>
|
||||
<li>Renkforce E0001PA</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>
|
||||
<li>Weatherstation TFA 35.1140.01 with temperature / humidity sensor TFA 30.3221.02 and temperature / humidity / windspeed sensor TFA 30.3222.02</li>
|
||||
</ul><br><br>
|
||||
|
||||
<a name="SD_WS_Define"></a>
|
||||
<b>Define</b>
|
||||
<ul>The received devices created automatically.<br>
|
||||
The ID of the defice is the cannel or, if the longid attribute is specified, it is a combination of channel and some random generated bits at powering the sensor and the channel.<br>
|
||||
If you want to use more sensors, than channels available, you can use the longid option to differentiate them.
|
||||
</ul>
|
||||
<br>
|
||||
<b>Define</b><br><br>
|
||||
<ul>
|
||||
Newly received sensors are usually automatically created in FHEM via autocreate.<br>
|
||||
It is also possible to set up the devices manually with the following command:<br><br>
|
||||
<code>define <name> SD_WS <code> </code> <br><br>
|
||||
<code> is the channel or individual identifier used to identify the sensor.<br>
|
||||
</ul><br><br>
|
||||
|
||||
<a name="SD_WS Events"></a>
|
||||
<b>Generated readings:</b>
|
||||
<br>Some devices may not support all readings, so they will not be presented<br>
|
||||
<b>Generated readings:</b><br><br>
|
||||
<ul>
|
||||
<li>State (T: H:)</li>
|
||||
<li>temperature (°C)</li>
|
||||
<li>humidity: (The humidity (1-100 if available)</li>
|
||||
<li>battery: (low or ok)</li>
|
||||
<li>channel: (The Channelnumber (number if)</li>
|
||||
</ul>
|
||||
<br>
|
||||
<b>Attributes</b>
|
||||
Some devices may not support all readings, so they will not be presented<br>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="#do_not_notify">do_not_notify</a></li>
|
||||
<li><a href="#ignore">ignore</a></li>
|
||||
<li><a href="#showtime">showtime</a></li>
|
||||
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
|
||||
</ul>
|
||||
|
||||
<a name="SD_WS_Set"></a>
|
||||
<b>Set</b> <ul>N/A</ul><br>
|
||||
|
||||
<a name="SD_WS_Parse"></a>
|
||||
<b>Set</b> <ul>N/A</ul><br>
|
||||
<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>temperature (°C)</li>
|
||||
<li>temperatureTrend (consistent, rising, falling)</li>
|
||||
</ul><br><br>
|
||||
|
||||
<a name="SD_WS Attribute"></a>
|
||||
<b>Attributes</b><br><br>
|
||||
<ul>
|
||||
<li><a href="#do_not_notify">do_not_notify</a></li><br>
|
||||
<li><a href="#ignore">ignore</a></li><br>
|
||||
<li>max-deviation-hum<br>
|
||||
(Default: 1, allowed values: 1,2,3,4,5,6,7,8,9,10,15,20,25,30,35,40,45,50)<br>
|
||||
<a name="max-deviation-hum"></a>
|
||||
Maximum permissible deviation of the measured humidity from the previous value in percent.<br>
|
||||
Since many of the sensors handled in the module do not have checksums, etc. send, it can easily come to the reception of implausible values.
|
||||
To intercept these, a maximum deviation from the last correctly received value can be set.
|
||||
Greater deviations are then ignored and result in an error message in the log file, such as an error message like this:<br>
|
||||
<code>SD_WS_TH_84 ERROR - Hum diff too large (old 60, new 68, diff 8)</code><br>
|
||||
In addition to the set value, a value dependent on the difference of the reception times is added.
|
||||
This is 1.0% relative humidity per minute.
|
||||
This means e.g. if a difference of 8 is set and the time interval of receipt of the messages is 3 minutes, the maximum allowable difference is 11.<br>
|
||||
Instead of the <code>max-deviation-hum</code> and <code>max-deviation-temp</code> attributes,
|
||||
the <code>doubleMsgCheck_IDs</code> attribute of the SIGNALduino can also be used if the sensor is well received.
|
||||
An update of the readings is only executed if the same values ??have been received at least twice.
|
||||
<a name="end_max-deviation-hum"></a>
|
||||
</li><br>
|
||||
<li>max-deviation-temp<br>
|
||||
(Default: 1, allowed values: 1,2,3,4,5,6,7,8,9,10,15,20,25,30,35,40,45,50)<br>
|
||||
<a name="max-deviation-temp"></a>
|
||||
Maximum permissible deviation of the measured temperature from the previous value in Kelvin.<br>
|
||||
Explanation see attribute "max-deviation-hum".
|
||||
<a name="end_max-deviation-temp"></a>
|
||||
</li><br>
|
||||
<li>model<br>
|
||||
(Default: other, currently supported sensors: E0001PA, S522)<br>
|
||||
<a name="model"></a>
|
||||
The sensors of the "SD_WS_33 series" use different positions for the battery bit and different readings.
|
||||
If the battery bit is detected incorrectly (low instead of ok), then you can possibly adjust with the model selection of the sensor.<br>
|
||||
So far, 3 variants are known. All sensors are created by Autocreate as model "other".
|
||||
If you receive a Conrad S522, Renkforce E0001PA or TX-EZ6, then set the appropriate model for the proper processing of readings.
|
||||
<a name="end_model"></a>
|
||||
</li><br>
|
||||
<li><a href="#readingFnAttributes">readingFnAttributes</a></li><br>
|
||||
<li><a href="#showtime">showtime</a></li><br>
|
||||
</ul><br>
|
||||
<b>Set</b>
|
||||
<ul>N/A</ul><br>
|
||||
</ul>
|
||||
|
||||
=end html
|
||||
@ -743,50 +1006,91 @@ sub SD_WS_WH2SHIFT($){
|
||||
<a name="SD_WS"></a>
|
||||
<h3>SD_WS</h3>
|
||||
<ul>
|
||||
Das SD_WS Modul verarbeitet von einem IO Gerät (CUL, CUN, SIGNALDuino, etc.) empfangene Nachrichten von Temperatur-Sensoren.<br>
|
||||
Das Modul SD_WS verarbeitet die von einem IO-Gerät (CUL, CUN, SIGNALDuino, SignalESP etc.) empfangenen Nachrichten verschiedener Umwelt-Sensoren.<br>
|
||||
<br>
|
||||
<b>Unterstützte Modelle:</b>
|
||||
<b>Unterstützte Modelle:</b><br><br>
|
||||
<ul>
|
||||
<li>Bresser 7009994</li>
|
||||
<li>Opus XT300</li>
|
||||
<li>BresserTemeo</li>
|
||||
<li>WH2 (TFA Dostmann/Wertheim 30.3157(Temperatur!) (Deutschland), Agimex Rosenborg 66796 (Denmark),ClimeMET CM9088 (UK)</li>
|
||||
<li>Conrad S522</li>
|
||||
<li>Opus XT300</li>
|
||||
<li>PV-8644 infactory Poolthermometer</li>
|
||||
</ul>
|
||||
<br>
|
||||
Neu empfangene Sensoren werden in FHEM per autocreate angelegt.
|
||||
<li>Renkforce E0001PA</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>
|
||||
<li>Wetterstation TFA 35.1140.01 mit Temperatur-/Feuchtesensor TFA 30.3221.02 und Temperatur-/Feuchte- und Windsensor TFA 30.3222.02</li>
|
||||
</ul>
|
||||
<br><br>
|
||||
|
||||
<a name="SD_WS_Define"></a>
|
||||
<b>Define</b>
|
||||
<ul>Die empfangenen Sensoren werden automatisch angelegt.<br>
|
||||
Die ID der angelgten Sensoren ist entweder der Kanal des Sensors, oder wenn das Attribut longid gesetzt ist, dann wird die ID aus dem Kanal und einer Reihe von Bits erzeugt, welche der Sensor beim Einschalten zufällig vergibt.<br>
|
||||
<b>Define</b><br><br>
|
||||
<ul>
|
||||
Neu empfangene Sensoren werden in FHEM normalerweise per autocreate automatisch angelegt.<br>
|
||||
Es ist auch möglich, die Geräte manuell mit folgendem Befehl einzurichten:<br><br>
|
||||
<code>define <name> SD_WS <code> </code> <br><br>
|
||||
<code> ist der Kanal oder eine individuelle Ident, mit dem der Sensor identifiziert wird.<br>
|
||||
</ul>
|
||||
<br>
|
||||
<br><br>
|
||||
|
||||
<a name="SD_WS Events"></a>
|
||||
<b>Generierte Readings:</b>
|
||||
<b>Generierte Readings:</b><br><br>
|
||||
<ul>(verschieden, je nach Typ des Sensors)</ul>
|
||||
<ul>
|
||||
<li>State (T: H:)</li>
|
||||
<li>temperature (°C)</li>
|
||||
<li>humidity: (Luftfeuchte (1-100)</li>
|
||||
<li>battery: (low oder ok)</li>
|
||||
<li>channel: (Der Sensor Kanal)</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>state (T: H: W:)</li>
|
||||
<li>temperature (°C)</li>
|
||||
<li>temperatureTrend (gleichbleibend, steigend, fallend)</li>
|
||||
<li>sendmode (Der Sendemodus, automatic oder manuell mittels Taster am Sender)</li>
|
||||
</ul>
|
||||
<br>
|
||||
<b>Attribute</b>
|
||||
<br><br>
|
||||
|
||||
<a name="SD_WS Attribute"></a>
|
||||
<b>Attribute</b><br><br>
|
||||
<ul>
|
||||
<li><a href="#do_not_notify">do_not_notify</a></li>
|
||||
<li><a href="#ignore">ignore</a></li>
|
||||
<li><a href="#showtime">showtime</a></li>
|
||||
<li><a href="#readingFnAttributes">readingFnAttributes</a></li>
|
||||
<li><a href="#do_not_notify">do_not_notify</a></li><br>
|
||||
<li><a href="#ignore">ignore</a></li><br>
|
||||
<li>max-deviation-hum<br>
|
||||
(Standard: 1, erlaubte Werte: 1,2,3,4,5,6,7,8,9,10,15,20,25,30,35,40,45,50)<br>
|
||||
<a name="max-deviation-hum"></a>
|
||||
Maximal erlaubte Abweichung der gemessenen Feuchte zum vorhergehenden Wert in Prozent.
|
||||
<br>Da viele der in dem Modul behandelten Sensoren keine Checksummen o.ä. senden, kann es leicht zum Empfang von unplausiblen Werten kommen.
|
||||
Um diese abzufangen, kann eine maximale Abweichung zum letzten korrekt empfangenen Wert festgelegt werden.
|
||||
Größere Abweichungen werden dann ignoriert und führen zu einer Fehlermeldung im Logfile, wie z.B. dieser:<br>
|
||||
<code>SD_WS_TH_84 ERROR - Hum diff too large (old 60, new 68, diff 8)</code><br>
|
||||
Zusätzlich zum eingestellten Wert wird ein von der Differenz der Empfangszeiten abhängiger Wert addiert.
|
||||
Dieser beträgt 1.0 % relative Feuchte pro Minute. Das bedeutet z.B. wenn eine Differenz von 8 eingestellt ist
|
||||
und der zeitliche Abstand des Empfangs der Nachrichten beträgt 3 Minuten, ist die maximal erlaubte Differenz 11.
|
||||
<br>Anstelle der Attribute <code>max-deviation-hum</code> und <code>max-deviation-temp</code> kann bei gutem Empfang des Sensors
|
||||
auch das Attribut <code>doubleMsgCheck_IDs</code> des SIGNALduino verwendet werden. Dabei wird ein Update der Readings erst
|
||||
ausgeführt, wenn mindestens zweimal die gleichen Werte empfangen wurden.
|
||||
<a name="end_max-deviation-hum"></a>
|
||||
</li><br>
|
||||
<li>max-deviation-temp<br>
|
||||
(Standard: 1, erlaubte Werte: 1,2,3,4,5,6,7,8,9,10,15,20,25,30,35,40,45,50)<br>
|
||||
<a name="max-deviation-temp"></a>
|
||||
Maximal erlaubte Abweichung der gemessenen Temperatur zum vorhergehenden Wert in Kelvin.<br>
|
||||
Erklärung siehe Attribut "max-deviation-hum".
|
||||
<a name="end_max-deviation-temp"></a>
|
||||
</li><br>
|
||||
<li>model<br>
|
||||
<a name="model"></a>
|
||||
(Standard: other, zur Zeit unterstützte Sensoren: E0001PA, S522, TX-EZ6)<br>
|
||||
Die Sensoren der "SD_WS_33 - Reihe" verwenden unterschiedliche Positionen für das Batterie-Bit und unterstützen verschiedene Readings.
|
||||
Sollte das Batterie-Bit falsch erkannt werden (low statt ok), so kann man mit der Modelauswahl des Sensors das evtl. anpassen.<br>
|
||||
Bisher sind 3 Varianten bekannt. Alle Sensoren werden durch Autocreate als Model "other" angelegt.
|
||||
Empfangen Sie einen Sensor vom Typ Conrad S522, Renkforce E0001PA oder TX-EZ6, so stellen Sie das jeweilige Modell für die richtige Verarbeitung der Readings ein.
|
||||
<a name="end_model"></a>
|
||||
</li><br>
|
||||
<li><a href="#readingFnAttributes">readingFnAttributes</a></li><br>
|
||||
<li><a href="#showtime">showtime</a></li><br>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<a name="SD_WS_Set"></a>
|
||||
<b>Set</b> <ul>N/A</ul><br>
|
||||
|
||||
<a name="SD_WS_Parse"></a>
|
||||
<b>Set</b> <ul>N/A</ul><br>
|
||||
|
||||
</ul>
|
||||
|
||||
=end html_DE
|
||||
|
Loading…
Reference in New Issue
Block a user