| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462 |
- ##############################################
- # $Id: 90_SIGNALduino_un.pm 12722 2016-12-06 21:03:14Z mrsidey $
- # The file is part of the SIGNALduino project
- # see http://www.fhemwiki.de/wiki/SIGNALduino
- # to support debugging of unknown signal data
- # The purpos is to use it as addition to the SIGNALduino
- # S. Butzek, 2015
- #
- package main;
- use strict;
- use warnings;
- use POSIX;
- #####################################
- sub
- SIGNALduino_un_Initialize($)
- {
- my ($hash) = @_;
- $hash->{Match} = '^[uP]\d+#.*';
- $hash->{DefFn} = "SIGNALduino_un_Define";
- $hash->{UndefFn} = "SIGNALduino_un_Undef";
- $hash->{AttrFn} = "SIGNALduino_un_Attr";
- $hash->{ParseFn} = "SIGNALduino_un_Parse";
- $hash->{AttrList} = "IODev do_not_notify:0,1 showtime:0,1 ignore:0,1 ".$readingFnAttributes;
- }
- #####################################
- sub
- SIGNALduino_un_Define($$)
- {
- my ($hash, $def) = @_;
- my @a = split("[ \t][ \t]*", $def);
- return "wrong syntax: define <name> SIGNALduino_un <code> <minsecs> <equalmsg>".int(@a)
- if(int(@a) < 3 || int(@a) > 5);
- $hash->{CODE} = $a[2];
- $hash->{minsecs} = ((int(@a) > 3) ? $a[3] : 30);
- $hash->{equalMSG} = ((int(@a) > 4) ? $a[4] : 0);
- $hash->{lastMSG} = "";
- $hash->{bitMSG} = "";
- $modules{SIGNALduino_un}{defptr}{$a[2]} = $hash;
- $hash->{STATE} = "Defined";
- AssignIoPort($hash);
- return undef;
- }
- #####################################
- sub
- SIGNALduino_un_Undef($$)
- {
- my ($hash, $name) = @_;
- delete($modules{SIGNALduino_un}{defptr}{$hash->{CODE}}) if($hash && $hash->{CODE});
- return undef;
- }
- sub SIGNALduino_un_hex2bin {
- my $h = shift;
- my $hlen = length($h);
- my $blen = $hlen * 4;
- return unpack("B$blen", pack("H$hlen", $h));
- }
- #####################################
- sub
- SIGNALduino_un_Parse($$)
- {
- my ($hash,$msg) = @_;
- my @a = split("", $msg);
- my $name = "SIGNALduino_unknown";# $hash->{NAME};
- Log3 $hash, 4, "$name incomming msg: $msg";
- #my $rawData=substr($msg,2);
- my ($protocol,$rawData) = split("#",$msg);
-
- my $dummyreturnvalue= "Unknown, please report";
- $protocol=~ s/^[uP](\d+)/$1/; # extract protocol
- Log3 $hash, 4, "$name rawData: $rawData";
- Log3 $hash, 4, "$name Protocol: $protocol";
- my $hlen = length($rawData);
- my $blen = $hlen * 4;
- my $bitData= unpack("B$blen", pack("H$hlen", $rawData));
- Log3 $hash, 4, "$name converted to bits: $bitData";
-
- if ($protocol == "7" && length($bitData)>=36) ## Unknown Proto 7
- {
-
-
- ## Try TX70DTH Decoding
- my $SensorTyp = "TX70DTH";
- my $channel = SIGNALduino_un_bin2dec(substr($bitData,9,3));
- my $bin = substr($bitData,0,8);
- my $id = sprintf('%X', oct("0b$bin"));
- my $bat = int(substr($bitData,8,1)) eq "1" ? "ok" : "critical";
- my $trend = "";
- my $sendMode = "";
- my $temp = SIGNALduino_un_bin2dec(substr($bitData,16,8));
- if (substr($bitData,14,1) eq "1") {
- $temp = $temp - 1024;
- }
- $temp = $temp / 10;
- my $hum = SIGNALduino_un_bin2dec(substr($bitData,29,7));
- my $val = "T: $temp H: $hum B: $bat";
- Log3 $hash, 4, "$name decoded protocolid: 7 ($SensorTyp) sensor id=$id, channel=$channel, temp=$temp, hum=$hum, bat=$bat\n" ;
-
- # Try Eurochron EAS 800
- # 4 8 12 24 28 36
- # 0011 0110 1010 000100000010 1111 00111000 0000 Kanal 3, 25.8 Grad, 56%
- # 0011 0110 1010 000011110011 1111 00111000 0000 Kanal 3, 24.3 Grad, 56%
- # 0011 0001 1001 000100001001 1111 00111101 0000 Kanal 2, 26.5 Grad, 61%
- # 0011 1000 1000 000100000011 1111 01000000 0000 Kanal 1
-
- # ID? CHN TMP ?? HUM
- $SensorTyp = "EAS800z";
- $id = oct ("0b".substr($bitData,4,4));
- $channel = SIGNALduino_un_bin2dec(substr($bitData,9,3))+1;
- $temp = oct ("0b".substr($bitData,12,12))/10;
- $bat = int(substr($bitData,8,1)) eq "1" ? "ok" : "critical"; # Eventuell falsch!
- $hum = SIGNALduino_un_bin2dec(substr($bitData,28,8));
- $sendMode = int(substr($bitData,4,1)) eq "1" ? "auto" : "manual"; # Eventuell falsch!
- my $type = SIGNALduino_un_bin2dec(substr($bitData,0,4));
-
- Log3 $hash, 4, "$name decoded protocolid: 7 ($SensorTyp / type=$type) mode=$sendMode, sensor id=$id, channel=$channel, temp=$temp, hum=$hum, bat=$bat\n" ;
-
-
- } elsif ($protocol == "6" && length($bitData)>=36) ## Eurochron
- {
- # EuroChron / Tchibo
- # /--------------------------- Channel, changes after every battery change
- # / / ------------------ Battery state 0 == Ok
- # / / /------------------ unknown
- # / / / / --------------- forced send
- # / / / / / ------------- unknown
- # / / / / / / -------- Humidity
- # / / / / / / / - neg Temp: if 1 then temp = temp - 2048
- # / / / / / / / / Temp
- # 01100010 1 00 1 00000 0100011 0 00011011101
- # Bit 0 8 9 11 12 17 24 25 36
- my $SensorTyp = "EuroChron";
- my $channel = "";
- my $bin = substr($bitData,0,8);
- my $id = sprintf('%X', oct("0b$bin"));
- my $bat = int(substr($bitData,8,1)) eq "0" ? "ok" : "critical";
- my $trend = "";
- my $sendMode = int(substr($bitData,11,1)) eq "0" ? "automatic" : "manual";
- my $temp = SIGNALduino_un_bin2dec(substr($bitData,25,11));
- if (substr($bitData,24,1) eq "1") {
- $temp = $temp - 2048
- }
- $temp = $temp / 10.0;
- my $hum = SIGNALduino_un_bin2dec(substr($bitData,17,7));
- my $val = "T: $temp H: $hum B: $bat";
- Log3 $hash, 4, "$name decoded protocolid: 6 $SensorTyp, sensor id=$id, channel=$channel, temp=$temp\n" ;
- } elsif ($protocol == "9" && length($bitData)>=70) ## Unknown Proto 9
- { #http://nupo-artworks.de/media/report.pdf
-
- my $syncpos= index($bitData,"11111110"); #7x1 1x0 preamble
-
- if ($syncpos ==-1 || length($bitData)-$syncpos < 68)
- {
- Log3 $hash, 4, "$name ctw600 not found, aborting";
- return undef;
- }
- my $sensdata = substr($bitData,$syncpos+8);
- my $bat = substr($sensdata,0,3);
- my $id = substr($sensdata,4,6);
- my $temp = substr($sensdata,12,10);
- my $hum = substr($sensdata,22,8);
- my $wind = substr($sensdata,30,16);
- my $rain = substr($sensdata,46,16);
- my $winddir = substr($sensdata,66,4);
-
- 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) ## 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 $deviceCode = substr($bitData,0,23);
- my $unit= substr($bitData,23,1);
-
- Log3 $hash, 4, "$name found RF21 protocol. devicecode=$deviceCode, unit=$unit";
- }
- elsif ($protocol == "14" && length($bitData)>=12) ## Heidman HX
- {
- my $bin = substr($bitData,0,4);
- my $deviceCode = sprintf('%X', oct("0b$bin"));
- my $sound = substr($bitData,7,5);
- Log3 $hash, 4, "$name found Heidman HX doorbell. devicecode=$deviceCode, sound=$sound";
- }
- elsif ($protocol == "15" && length($bitData)>=64) ## TCM
- {
- my $deviceCode = $a[4].$a[5].$a[6].$a[7].$a[8];
- Log3 $hash, 4, "$name found TCM doorbell. devicecode=$deviceCode";
- }
- elsif ($protocol == "16" && length($bitData)>=36) ##Rohrmotor24
- {
- 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 $all = ($channel == 0) ? "true" : "false";
- my $commandcode = SIGNALduino_un_binaryToNumber($bitData,32,35);
- my $direction="";
-
- 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, remotetype=$remote, channel=$channel, direction=$direction, all_shutters=$all";
- }
- elsif ($protocol == "21" && length($bitData)>=32) ##Einhell doorshutter
- {
- Log3 $hash, 4, "$name / Einhell doorshutter received";
-
-
- my $id = oct("0b".substr($bitData,0,28));
-
- my $dir = oct("0b".substr($bitData,28,2));
-
- my $channel = oct("0b".substr($bitData,30,3));
-
-
- Log3 $hash, 4, "$name found doorshutter from Einhell. id=$id, channel=$channel, direction=$dir";
- } elsif ($protocol == "23" && length($bitData)>=32) ##Perl Sensor
- {
- my $SensorTyp = "perl NC-7367?";
- my $id = oct ("0b".substr($bitData,4,4));
- my $channel = SIGNALduino_un_bin2dec(substr($bitData,9,3))+1;
- my $temp = oct ("0b".substr($bitData,20,8))/10;
- my $bat = int(substr($bitData,8,1)) eq "1" ? "ok" : "critical"; # Eventuell falsch!
- my $sendMode = int(substr($bitData,4,1)) eq "1" ? "auto" : "manual"; # Eventuell falsch!
- my $type = SIGNALduino_un_bin2dec(substr($bitData,0,4));
-
- 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 {
- Log3 $hash, 4, $dummyreturnvalue;
-
- return undef;
- }
- Log3 $hash, 4, $dummyreturnvalue;
- return undef;
- }
- sub
- SIGNALduino_un_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{SIGNALduino_un}{defptr}{$cde});
- $modules{SIGNALduino_un}{defptr}{$iohash->{NAME} . "." . $cde} = $hash;
- return undef;
- }
- # 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($)
- {
- my $h = shift;
- my $int = unpack("N", pack("B32",substr("0" x 32 . $h, -32)));
- return sprintf("%d", $int);
- }
- sub
- SIGNALduino_un_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;
- }
- 1;
- =pod
- =item summary Helper module for SIGNALduino
- =item summary_DE Unterstützungsmodul für SIGNALduino
- =begin html
- <a name="SIGNALduino_un"></a>
- <h3>SIGNALduino_un</h3>
- <ul>
- The SIGNALduino_un module is a testing and debugging module to decode some devices, it will not create any devices, it will catch only all messages from the signalduino which can't be send to another module
- <br><br>
- <a name="SIGNALduino_undefine"></a>
- <b>Define</b>
- <ul>
- <code>define <name> SIGNALduino_un <code> ]</code> <br>
- <br>
- You can define a Device, but currently you can do nothing with it.
- Autocreate is also not enabled for this module.
- The function of this module is only to output some logging at verbose 4 or higher. May some data is decoded correctly but it's also possible that this does not work.
- The Module will try to process all messages, which where not handled by other modules.
-
- </ul>
- <br>
- <a name="SIGNALduino_unset"></a>
- <b>Set</b> <ul>N/A</ul><br>
- <a name="SIGNALduino_unget"></a>
- <b>Get</b> <ul>N/A</ul><br>
- <a name="SIGNALduino_unattr"></a>
- <b>Attributes</b>
- <ul>
- <li><a href="#verbose">Verbose</a></li>
- </ul>
- <br>
- </ul>
- =end html
- =begin html_DE
- <a name="SIGNALduino_un"></a>
- <h3>SIGNALduino_un</h3>
- <ul>
- Das SIGNALduino_un module ist ein Hilfsmodul um unbekannte Nachrichten debuggen und analysieren zu koennen.
- Das Modul legt keinerlei Geräte oder ähnliches an.
- <br><br>
- <a name="SIGNALduino_undefine"></a>
- <b>Define</b>
- <code>define <name> SIGNALduino_un <code> </code> <br>
- <br>
- 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>
- 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>
- <a name="SIGNALduino_unget"></a>
- <b>Get</b> <ul>N/A</ul><br>
- <a name="SIGNALduino_unattr"></a>
- <b>Attributes</b>
- <ul>
- <li><a href="#verbose">Verbose</a></li>
- </ul>
- <br>
- </ul>
- =end html_DE
- =cut
|