2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-04-09 13:45:33 +00:00

00_SIGNALduino.pm: updated IO Module to release 3.2 and logical modules: hideki, SD_WS07, SD_WS09, 90_SIGNALduino_un.pm and firmware

git-svn-id: https://svn.fhem.de/fhem/trunk@10921 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
mrsidey 2016-02-22 21:09:54 +00:00
parent e680854005
commit cca5cf1c78
10 changed files with 5280 additions and 3998 deletions

View File

@ -1,5 +1,17 @@
# 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.
- bugfix: 00_SIGNALduino: Version 3.2.0 Module & Firmware
serval fixes and enhacements
improved stability
supports many new protocol
Supports ITv3 sockets and switches
new sendMsg Function
You need to flash your SIGNALduino
with the new firmware.
- bugfix: 14_Hideki: support rain sensors
- bugfix: 14_SD_WS07: Fixed some wordings
- feature: 14_SD_WS09 Module for WH1080
(WS-0101, TFA30.3189) & CTW600 868MHz OOK/AS
- feature: TimeSeries: median, holdtime for event-aggregator
- feature: 57_CALVIEW: added internal notify-fn for calendar-devices,
added attr disable for internal notify-fn,

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
# see http://www.fhemwiki.de/wiki/SIGNALduino
# and was modified by a few additions
# to support Hideki Sensors
# S. Butzek & HJGode &Ralf9 2015
# S. Butzek & HJGode & Ralf9 2015-2016
#
package main;
@ -22,7 +22,7 @@ Hideki_Initialize($)
my ($hash) = @_;
$hash->{Match} = "^P12#75[A-F0-9]{17,30}"; # Länge (Anhahl nibbles nach 0x75 )noch genauer zpezifiieren
$hash->{Match} = "^P12#75[A-F0-9]{17,30}"; # Laenge (Anhahl nibbles nach 0x75 )noch genauer spezifizieren
$hash->{DefFn} = "Hideki_Define";
$hash->{UndefFn} = "Hideki_Undef";
$hash->{AttrFn} = "Hideki_Attr";
@ -91,42 +91,51 @@ Hideki_Parse($$)
Log3 $iohash, 4, "$name decrypt failed";
return undef;
}
my $sensorTyp=getSensorType($decodedBytes[3]);
Log3 $iohash, 4, "Hideki_Parse SensorTyp = $sensorTyp decodedString = $decodedString";
if (!Hideki_crc(\@decodedBytes))
{
Log3 $iohash, 4, "$name crc failed";
return undef;
}
my $sensorTyp=getSensorType($decodedBytes[3]);
Log3 $iohash, 4, "Hideki_Parse SensorTyp = $sensorTyp decodedString = $decodedString";
my $id=substr($decodedString,2,2); # get the random id from the data
my $channel=0;
my $temp=0;
my $hum=0;
my $rain=0;
my $rc;
my $val;
my $bat;
my $deviceCode;
my $model= "Hideki_$sensorTyp";
## 1. Detect what type of sensor we have, then calll specific function to decode
## 1. Detect what type of sensor we have, then call specific function to decode
if ($sensorTyp==0x1E){
($channel, $temp, $hum) = decodeThermoHygro(\@decodedBytes); # decodeThermoHygro($decodedString);
$bat = ($decodedBytes[2] >> 6 == 3) ? 'ok' : 'low'; # decode battery
$val = "T: $temp H: $hum Bat: $bat";
}else{
}elsif($sensorTyp==0x0E){
($channel, $rain) = decodeRain(\@decodedBytes); # decodeThermoHygro($decodedString);
$bat = ($decodedBytes[2] >> 6 == 3) ? 'ok' : 'low'; # decode battery
$val = "R: $rain Bat: $bat";
}
else{
Log3 $iohash, 4, "$name Sensor Typ $sensorTyp not supported, please report sensor information!";
return "$name Sensor Typ $sensorTyp not supported, please report sensor information!";
}
my $longids = AttrVal($iohash->{NAME},'longids',0);
if ( ($longids != 0) && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/)))
if ( ($longids ne "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/)))
{
$deviceCode = $model . "_" . $id;
$deviceCode=$model . "_" . $id . "." . $channel;
Log3 $iohash,4, "$name using longid: $longids model: $model";
} else {
$deviceCode = $model . "_" . $channel;
}
Log3 $iohash, 4, "$name decoded Hideki protocol model=$model, sensor id=$id, channel=$channel, temp=$temp, humidity=$hum, bat=$bat";
Log3 $iohash, 4, "$name decoded Hideki protocol model=$model, sensor id=$id, channel=$channel, temp=$temp, humidity=$hum, bat=$bat, rain=$rain";
Log3 $iohash, 5, "deviceCode: $deviceCode";
my $def = $modules{Hideki}{defptr}{$iohash->{NAME} . "." . $deviceCode};
@ -161,8 +170,14 @@ Hideki_Parse($$)
readingsBeginUpdate($hash);
readingsBulkUpdate($hash, "state", $val);
readingsBulkUpdate($hash, "battery", $bat) if ($bat ne "");
readingsBulkUpdate($hash, "humidity", $hum) if ($hum ne "");
readingsBulkUpdate($hash, "temperature", $temp) if ($temp ne "");
readingsBulkUpdate($hash, "channel", $channel) if ($channel ne "");
if ($sensorTyp==0x1E){
readingsBulkUpdate($hash, "humidity", $hum) if ($hum ne "");
readingsBulkUpdate($hash, "temperature", $temp) if ($temp ne "");
}
elsif($sensorTyp==0x0E){
readingsBulkUpdate($hash, "rain", $rain) if ($rain ne "");
}
readingsEndUpdate($hash, 1); # Notify is done by Dispatch
return $name;
@ -276,6 +291,46 @@ sub decodeThermoHygro {
return ($channel, $temp, $humi);
}
# decode byte array and return channel and total rain in mm
# input: decrypted byte array starting with 0x75, passed by reference as in mysub(\@array);
# output <return code>, <channel>, <totalrain>
# was unable to get this working with an array ref as input, so switched to hex string input
sub decodeRain {
my @Hidekibytes = @{$_[0]};
#my $Hidekihex = shift;
#my @Hidekibytes=();
#for (my $i=0; $i<(length($Hidekihex))/2; $i++){
# my $hex=hex(substr($Hidekihex, $i*2, 2)); ## Mit split und map geht es auch ... $str =~ /(..?)/g;
# push (@Hidekibytes, $hex);
#}
my $channel=0;
my $rain=0;
my $tests=0;
#additional checks?
if($Hidekibytes[2]==0xCC){
$tests+=1;
}
if($Hidekibytes[6]==0x66){
$tests+=1;
}
# possibly test if $tests==2 for sanity check
#printf("SANITY CHECK tests=%i\n", $tests);
$channel = $Hidekibytes[1] >> 5;
# //Internally channel 4 is used for the other sensor types (rain, uv, anemo).
# //Therefore, if channel is decoded 5 or 6, the real value set on the device itself is 4 resp 5.
if ($channel >= 5) {
$channel--;
}
my $sensorId = $Hidekibytes[1] & 0x1f; # Extract random id from sensor
$rain = ($Hidekibytes[4] + $Hidekibytes[5]*0xff)*0.7;
return ($channel, $rain);
}
sub
Hideki_Attr(@)
{
@ -337,6 +392,7 @@ Hideki_Attr(@)
<li>temperature (&deg;C)</li>
<li>humidity (0-100)</li>
<li>battery (ok or low)</li>
<li>channel (The Channelnumber (number if)</li>
</ul>
@ -369,7 +425,7 @@ Hideki_Attr(@)
<br><br>
<a name="Hideki_define"></a>
<b>Unterstützte Hersteller</b>
<b>Unterstuetzte Hersteller</b>
<ul>
<li>Hama</li>
<li>Bresser</li>
@ -390,7 +446,7 @@ Hideki_Attr(@)
&lt;code&gt; besteht aus dem Sensortyp und der Kanalnummer (1..5) oder wenn das Attribut longid im IO Device gesetzt ist aus einer Zufallsadresse, die durch den Sensor beim einlegen der
Batterie generiert wird (Die Adresse aendert sich bei jedem Batteriewechsel).<br>
</li>
<li>Wenn autocreate aktiv ist, dann wird der Sensor automatisch in FHEM angelegt. Das ist der empfohlene Weg, neue Sensoren hinzuzufügen.</li>
<li>Wenn autocreate aktiv ist, dann wird der Sensor automatisch in FHEM angelegt. Das ist der empfohlene Weg, neue Sensoren hinzuzufuegen.</li>
</ul>
<br>
@ -402,6 +458,7 @@ Hideki_Attr(@)
<li>temperature (&deg;C)</li>
<li>humidity (0-100)</li>
<li>battery (ok or low)</li>
<li>channel (Der Sensor Kanal)</li>
</ul>
<a name="Hideki_unset"></a>
<b>Set</b> <ul>N/A</ul><br>

View File

@ -1,10 +1,9 @@
##############################################
##############################################
# $Id$
#
# The purpose of this module is to support serval eurochron
# weather sensors like eas8007 which use the same protocol
# Sidey79 & Ralf9 2015
# Sidey79 & Ralf9 2015-2016
#
package main;
@ -81,7 +80,6 @@ SD_WS07_Parse($$)
my $hlen = length($rawData);
my $blen = $hlen * 4;
my $bitData = unpack("B$blen", pack("H$hlen", $rawData));
Log3 $name, 4, "SD_WS07_Parse $model ($msg) length: $hlen";
@ -117,23 +115,24 @@ SD_WS07_Parse($$)
}
if ($hum > 100) {
return undef; # Eigentlich müsste sowas wie ein skip rein, damit ggf. später noch weitre Sensoren dekodiert werden können.
return undef; # Eigentlich muesste sowas wie ein skip rein, damit ggf. spaeter noch weitre Sensoren dekodiert werden koennen.
}
if ($temp > 700 && $temp < 3840) {
return undef;
} elsif ($temp >= 3840) { # negative Temperaturen, muß noch ueberprueft und optimiert werden
} elsif ($temp >= 3840) { # negative Temperaturen, muss noch ueberprueft und optimiert werden
$temp -= 4095;
}
$temp /= 10;
Log3 $iohash, 4, "$model decoded protocolid: 7 sensor id=$id, channel=$channel, temp=$temp, hum=$hum, bat=$bat" ;
Log3 $iohash, 4, "$model decoded protocolid: 7 sensor id=$id, channel=$channel, temp=$temp, hum=$hum, bat=$bat";
my $deviceCode;
my $longids = AttrVal($iohash->{NAME},'longids',0);
if ( ($longids != 0) && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/)))
if ( ($longids ne "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/)))
{
$deviceCode=$model."_".$id.$channel;
$deviceCode=$model.'_'.$id.$channel;
Log3 $iohash,4, "$name using longid: $longids model: $model";
} else {
$deviceCode = $model . "_" . $channel;
@ -150,10 +149,9 @@ SD_WS07_Parse($$)
}
#Log3 $iohash, 3, 'SD_WS07: ' . $def->{NAME} . ' ' . $id;
my $hash = $def;
$name = $hash->{NAME};
Log3 $name, 5, "SD_WS07: $name ($rawData)";
Log3 $name, 4, "SD_WS07: $name ($rawData)";
if (!defined(AttrVal($hash->{NAME},"event-min-interval",undef)))
{
@ -164,9 +162,9 @@ SD_WS07_Parse($$)
}
}
$def->{lastMSG} = $rawData;
$def->{bitMSG} = $bitData2;
$hash->{lastReceive} = time();
$hash->{lastMSG} = $rawData;
$hash->{bitMSG} = $bitData2;
my $state = "T: $temp". ($hum>0 ? " H: $hum":"");
@ -261,12 +259,14 @@ sub SD_WS07_Attr(@)
<a name="SD_WS07"></a>
<h3>SD_WS07</h3>
<ul>
Das SD_WS07 Module verarbeitet von einem IO Gerät (CUL, CUN, SIGNALDuino, etc.) empfangene Nachrichten von Temperatur-Sensoren.<br>
Das SD_WS07 Module verarbeitet von einem IO Geraet (CUL, CUN, SIGNALDuino, etc.) empfangene Nachrichten von Temperatur-Sensoren.<br>
<br>
<b>Unterstütze Modelle:</b>
<b>Unterstuetze Modelle:</b>
<ul>
<li>Eurochon EAS800z</li>
<li>Technoline WS6750/TX70DTH</li>
<li>TFA 30320902</li>
<li>FreeTec Aussenmodul fuer Wetterstation NC-7344</li>
</ul>
<br>
Neu empfangene Sensoren werden in FHEM per autocreate angelegt.
@ -275,7 +275,7 @@ sub SD_WS07_Attr(@)
<a name="SD_WS07_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>
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 zufaellig vergibt.<br>
</ul>
<br>
<a name="SD_WS07 Events"></a>

411
fhem/FHEM/14_SD_WS09.pm Normal file
View File

@ -0,0 +1,411 @@
##############################################
##############################################
# $Id$
#
# The purpose of this module is to support serval
# weather sensors like WS-0101 (Sender 868MHz ASK Epmfänger RX868SH-DV elv)
# Sidey79 & pejonp 2015
#
package main;
use strict;
use warnings;
#use Math::Round qw/nearest/;
sub SD_WS09_Initialize($)
{
my ($hash) = @_;
$hash->{Match} = "^P9#[A-Fa-f0-9]+"; ## pos 7 ist aktuell immer 0xF
$hash->{DefFn} = "SD_WS09_Define";
$hash->{UndefFn} = "SD_WS09_Undef";
$hash->{ParseFn} = "SD_WS09_Parse";
$hash->{AttrFn} = "SD_WS09_Attr";
$hash->{AttrList} = "IODev do_not_notify:1,0 ignore:0,1 showtime:1,0 "
."windKorrektur:-3,-2,-1,0,1,2,3 "
."$readingFnAttributes ";
$hash->{AutoCreate} =
{ "SD_WS09.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.* windKorrektur:.*:0", FILTER => "%NAME", GPLOT => "temp4hum4:Temp/Hum,", autocreateThreshold => "2:180"} };
}
#############################
sub SD_WS09_Define($$)
{
my ($hash, $def) = @_;
my @a = split("[ \t][ \t]*", $def);
return "wrong syntax: define <name> SD_WS09 <code> ".int(@a)
if(int(@a) < 3 );
$hash->{CODE} = $a[2];
$hash->{lastMSG} = "";
$hash->{bitMSG} = "";
$modules{SD_WS09}{defptr}{$a[2]} = $hash;
$hash->{STATE} = "Defined";
my $name= $hash->{NAME};
return undef;
}
#####################################
sub SD_WS09_Undef($$)
{
my ($hash, $name) = @_;
delete($modules{SD_WS09}{defptr}{$hash->{CODE}})
if(defined($hash->{CODE}) &&
defined($modules{SD_WS09}{defptr}{$hash->{CODE}}));
return undef;
}
###################################
sub SD_WS09_Parse($$)
{
my ($iohash, $msg) = @_;
my $name = $iohash->{NAME};
my (undef ,$rawData) = split("#",$msg);
my @winddir_name=("N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW");
my $hlen = length($rawData);
my $blen = $hlen * 4;
my $bitData = unpack("B$blen", pack("H$hlen", $rawData));
my $rain = 0;
my $deviceCode = 0;
my $model = "undef"; # 0xFFA -> WS0101/WH1080 alles andere -> CTW600
my $modelid;
my $windSpeed = 0;
my $windguest =0;
my $sensdata;
my $id;
my $bat = 0;
my $temp;
my $hum;
my $windDirection ;
my $windDirectionText;
Log3 $name, 4, "SD_WS09_Parse HEX=$msg length: $hlen";
my $syncpos= index($bitData,"11111110"); #7x1 1x0 preamble
Log3 $iohash, 3, "SD_WS09_Parse Bin=$bitData syncp=$syncpos length:".length($bitData) ;
if ($syncpos ==-1 || length($bitData)-$syncpos < 78)
{
Log3 $iohash, 3, "EXIT SD_WS09_Parse msg=$rawData syncp=$syncpos length:".length($bitData) ;
return undef;
}
my $wh = substr($bitData,0,8);
if($wh == "11111111") {
$sensdata = substr($bitData,8);
my $whid = substr($sensdata,0,4);
if( $whid == "1010" ){ # A
Log3 $iohash, 3, "WH SD_WS09_Parse WH=$wh msg=$sensdata syncp=$syncpos length:".length($sensdata) ;
$model = "WH1080";
$id = SD_WS09_bin2dec(substr($sensdata,4,8));
$bat = (SD_WS09_bin2dec((substr($sensdata,64,4))) == 0) ? 'ok':'low' ; # decode battery = 0 --> ok
$temp = (SD_WS09_bin2dec(substr($sensdata,12,12)) - 400)/10;
$hum = SD_WS09_bin2dec(substr($sensdata,24,8));
$windDirection = SD_WS09_bin2dec(substr($sensdata,68,4));
$windDirectionText = $winddir_name[$windDirection];
$windSpeed = round((SD_WS09_bin2dec(substr($sensdata,32,8))* 34)/100,01);
Log3 $iohash, 3, "SD_WS09_Parse ".$model." Windspeed bit: ".substr($sensdata,32,8)." Dec: " . $windSpeed ;
$windguest = round((SD_WS09_bin2dec(substr($sensdata,40,8)) * 34)/100,01);
Log3 $iohash, 3, "SD_WS09_Parse ".$model." Windguest bit: ".substr($sensdata,40,8)." Dec: " . $windguest ;
$rain = SD_WS09_bin2dec(substr($sensdata,56,8)) * 0.3;
Log3 $iohash, 3, "SD_WS09_Parse ".$model." Rain bit: ".substr($sensdata,56,8)." Dec: " . $rain ;
} else {
if( $whid == "1011" ){ # B DCF-77 Zeitmeldungen vom Sensor
my $hrs1 = substr($sensdata,16,8);
my $hrs;
my $mins;
my $sec;
my $mday;
my $month;
my $year;
Log3 $iohash, 3, "Zeitmeldung SD_WS09_Parse HRS1=$hrs1" ;
# $hrs = SD_WS09_BCD2bin(substr($sensdata,16,8) & 0x3F) ; #h
$hrs = SD_WS09_BCD2bin(substr($sensdata,18,6) ) ; # Stunde
$mins = SD_WS09_BCD2bin(substr($sensdata,24,8)); # Minute
$sec = SD_WS09_BCD2bin(substr($sensdata,32,8)); # Sekunde
#day month year
$year = SD_WS09_BCD2bin(substr($sensdata,40,8)); # Jahr
#$month = SD_WS09_BCD2bin(substr($sensdata,48,8) & 0x1f); #d
$month = SD_WS09_BCD2bin(substr($sensdata,51,5)); # Monat
$mday = SD_WS09_BCD2bin(substr($sensdata,56,8)); # Tag
Log3 $iohash, 3, "Zeitmeldung SD_WS09_Parse msg=$rawData syncp=$syncpos length:".length($bitData) ;
Log3 $iohash, 3, "Zeitmeldung SD_WS09_Parse HH:mm:ss - ".$hrs.":".$mins.":".$sec ;
Log3 $iohash, 3, "Zeitmeldung SD_WS09_Parse dd:mm:yy - ".$mday.":".$month.":".$year ;
}
Log3 $iohash, 3, "Zeitmeldung SD_WS09_Parse msg=$rawData syncp=$syncpos length:".length($sensdata) ;
return undef;
}
}else{
# eine CTW600 wurde erkannt
$sensdata = substr($bitData,$syncpos+8);
Log3 $iohash, 3, "WH_2 SD_WS09_Parse WH=$wh msg=$sensdata syncp=$syncpos length:".length($sensdata) ;
$model = "CTW600";
$modelid = substr($sensdata,0,4);
Log3 $iohash, 3, "SD_WS09_Parse Id: ".$modelid." Bin-Sync=$sensdata syncp=$syncpos length:".length($sensdata) ;
$bat = SD_WS09_bin2dec((substr($sensdata,0,3))) ;
$id = SD_WS09_bin2dec(substr($sensdata,4,6));
$temp = (SD_WS09_bin2dec(substr($sensdata,12,10)) - 400)/10;
$hum = SD_WS09_bin2dec(substr($sensdata,22,8));
$windDirection = SD_WS09_bin2dec(substr($sensdata,66,4));
$windDirectionText = $winddir_name[$windDirection];
$windSpeed = round(SD_WS09_bin2dec(substr($sensdata,30,16))/240,01);
Log3 $iohash, 3, "SD_WS09_Parse ".$model." Windspeed bit: ".substr($sensdata,32,8)." Dec: " . $windSpeed ;
$windguest = round((SD_WS09_bin2dec(substr($sensdata,40,8)) * 34)/100,01);
Log3 $iohash, 3, "SD_WS09_Parse ".$model." Windguest bit: ".substr($sensdata,40,8)." Dec: " . $windguest ;
$rain = round(SD_WS09_bin2dec(substr($sensdata,46,16)) * 0.3,01);
Log3 $iohash, 3, "SD_WS09_Parse ".$model." Rain bit: ".substr($sensdata,46,16)." Dec: " . $rain ;
}
Log3 $iohash, 3, "SD_WS09_Parse ".$model." id:$id :$sensdata ";
Log3 $iohash, 3, "SD_WS09_Parse ".$model." id:$id, bat:$bat, temp=$temp, hum=$hum, winddir=$windDirection:$windDirectionText wS=$windSpeed, wG=$windguest, rain=$rain";
if($hum > 100 || $hum < 0) {
Log3 $iohash, 3, "Hum SD_WS09_Parse hum=$hum msg=$rawData " ;
return undef;
}
my $longids = AttrVal($iohash->{NAME},'longids',0);
if ( ($longids ne "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/)))
{
$deviceCode=$model."_".$id;
Log3 $iohash,4, "$name using longid: $longids model: $model";
} else {
$deviceCode = $model;
}
my $def = $modules{SD_WS09}{defptr}{$iohash->{NAME} . "." . $deviceCode};
$def = $modules{SD_WS09}{defptr}{$deviceCode} if(!$def);
if(!$def) {
Log3 $iohash, 1, 'SD_WS09: UNDEFINED sensor ' . $model . ' detected, code ' . $deviceCode;
return "UNDEFINED $deviceCode SD_WS09 $deviceCode";
}
my $hash = $def;
$name = $hash->{NAME};
Log3 $name, 4, "SD_WS09_Parse: $name ($rawData)";
my $windkorr = AttrVal($hash->{NAME},'windKorrektur',0);
if ($windkorr != 0 )
{
my $oldwinddir = $windDirection;
$windDirection = $windDirection + $windkorr;
$windDirectionText = $winddir_name[$windDirection];
Log3 $iohash, 3, "SD_WS09_Parse ".$model." Faktor:$windkorr wD:$oldwinddir Korrektur wD:$windDirection:$windDirectionText" ;
}
if (!defined(AttrVal($hash->{NAME},"event-min-interval",undef)))
{
my $minsecs = AttrVal($iohash->{NAME},'minsecs',0);
if($hash->{lastReceive} && (time() - $hash->{lastReceive} < $minsecs)) {
Log3 $hash, 4, "$deviceCode Dropped due to short time. minsecs=$minsecs";
return "";
}
}
$def->{lastMSG} = $rawData;
#$def->{bitMSG} = $bitData2;
my $state = "T: $temp ". ($hum>0 ? " H: $hum ":" ")." Ws: $windSpeed "." Wg: $windguest "." Wd: $windDirectionText "." R: $rain";
# my $state = "T: $temp". ($hum>0 ? " H: $hum":"");
readingsBeginUpdate($hash);
readingsBulkUpdate($hash, "state", $state);
readingsBulkUpdate($hash, "temperature", $temp) if ($temp ne"");
readingsBulkUpdate($hash, "humidity", $hum) if ($hum ne "" && $hum != 0 );
readingsBulkUpdate($hash, "battery", $bat) if ($bat ne "");
readingsBulkUpdate($hash, "id", $id) if ($id ne "");
#zusätzlich Daten für Wetterstation
readingsBulkUpdate($hash, "rain", $rain );
readingsBulkUpdate($hash, "windGust", $windguest );
readingsBulkUpdate($hash, "windSpeed", $windSpeed );
readingsBulkUpdate($hash, "windDirectionDegree", $windDirection );
readingsBulkUpdate($hash, "windDirectionText", $windDirectionText );
readingsEndUpdate($hash, 1); # Notify is done by Dispatch
return $name;
}
sub SD_WS09_Attr(@)
{
my @a = @_;
# Make possible to use the same code for different logical devices when they
# are received through different physical devices.
return if($a[0] ne "set" || $a[2] ne "IODev");
my $hash = $defs{$a[1]};
my $iohash = $defs{$a[3]};
my $cde = $hash->{CODE};
delete($modules{SD_WS09}{defptr}{$cde});
$modules{SD_WS09}{defptr}{$iohash->{NAME} . "." . $cde} = $hash;
return undef;
}
sub SD_WS09_bin2dec($)
{
my $h = shift;
my $int = unpack("N", pack("B32",substr("0" x 32 . $h, -32)));
return sprintf("%d", $int);
}
sub SD_WS09_binflip($)
{
my $h = shift;
my $hlen = length($h);
my $i = 0;
my $flip = "";
for ($i=$hlen-1; $i >= 0; $i--) {
$flip = $flip.substr($h,$i,1);
}
return $flip;
}
sub SD_WS09_BCD2bin($) {
my $BCD = shift;
return (10 * ($BCD >> 4 & 0xF) + ($BCD & 0xF));
}
1;
=pod
=begin html
<a name="SD_WS09"></a>
<h3>Wether Sensors protocol #9</h3>
<ul>
The SD_WS09 module interprets temperature sensor messages received by a Device like CUL, CUN, SIGNALduino etc.<br>
<br>
<b>Known models:</b>
<ul>
<li>WS-0101 --> Model: WH1080</li>
<li>TFA 30.3189 / WH1080 --> Model: WH1080</li>
<li>1073 (WS1080) --> Model: WH1080</li>
<li>CTW600 --> Model: CTW600 (??) </li>
</ul>
<br>
New received device are add in fhem with autocreate.
<br><br>
<a name="SD_WS09_Define"></a>
<b>Define</b>
<ul>The received devices created automatically.<br>
The ID of the defice is the model or, if the longid attribute is specified, it is a combination of model and some random generated bits at powering the sensor.<br>
If you want to use more sensors, you can use the longid option to differentiate them.
</ul>
<br>
<a name="SD_WS09 Events"></a>
<b>Generated readings:</b>
<br>Some devices may not support all readings, so they will not be presented<br>
<ul>
<li>State (T: H: Ws: Wg: Wd: R: ) temperature, humidity, windSpeed, windGuest, windDirection, Rain</li>
<li>Temperature (&deg;C)</li>
<li>Humidity: (The humidity (1-100 if available)</li>
<li>Battery: (low or ok)</li>
<li>ID: (The ID-Number (number if)</li>
<li>windSpeed (m/s) and windDirection (N-O-S-W)</li>
<li>Rain (mm)</li>
</ul>
<br>
<b>Attributes</b>
<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>model<br>
WH1080, CTW600
</li><br>
<li>windKorrektur<br>
-3,-2,-1,0,1,2,3
</li><br>
</ul>
<a name="SD_WS09_Set"></a>
<b>Set</b> <ul>N/A</ul><br>
<a name="SD_WS09_Parse"></a>
<b>Set</b> <ul>N/A</ul><br>
</ul>
=end html
=begin html_DE
<a name="SD_WS09"></a>
<h3>SD_WS09</h3>
<ul>
Das SD_WS09 Module verarbeitet von einem IO Gerät (CUL, CUN, SIGNALDuino, etc.) empfangene Nachrichten von Temperatur-Sensoren.<br>
<br>
<b>Unterstütze Modelle:</b>
<ul>
<li>WS-0101 --> Model: WH1080</li>
<li>TFA 30.3189 / WH1080 --> Model: WH1080</li>
<li>1073 (WS1080) --> Model: WH1080</li>
<li>CTW600 --> Model: CTW600 (nicht getestet) </li>
</ul>
<br>
Neu empfangene Sensoren werden in FHEM per autocreate angelegt.
<br><br>
<a name="SD_WS09_Define"></a>
<b>Define</b>
<ul>Die empfangenen Sensoren werden automatisch angelegt.<br>
Die ID der angelegten Sensoren wird nach jedem Batteriewechsel geändert, welche der Sensor beim Einschalten zufällig vergibt.<br>
CRC Checksumme wird zur Zeit noch nicht überprüft, deshalb werden Sensoren bei denen die Luftfeuchte < 0 oder > 100 ist, nicht angelegt.<br>
</ul>
<br>
<a name="SD_WS09 Events"></a>
<b>Generierte Readings:</b>
<ul>
<li>State (T: H: Ws: Wg: Wd: R: ) temperature, humidity, windSpeed, windGuest, windDirection, Rain</li>
<li>Temperature (&deg;C)</li>
<li>Humidity: (The humidity (1-100 if available)</li>
<li>Battery: (low or ok)</li>
<li>ID: (The ID-Number (number if)</li>
<li>windSpeed (m/s) and windDirection (N-O-S-W)</li>
<li>Rain (mm)</li>
</ul>
<br>
<b>Attribute</b>
<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>model<br>
WH1080, CTW600
</li><br>
<li>windKorrektur<br>
Korrigiert die Nord-Ausrichtung des Windrichtungsmessers, wenn dieser nicht richtig nach Norden ausgerichtet ist.
-3,-2,-1,0,1,2,3
</li><br>
</ul>
<a name="SD_WS09_Set"></a>
<b>Set</b> <ul>N/A</ul><br>
<a name="SD_WS09_Parse"></a>
<b>Set</b> <ul>N/A</ul><br>
</ul>
=end html_DE
=cut

View File

@ -188,13 +188,16 @@ SIGNALduino_un_Parse($$)
Log3 $hash, 4, "$name found ctw600 syncpos at $syncpos message is: $sensdata - sensor id:$id, bat:$bat, temp=$temp, hum=$hum, wind=$wind, rain=$rain, winddir=$winddir";
} elsif ($protocol == "13" && length($bitData)>=14) ## RF20 Protocol
} elsif ($protocol == "13" && length($bitData)>=14) ## RF21 Protocol
{
my $model=$a[3];
my $deviceCode = $a[5].$a[6].$a[7].$a[8].$a[9];
my $Freq = $a[10].$a[11].$a[12].$a[13].$a[14];
#my $model=$a[3];
#my $deviceCode = $a[5].$a[6].$a[7].$a[8].$a[9];
#my $Freq = $a[10].$a[11].$a[12].$a[13].$a[14];
my $deviceCode = substr($bitData,0,23);
my $unit= substr($bitData,23,1);
Log3 $hash, 4, "$name found RF21 protocol. model=$model, devicecode=$deviceCode, freq=$Freq ";
Log3 $hash, 4, "$name found RF21 protocol. devicecode=$deviceCode, unit=$unit";
}
elsif ($protocol == "14" && length($bitData)>=12) ## Heidman HX
{
@ -218,20 +221,21 @@ SIGNALduino_un_Parse($$)
{
Log3 $hash, 4, "$name / shutter Dooya $bitData received";
Log3 $hash,4, substr($bitData,0,23)." ".substr($bitData,24,4)." ".substr($bitData,28,4)." ".substr($bitData,32,4)." ".substr($bitData,36,4);
my $id = SIGNALduino_un_binaryToNumber($bitData,0,23);
my $remote = SIGNALduino_un_binaryToNumber($bitData,24,27);
my $channel = SIGNALduino_un_binaryToNumber($bitData,28,31);
my $id = oct("0b".substr($bitData,0,29));
my $channel = oct("0b".substr($bitData,29,3));
my $all = ($channel == 0) ? 1 : 0;
my $commandcode = oct("0b".substr($bitData,33,4));
my $all = ($channel == 0) ? "true" : "false";
my $commandcode = SIGNALduino_un_binaryToNumber($bitData,32,35);
my $direction="";
if ($commandcode == 0b001) {$direction="up";}
elsif ($commandcode == 0b011) {$direction="down";}
elsif ($commandcode == 0b101) {$direction="stop";}
if ($commandcode == 0b0001) {$direction="up";}
elsif ($commandcode == 0b0011) {$direction="down";}
elsif ($commandcode == 0b0101) {$direction="stop";}
elsif ($commandcode == 0b1100) {$direction="learn";}
else { $direction="unknown";}
Log3 $hash, 4, "$name found shutter from Dooya. id=$id, channel=$channel, direction=$direction, all_shutters=$all";
Log3 $hash, 4, "$name found shutter from Dooya. id=$id, remotetype=$remote, channel=$channel, direction=$direction, all_shutters=$all";
}
elsif ($protocol == "21" && length($bitData)>=32) ##Einhell doorshutter
{
@ -259,6 +263,50 @@ SIGNALduino_un_Parse($$)
Log3 $hash, 4, "$name decoded protocolid: 7 ($SensorTyp / type=$type) mode=$sendMode, sensor id=$id, channel=$channel, temp=$temp, bat=$bat\n" ;
} elsif ($protocol == "33" && length($bitData)>=42) ## S014 or tcm sensor
{
my $SensorTyp = "s014/TFA 30.3200/TCM/Conrad";
my $id = SIGNALduino_un_binaryToNumber($bitData,0,9);
#my $unknown1 = SIGNALduino_un_binaryToNumber($bitData,8,10);
my $sendMode = SIGNALduino_un_binaryToNumber($bitData,10,11) eq "1" ? "manual" : "auto";
my $channel = SIGNALduino_un_binaryToNumber($bitData,12,13)+1;
#my $temp = (((oct("0b".substr($bitData,22,4))*256) + (oct("0b".substr($bitData,18,4))*16) + (oct("0b".substr($bitData,14,4)))/10) - 90 - 32) * (5/9);
my $temp = (((SIGNALduino_un_binaryToNumber($bitData,22,25)*256 + SIGNALduino_un_binaryToNumber($bitData,18,21)*16 + SIGNALduino_un_binaryToNumber($bitData,14,17)) *10 -12200) /18)/10;
my $hum=SIGNALduino_un_binaryToNumber($bitData,30,33)*16 + SIGNALduino_un_binaryToNumber($bitData,26,29);
my $bat = SIGNALduino_un_binaryToBoolean($bitData,34) eq "1" ? "ok" : "critical"; # Eventuell falsch!
my $sync = SIGNALduino_un_binaryToBoolean($bitData,35,35) eq "1" ? "true" : "false";
my $unknown3 =SIGNALduino_un_binaryToNumber($bitData,36,37);
my $crc=substr($bitData,36,4);
Log3 $hash, 4, "$name decoded protocolid: $protocol ($SensorTyp ) mode=$sendMode, sensor id=$id, channel=$channel, temp=$temp, hum=$hum, bat=$bat, crc=$crc, sync=$sync, unkown3=$unknown3\n" ;
} elsif ($protocol == "37" && length($bitData)>=40) ## Bresser 7009993
{
# 0 7 8 9 10 12 22 25 31
# 01011010 0 0 01 01100001110 10 0111101 11001010
# ID B? T Kan Temp ?? Hum Pruefsumme?
#
my $SensorTyp = "Bresser 7009994";
my $id = SIGNALduino_un_binaryToNumber($bitData,0,7);
my $channel = SIGNALduino_un_binaryToNumber($bitData,10,11);
my $hum=SIGNALduino_un_binaryToNumber($bitData,25,31);
my $rawTemp = SIGNALduino_un_binaryToNumber($bitData,12,22);
my $temp = ($rawTemp - 609.93) / 9.014;
$temp = sprintf("%.2f", $temp);
my $bitData2 = substr($bitData,0,8) . ' ' . substr($bitData,8,4) . ' ' . substr($bitData,12,11);
$bitData2 = $bitData2 . ' ' . substr($bitData,23,2) . ' ' . substr($bitData,25,7) . ' ' . substr($bitData,32,8);
Log3 $hash, 4, "$name converted to bits: " . $bitData2;
Log3 $hash, 4, "$name decoded protocolid: $protocol ($SensorTyp) sensor id=$id, channel=$channel, rawTemp=$rawTemp, temp=$temp, hum=$hum";
} else {
return $dummyreturnvalue;
}
@ -286,6 +334,28 @@ SIGNALduino_un_Attr(@)
}
# binary string, fistbit #, lastbit #
sub
SIGNALduino_un_binaryToNumber
{
my $binstr=shift;
my $fbit=shift;
my $lbit=$fbit;
$lbit=shift if @_;
return oct("0b".substr($binstr,$fbit,($lbit-$fbit)+1));
}
sub
SIGNALduino_un_binaryToBoolean
{
return int(SIGNALduino_un_binaryToNumber(@_));
}
sub
SIGNALduino_un_bin2dec($)
@ -355,8 +425,8 @@ SIGNALduino_un_binflip($)
<a name="SIGNALduino_un"></a>
<h3>SIGNALduino_un</h3>
<ul>
Das SIGNALduino_un module ist ein Hilfsmodul um unbekannte Nachrichten debuggen und analysieren zu können.
Das Modul legt keinerlei Geräte oder ähnliches an.
Das SIGNALduino_un module ist ein Hilfsmodul um unbekannte Nachrichten debuggen und analysieren zu koennen.
Das Modul legt keinerlei Geraete oder aehnliches an.
<br><br>
<a name="SIGNALduino_undefine"></a>
@ -364,10 +434,10 @@ SIGNALduino_un_binflip($)
<code>define &lt;name&gt; SIGNALduino_un &lt;code&gt; </code> <br>
<br>
Es ist möglich ein Gerät manuell zu definieren, aber damit passiert überhaupt nichts.
Autocreate wird auch keinerlei Geräte aus diesem Modul anlegen.
Es ist moeglich ein Geraet manuell zu definieren, aber damit passiert ueberhaupt nichts.
Autocreate wird auch keinerlei Geraete aus diesem Modul anlegen.
<br>
Die einzgeste Funktion dieses Modules ist, ab Verbose 4 Logmeldungen über die Empfangene Nachricht ins Log zu schreiben. Dabei kann man sich leider nicht darauf verlassen, dass die Nachricht korrekt dekodiert wurde.<br>
Die einzgeste Funktion dieses Modules ist, ab Verbose 4 Logmeldungen ueber die Empfangene Nachricht ins Log zu schreiben. Dabei kann man sich leider nicht darauf verlassen, dass die Nachricht korrekt dekodiert wurde.<br>
Dieses Modul wird alle Nachrichten verarbeiten, welche von anderen Modulen nicht verarbeitet wurden.
<a name="SIGNALduino_unset"></a>
<b>Set</b> <ul>N/A</ul><br>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -81,6 +81,7 @@ FHEM/16_CUL_RFR.pm rudolfkoenig http://forum.fhem.de SlowRF
FHEM/16_STACKABLE_CC.pm rudolfkoenig http://forum.fhem.de SlowRF
FHEM/17_EGPM2LAN.pm alexus http://forum.fhem.de Sonstiges
FHEM/14_SD_WS07.pm Sidey/Ralf9 http://forum.fhem.de Sonstige Systeme
FHEM/14_SD_WS09.pm Sidey/pejonp http://forum.fhem.de Sonstige Systeme
FHEM/17_SIS_PMS.pm painseeker http://forum.fhem.de Sonstiges
FHEM/18_CUL_HOERMANN.pm rudolfkoenig http://forum.fhem.de SlowRF
FHEM/19_Revolt.pm martinppp/mehf http://forum.fhem.de SlowRF