| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890 |
- # From dancer0705
- #
- # Receive temperature sensor
- # Supported models:
- # - "TCM97..."
- # - "ABS700"
- # - "TCM21...."
- # - "Prologue"
- # - "Rubicson"
- # - "NC_WS"
- # - "GT_WT_02"
- # - "AURIOL"
- # - "KW9010"
- #
- # Unsupported models are saved in a device named CUL_TCM97001_Unknown
- #
- # Copyright (C) 2016 Bjoern Hempel
- #
- # This program is free software; you can redistribute it and/or modify it under
- # the terms of the GNU General Public License as published by the Free Software
- # Foundation; either version 2 of the License, or (at your option) any later
- # version.
- #
- # This program is distributed in the hope that it will be useful, but
- # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- # more details.
- #
- # You should have received a copy of the GNU General Public License along with
- # this program; if not, write to the
- # Free Software Foundation, Inc.,
- # 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
- #
- # $Id: 14_CUL_TCM97001.pm 15367 2017-10-31 17:44:02Z bjoernh $
- #
- #
- # 14.06.2017 W155(TCM21...) wind/rain pejonp
- # 25.06.2017 W155(TCM21...) wind/rain pejonp
- # 04.07.2017 PFR-130 rain pejonp
- # 04.07.2017 TFA 30.3161 temp/rain pejonp
- # 22.10.2017 W174 rain elektron-bbs/HomeAutoUser
- ##############################################
- package main;
- use strict;
- use warnings;
- use SetExtensions;
- use constant { TRUE => 1, FALSE => 0 };
- #
- # All suported models
- #
- my %models = (
- "TCM97..." => 'TCM97...',
- "ABS700" => 'ABS700',
- "TCM21...." => 'TCM21....',
- "Prologue" => 'Prologue',
- "Rubicson" => 'Rubicson',
- "NC_WS" => 'NC_WS',
- "GT_WT_02" => 'GT_WT_02',
- "AURIOL" => 'AURIOL',
- "PFR_130" => 'PFR_130',
- "Type1" => 'Type1',
- "Mebus" => 'Mebus',
- "Eurochron" => 'Eurochron',
- "KW9010" => 'KW9010',
- "Unknown" => 'Unknown',
- "W174" => 'W174',
- );
- sub
- CUL_TCM97001_Initialize($)
- {
- my ($hash) = @_;
- $hash->{Match} = "^s.....";
- $hash->{DefFn} = "CUL_TCM97001_Define";
- $hash->{UndefFn} = "CUL_TCM97001_Undef";
- $hash->{ParseFn} = "CUL_TCM97001_Parse";
- $hash->{AttrList} = "IODev do_not_notify:1,0 ignore:0,1 showtime:1,0 " .
- "$readingFnAttributes " .
- "model:".join(",", sort keys %models);
- $hash->{AutoCreate}=
- {
- "CUL_TCM97001_Unknown.*" => { GPLOT => "", FILTER => "%NAME", autocreateThreshold => "2:10" },
- "CUL_TCM97001.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", GPLOT => "temp4hum4:Temp/Hum,", FILTER => "%NAME", autocreateThreshold => "2:180"},
- "Prologue_.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", GPLOT => "temp4hum4:Temp/Hum,", FILTER => "%NAME", autocreateThreshold => "2:180"},
- "Mebus_.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", GPLOT => "temp4hum4:Temp/Hum,", FILTER => "%NAME", autocreateThreshold => "2:180"},
- "NC_WS.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", GPLOT => "temp4hum4:Temp/Hum,", FILTER => "%NAME", autocreateThreshold => "2:180"},
- "ABS700.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", GPLOT => "temp4hum4:Temp/Hum,", FILTER => "%NAME", autocreateThreshold => "2:180"},
- "Eurochron.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", GPLOT => "temp4hum4:Temp/Hum,", FILTER => "%NAME", autocreateThreshold => "2:180"},
- "TCM21....*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", GPLOT => "temp4hum4:Temp/Hum,", FILTER => "%NAME", autocreateThreshold => "2:180"},
- "TCM97..._.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", GPLOT => "temp4hum4:Temp/Hum,", FILTER => "%NAME", autocreateThreshold => "2:180"},
- "GT_WT_02.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", GPLOT => "temp4hum4:Temp/Hum,", FILTER => "%NAME", autocreateThreshold => "2:180"},
- "Type1.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", GPLOT => "temp4hum4:Temp/Hum,", FILTER => "%NAME", autocreateThreshold => "2:180"},
- "Rubicson.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", GPLOT => "temp4hum4:Temp/Hum,", FILTER => "%NAME", autocreateThreshold => "2:180"},
- "AURIOL.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", GPLOT => "temp4hum4:Temp/Hum,", FILTER => "%NAME", autocreateThreshold => "2:180"},
- "PFR_130.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", GPLOT => "temp4hum4:Temp/Hum,", FILTER => "%NAME", autocreateThreshold => "2:180"},
- "KW9010.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", GPLOT => "temp4hum4:Temp/Hum,", FILTER => "%NAME", autocreateThreshold => "2:180"},
- "TCM97001.*" => { ATTR => "event-on-change-reading:.*", GPLOT => "temp4hum4:Temp/Hum,", FILTER => "%NAME", autocreateThreshold => "2:340"},
- "W174.*" => { ATTR => "event-min-interval:.*:300 event-on-change-reading:.*", GPLOT => "rain4:Rain,", FILTER => "%NAME", autocreateThreshold => "2:180"},
- "Unknown_.*" => { autocreateThreshold => "2:10"}
- };
- }
- #############################
- sub
- CUL_TCM97001_Define($$)
- {
- my ($hash, $def) = @_;
- my @a = split("[ \t][ \t]*", $def);
- return "wrong syntax: define <name> CUL_TCM97001 <code>"
- if(int(@a) < 3 || int(@a) > 5);
- $hash->{CODE} = $a[2];
- $hash->{lastT} = 0;
- $hash->{lastH} = 0;
- $modules{CUL_TCM97001}{defptr}{$a[2]} = $hash;
- $hash->{STATE} = "Defined";
- return undef;
- }
- #####################################
- sub
- CUL_TCM97001_Undef($$)
- {
- my ($hash, $name) = @_;
- delete($modules{CUL_TCM97001}{defptr}{$hash->{CODE}})
- if(defined($hash->{CODE}) &&
- defined($modules{CUL_TCM97001}{defptr}{$hash->{CODE}}));
- return undef;
- }
- ### inserted by elektron-bbs for rain gauge Ventus W174
- # Checksum for Rain Gauge VENTUS W174 Protocol Auriol
- # n8 = ( 0x7 + n0 + n1 + n2 + n3 + n4 + n5 + n6 + n7 ) & 0xf
- sub checksum_W174 {
- my $msg = shift;
- Log3 "CUL_TCM97001: ", 4 , "CUL_TCM97001: W174 checksum calc for: $msg";
- my @a = split("", $msg);
- my $bitReverse = undef;
- my $x = undef;
- foreach $x (@a) {
- my $bin3=sprintf("%04b",hex($x));
- $bitReverse = $bitReverse . reverse($bin3);
- }
- my $hexReverse = unpack("H*", pack ("B*", $bitReverse));
- my @aReverse = split("", $hexReverse); # Split reversed a again
- my $CRC = (7 + hex($aReverse[0])+hex($aReverse[1])+hex($aReverse[2])+hex($aReverse[3])+hex($aReverse[4])+hex($aReverse[5])+hex($aReverse[6])+hex($aReverse[7])) & 15;
- if ($CRC == hex($aReverse[8])) {
- Log3 "CUL_TCM97001: ", 4 , "CUL_TCM97001: W174 checksum ok $CRC == ".hex($aReverse[8]);
- return TRUE;
- } else {
- return FALSE;
- }
- }
- #
- # CRC Check for TCM 21....
- #
- sub checkCRC {
- my $msg = shift;
- my @a = split("", $msg);
- my $bitReverse = undef;
- my $x = undef;
- foreach $x (@a) {
- my $bin3=sprintf("%04b",hex($x));
- $bitReverse = $bitReverse . reverse($bin3);
- }
- my $hexReverse = unpack("H*", pack ("B*", $bitReverse));
- #Split reversed a again
- my @aReverse = split("", $hexReverse);
- my $CRC = (hex($aReverse[0])+hex($aReverse[1])+hex($aReverse[2])+hex($aReverse[3])
- +hex($aReverse[4])+hex($aReverse[5])+hex($aReverse[6])+hex($aReverse[7])) & 15;
- if ($CRC + hex($aReverse[8]) == 15) {
- return TRUE;
- }
- return FALSE;
- }
- #
- # CRC 4 check for PFR-130
- # xor 4 bits of nibble 0 to 7
- #
- sub checkCRC4 {
- my $msg = shift;
- my @a = split("", $msg);
- if(scalar(@a)<9){
- Log3 "checkCRC4", 5, "CUL_TCM97001 failed for msg=($msg) length<9";
- return FALSE;
- }
- # xor nibbles 0 to 7 and compare to n8, if more nibble they might have been added to fill gap
- my $CRC = ( (hex($a[0])) ^ (hex($a[1])) ^ (hex($a[2])) ^ (hex($a[3])) ^
- (hex($a[4])) ^ (hex($a[5])) ^ (hex($a[6])) ^ (hex($a[7])) );
- if ($CRC == (hex($a[8]))) {
- Log3 "checkCRC4", 5, "CUL_TCM97001 OK for msg=($msg)";
- return TRUE;
- }
- Log3 "checkCRC4", 5, "CUL_TCM97001 FAILED for msg=($msg)";
- return FALSE;
- }
- #
- # CRC 4 check for PFR-130
- # xor 4 bits of nibble 0 to 7
- #
- sub isRain {
- my $msg = shift;
- my @a = split("", $msg);
- if(scalar(@a)<9){
- Log3 "isRain", 5, "isRain: CUL_TCM97001 failed for msg=($msg) length<9";
- return FALSE;
- }
- # if bit 0 of nibble 2 is 1 then this is no rain data
- my $isRainData = ( (hex($a[2]) & 1) );
- if ($isRainData == 1) {
- Log3 "isRain", 5, "isRain: CUL_TCM97001 for msg=($msg) = FALSE";
- return FALSE;
- }
- Log3 "isRain", 5, "isRain: CUL_TCM97001 for msg=($msg) = TRUE";
- return TRUE;
- }
- #
- # CRC Check for KW9010....
- #
- sub checkCRCKW9010 {
- my $msg = shift;
- Log3 "CUL_TCM97001", 5 , "crc calc for: $msg";
- my @a = split("", $msg);
- my $bitReverse = undef;
- my $x = undef;
- foreach $x (@a) {
- my $bin3=sprintf("%04b",hex($x));
- $bitReverse = $bitReverse . reverse($bin3);
- }
- my $hexReverse = unpack("H*", pack ("B*", $bitReverse));
- #Split reversed a again
- my @aReverse = split("", $hexReverse);
- my $CRC = (hex($aReverse[0])+hex($aReverse[1])+hex($aReverse[2])+hex($aReverse[3])
- +hex($aReverse[4])+hex($aReverse[5])+hex($aReverse[6])+hex($aReverse[7])) & 15;
- Log3 "CUL_TCM97001", 5 , "calc crc is: $CRC";
- Log3 "CUL_TCM97001", 5 , "ref crc is :".hex($aReverse[8]);
- if ($CRC == hex($aReverse[8])) {
- return TRUE;
- }
- return FALSE;
- }
- #
- # CRC Check for Mebus
- #
- sub checkCRC_Mebus {
- my $msg = shift;
- my @a = split("", $msg);
- my $CRC = ((hex($a[1])+hex($a[2])+hex($a[3])
- +hex($a[4])+hex($a[5])+hex($a[6])) -1) & 15;
- my $CRCCHECKVAL= (hex($a[0]));
- if ($CRC == $CRCCHECKVAL) {
- return TRUE;
- }
- return FALSE;
- }
- #
- # CRC Check for GT_WT_02
- ### edited by elektron-bbs for GT_WT_02
- sub checkCRC_GTWT02 {
- my $msg = shift;
- my @a = split("", $msg);
- my $CRC = (hex($a[0])+hex($a[1])+hex($a[2])+hex($a[3])
- +hex($a[4])+hex($a[5])+hex($a[6])+(hex($a[7]) & 0xE));
- # my $CRC = (hex($a[0])+hex($a[1])+hex($a[2])+hex($a[3])
- # +hex($a[4])+hex($a[5])+hex($a[6])+hex($a[7])) -1;
- my $CRCCHECKVAL= (hex($a[7].$a[8].$a[9]) & 0x1F8) >> 3;
- if ($CRC % 64 == $CRCCHECKVAL) {
- return TRUE;
- }
- return FALSE;
- }
- #
- # CRC Check for Sensor-Type1
- #
- sub checkCRC_Type1 {
- my $msg = shift;
- my @a = split("", $msg);
- my $CRC = (hex($a[0])+hex($a[1])+hex($a[2])+hex($a[3])
- +hex($a[4])+hex($a[5])+hex($a[6])+hex($a[7]));
- my $CRCCHECKVAL= (hex($a[7].$a[8].$a[9]) & 0x1F8) >> 3;
- if ($CRC == $CRCCHECKVAL) {
- return TRUE;
- }
- return FALSE;
- }
- sub checkValues {
- my $temp = shift;
- my $humidy = shift;
- if (!defined($humidy)) {
- $humidy = 50;
- }
- if ($temp <= 60 && $temp >= -30
- && $humidy >= 0 && $humidy <= 100) {
- return TRUE;
- }
- return FALSE;
- }
- ###################################
- sub
- CUL_TCM97001_Parse($$)
- {
- my $enableLongIDs = TRUE; # Disable short ID support, enable longIDs
- my ($hash, $msg) = @_;
- $msg = substr($msg, 1);
- my @a = split("", $msg);
- my $id3 = hex($a[0] . $a[1]);
- #my $id4 = hex($a[0] . $a[1] . $a[2] . (hex($a[3]) & 0x3));
- my $def = $modules{CUL_TCM97001}{defptr}{$id3}; # test for already defined devices use old naming convention
- #my $def2 = $modules{CUL_TCM97001}{defptr}{$idType2};
- if(!$def) {
- $def = $modules{CUL_TCM97001}{defptr}{'CUL_TCM97001_'.$id3}; # use new naming convention
- }
-
- my $now = time();
- my $name = "Unknown";
- if($def) {
- $name = $def->{NAME};
- }
- my $readedModel = AttrVal($name, "model", "Unknown");
-
- my $syncTimeIndex = rindex($msg,";");
- my @syncBit;
- if ($syncTimeIndex != -1) {
- my $syncTimeMsg = substr($msg, $syncTimeIndex + 1);
- @syncBit = split(":", $syncTimeMsg);
- $msg = substr($msg, 0, $syncTimeIndex);
- } else {
- $syncBit[0] = 0;
- $syncBit[1] = 4000;
- }
-
- my $rssi;
- my $l = length($msg);
- $rssi = substr($msg, $l-2, 2);
- undef($rssi) if ($rssi eq "00");
-
- if (defined($rssi))
- {
- $rssi = hex($rssi);
- $rssi = ($rssi>=128 ? (($rssi-256)/2-74) : ($rssi/2-74)) if defined($rssi);
- Log3 $name, 4, "CUL_TCM97001 $name $id3 ($msg) length: $l RSSI: $rssi";
- } else {
- Log3 $name, 4, "CUL_TCM97001 $name $id3 ($msg) length: $l";
- }
- my ($msgtype, $msgtypeH);
-
- my $packageOK = FALSE;
-
- my $batbit=undef;
- my $mode=undef;
- my $trend=undef;
- my $hashumidity = FALSE;
- my $hasbatcheck = FALSE;
- my $hastrend = FALSE;
- my $haschannel = FALSE;
- my $hasmode = FALSE;
- my $model="Unknown";
- my $temp = undef;
- my $humidity=undef;
- my $channel = undef;
- # für zusätzliche Sensoren
- my @winddir_name=("N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW");
- my $windSpeed = 0;
- my $windDirection = 0 ;
- my $windDirectionText = "N";
- my $windgrad = 0 ;
- my $windGuest = 0;
- my $rain = 0;
- my $haswindspeed = FALSE;
- my $haswind = FALSE;
- my $hasrain = FALSE;
- my $rainticks = undef;
- my $rainMM = undef;
-
-
- my $longids = AttrVal($hash->{NAME},'longids',1);
- if (length($msg) == 8) {
- # Only tmp TCM device
- #eg. 1000 1111 0100 0011 0110 1000 = 21.8C
- #eg. --> shift2 0100 0011 0110 10
- my $tcm97id = hex($a[0] . $a[1]);
- $def = $modules{CUL_TCM97001}{defptr}{$tcm97id};
- if($def) {
- $name = $def->{NAME};
- }
- $readedModel = AttrVal($name, "model", "Unknown");
-
- if ($readedModel eq "Unknown" || $readedModel eq "TCM97...") {
- $temp = (hex($a[3].$a[4].$a[5]) >> 2) & 0xFFFF;
- my $negative = (hex($a[2]) >> 0) & 0x3;
- if ($negative == 0x3) {
- $temp = (~$temp & 0x03FF) + 1;
- $temp = -$temp;
- }
- $temp = $temp / 10;
- if (checkValues($temp, 50)) {
- $model="TCM97...";
- # I think bit 3 on byte 3 is battery warning
- $batbit = (hex($a[2]) >> 0) & 0x4;
- $batbit = ~$batbit & 0x1; # Bat bit umdrehen
- $mode = (hex($a[5]) >> 0) & 0x1;
- my $unknown = (hex($a[4]) >> 0) & 0x2;
- if ($mode) {
- Log3 $name, 5, "CUL_TCM97001 Mode: manual triggert";
- } else {
- Log3 $name, 5, "CUL_TCM97001 Mode: auto triggert";
- }
- if ($unknown) {
- Log3 $name, 5, "CUL_TCM97001 Unknown Bit: $unknown";
- }
-
- my $deviceCode;
-
- if (!defined($modules{CUL_TCM97001}{defptr}{$tcm97id}))
- {
- if ( $enableLongIDs == TRUE || (($longids != "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/))))
- {
- $deviceCode="CUL_TCM97001_".$tcm97id;
- Log3 $hash,4, "CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="CUL_TCM97001_" . $model;
- }
- } else {
- $deviceCode=$tcm97id;
- }
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
-
-
-
- if(!$def) {
- Log3 $name, 2, "CUL_TCM97001 Unknown device $deviceCode, please define it";
- return "UNDEFINED $model" . substr($deviceCode, rindex($deviceCode,"_")) . " CUL_TCM97001 $deviceCode";
- }
- $packageOK = TRUE;
- $hasbatcheck = TRUE;
- $hasmode = TRUE;
- $readedModel=$model;
- }
- }
- if ($readedModel eq "Unknown" || $readedModel eq "ABS700") {
- $temp = (hex($a[2].$a[3]) & 0x7F)+(hex($a[5])/10);
- if ((hex($a[2]) & 0x8) == 0x8) {
- $temp = -$temp;
- }
-
- if (checkValues($temp, 50)) {
- $model="ABS700";
- $batbit = ((hex($a[4]) & 0x8) != 0x8);
- $mode = (hex($a[4]) & 0x4) >> 2;
-
- my $deviceCode;
- if (!defined($modules{CUL_TCM97001}{defptr}{$tcm97id}))
- {
- if ( $enableLongIDs == TRUE || (($longids != "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/))))
- {
- $deviceCode="CUL_TCM97001_".$tcm97id;
- Log3 $hash,4, "CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="CUL_TCM97001_" . $model;
- }
- } else {
- $deviceCode=$tcm97id;
- }
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
- if(!$def) {
- Log3 $name, 2, "CUL_TCM97001 Unknown device $deviceCode, please define it";
- return "UNDEFINED $model" . substr($deviceCode, rindex($deviceCode,"_")) . " CUL_TCM97001 $deviceCode";
- }
- $hasbatcheck = TRUE;
- $packageOK = TRUE;
- $hasmode = TRUE;
-
- $readedModel=$model;
- }
- }
- } elsif (length($msg) == 10) {
- #Log3 $name, 2, "CUL_TCM97001 10er msg: " . $msg;
- my $idType2 = hex($a[1] . $a[2]);
- my $deviceCode = $idType2;
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode}; # test for already defined devices use old naming convention
- if(!$def) {
- $deviceCode = "CUL_TCM97001_" . $idType2; # use new naming convention
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- }
- if($def) {
- $name = $def->{NAME};
- }
-
- $readedModel = AttrVal($name, "model", "Unknown");
-
- if (checkCRC_Mebus($msg) == TRUE && ($readedModel eq "Unknown" || $readedModel eq "Mebus")) {
- # Protocol mebus start everytime with 1001
- # Sync bit 9700ms, bit 0 = 350ms, bit 1 = 2000ms
- # e.g. 8250ED70 1000 0010 0101 0000 1110 1101 0111
- # A B C D E F G
- # A = CRC ((B+C+D+E+F+G)-1)
- # B+C = Random Address
- # D+E+F temp (/10)
- # G Bit 4,3 = Channel, Bit 2 = Battery, Bit 1 = Force sending
- $temp = (hex($a[3].$a[4].$a[5])) & 0x3FF;
- my $negative = (hex($a[3])) & 0xC;
- if ($negative == 0xC) {
- $temp = (~$temp & 0x03FF) + 1;
- $temp = -$temp;
- }
- $temp = $temp / 10;
-
- if (checkValues($temp, 50)) {
- $batbit = (hex($a[6]) & 0x2) >> 1;
- #$batbit = ~$batbit & 0x1; # Bat bit umdrehen
- $mode = (hex($a[6]) & 0x1);
- $channel = (hex($a[6]) & 0xC) >> 2;
- $model="Mebus";
- my $deviceCode;
-
- if (!defined($modules{CUL_TCM97001}{defptr}{$idType2}))
- {
- if ( $enableLongIDs == TRUE || (($longids != "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/))))
- {
- $deviceCode="CUL_TCM97001_".$idType2;
- Log3 $hash,4, "CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="CUL_TCM97001_" . $model . "_" . $channel;
- }
- } else { # Fallback for already defined devices use old naming convention
- $deviceCode=$idType2;
- }
-
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
- if(!$def) {
- Log3 $name, 2, "CUL_TCM97001 Unknown device $deviceCode, please define it";
- return "UNDEFINED $model" . substr($deviceCode, rindex($deviceCode,"_")) . " CUL_TCM97001 $deviceCode";
- }
- $packageOK = TRUE;
-
- $readedModel=$model;
- $hasmode = TRUE;
- $hasbatcheck = TRUE;
- $haschannel = TRUE;
- $id3 = $idType2
- } else {
- $name = "Unknown";
- }
- }
- if ($packageOK == FALSE) {
- my $idType1 = hex($a[0] . $a[1]);
- $deviceCode = $idType1;
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode}; # test for already defined devices use old naming convention
- #my $def2 = $modules{CUL_TCM97001}{defptr}{$idType2};
- #my $def3 = $modules{CUL_TCM97001}{defptr}{$idType3};
- if(!$def) {
- $deviceCode = "CUL_TCM97001_" . $idType1; # use new naming convention
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- }
- if($def) {
- $name = $def->{NAME};
- #} elsif($def2) {
- # $def = $def2;
- # $name = $def->{NAME};
- #} elsif($def3) {
- # $def = $def3;
- # $name = $def->{NAME};
- }
- $readedModel = AttrVal($name, "model", "Unknown");
-
-
- if (($readedModel eq "AURIOL" || $readedModel eq "Unknown")) {
- # Implementation from Femduino
- # AURIOL (Lidl Version: 09/2013)
- # /--------------------------------- Channel, changes after every battery change
- # / / ------------------------ Battery state 1 == Ok
- # / / /------------------------ Battery changed, Sync startet
- # / / / ----------------------- Unknown
- # / / / / /--------------------- neg Temp: if 1 then temp = temp - 4096
- # / / / / /---------------------- 12 Bit Temperature
- # / / / / / /---------- ??? CRC
- # / / / / / / /---- Trend 10 == rising, 01 == falling
- # 0101 0101 1 0 00 0001 0000 1011 1100 01 00
- # Bit 0 8 9 10 12 24 30
- $def = $modules{CUL_TCM97001}{defptr}{$idType1};
- if($def) {
- $name = $def->{NAME};
- }
- $temp = (hex($a[3].$a[4].$a[5])) & 0x7FF;
- my $negative = (hex($a[3])) & 0x8;
- if ($negative == 0x8) {
- $temp = (~$temp & 0x07FF) + 1;
- $temp = -$temp;
- }
- $temp = $temp / 10;
-
- if (checkValues($temp, 50)) {
- $batbit = (hex($a[2]) & 0x8) >> 3;
- $batbit = ~$batbit & 0x1; # Bat bit umdrehen
- $mode = (hex($a[2]) & 0x4) >> 2;
- $trend = (hex($a[7]) & 0x3);
- $model="AURIOL";
-
- if ($deviceCode ne $idType1) # new naming convention
- {
- if ( $enableLongIDs == TRUE || (($longids != "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/))))
- {
- $deviceCode="CUL_TCM97001_".$idType1;
- } else {
- $deviceCode="CUL_TCM97001_" . $model . "_" . $channel;
- }
- }
-
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
-
- if(!$def) {
- Log3 $name, 2, "CUL_TCM97001 Unknown device $deviceCode, please define it";
- return "UNDEFINED $model" . substr($deviceCode, rindex($deviceCode,"_")) . " CUL_TCM97001 $deviceCode";
- }
- $hasbatcheck = TRUE;
- $hastrend = TRUE;
- $packageOK = TRUE;
- $hasmode = TRUE;
-
- $readedModel=$model;
- } else {
- $name = "Unknown";
- }
- }
- }
-
- } elsif (length($msg) == 12) {
- my $bin = undef;
- my $deviceCode;
- my $idType1 = hex($a[0] . $a[1]);
- #my $idType2 = hex($a[1] . $a[2]);
- #my $idType3 = hex($a[0] . $a[1] . $a[2] . (hex($a[3]) & 0x3));
- $deviceCode = $idType1;
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode}; # test for already defined devices use old naming convention
- #my $def2 = $modules{CUL_TCM97001}{defptr}{$idType2};
- #my $def3 = $modules{CUL_TCM97001}{defptr}{$idType3};
- if(!$def) {
- $deviceCode = "CUL_TCM97001_" . $idType1; # use new naming convention
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- }
- if($def) {
- $name = $def->{NAME};
- #} elsif($def2) {
- # $def = $def2;
- # $name = $def->{NAME};
- #} elsif($def3) {
- # $def = $def3;
- # $name = $def->{NAME};
- }
- $readedModel = AttrVal($name, "model", "Unknown");
- Log3 $name, 4, "CUL_TCM97001 Parse Name: $name , devicecode: $deviceCode , Model defined: $readedModel";
-
- if (($readedModel eq "Eurochron" || (hex($a[6]) == 0xF && $readedModel eq "Unknown") && $syncBit[1] < 5000)) {
- # EAS 800
- # G is every time 1111
- #
- # 0100 1110 1001 0000 1010 0001 1111 0100 1001
- # A B C D E F G H I
- #
- # A+B = ID = 4E
- # C Bit 0 = Bat (1) OK
- # C Bit 1-3 = Channel 001 = 1
- # D-F = Temp (0000 1010 0001) = 161 ~ 16,1°
- # G = Unknown
- # H+I = hum (0100 1001) = 73
- $def = $modules{CUL_TCM97001}{defptr}{$idType1};
- if($def) {
- $name = $def->{NAME};
- } else {
- # Redirect to
- my $SD_WS07_ClientMatch=index($hash->{Clients},"SD_WS07");
- if ($SD_WS07_ClientMatch == -1) {
- # Append Clients and MatchList for CUL
- $hash->{Clients} = $hash->{Clients}.":SD_WS07:";
- $hash->{MatchList}{"C:SD_WS07"} = "^P7#[A-Fa-f0-9]{6}F[A-Fa-f0-9]{2}";
- }
- my $dmsg = "P7#" . substr($msg, 0, $l-2, 2);
- $hash->{RAWMSG} = $msg;
- my %addvals = (RAWMSG => $msg, DMSG => $dmsg);
- Log3 $name, 5, "CUL_TCM97001 Dispatch $dmsg to other modul";
- Dispatch($hash, $dmsg, \%addvals); ## Dispatch to other Modules
- return "";
- }
- $temp = (hex($a[3].$a[4].$a[5])) & 0x7FF;
- my $negative = (hex($a[3])) & 0x8;
- if ($negative == 0x8) {
- $temp = (~$temp & 0x07FF) + 1;
- $temp = -$temp;
- }
- $temp = $temp / 10;
-
- $humidity = hex($a[7].$a[8]) & 0x7F;
- if (checkValues($temp, $humidity)) {
- $batbit = (hex($a[2]) & 0x8) >> 3;
- #$batbit = ~$batbit & 0x1; # Bat bit umdrehen
- $mode = (hex($a[2]) & 0x4) >> 2;
- $channel = ((hex($a[2])) & 0x3) + 1;
- $model="Eurochron";
-
- if ($deviceCode ne $idType1) # new naming convention
- {
- if ( $enableLongIDs == TRUE || (($longids != "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/))))
- {
- Log3 $hash,4, "CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="CUL_TCM97001_" . $model . "_" . $channel;
- }
- }
-
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
- if(!$def) {
- Log3 $name, 2, "CUL_TCM97001 Unknown device $deviceCode, please define it";
- return "UNDEFINED $model" . substr($deviceCode, rindex($deviceCode,"_")) . " CUL_TCM97001 $deviceCode";
- }
- if (defined($humidity)) {
- if ($humidity >= 20) {
- $hashumidity = TRUE;
- }
- }
- $hasbatcheck = TRUE;
- $haschannel = TRUE;
- $packageOK = TRUE;
- $hasmode = TRUE;
-
- $readedModel=$model;
- } else {
- $name = "Unknown";
- }
- }
- ### inserted by elektron-bbs for rain gauge Ventus W174
- if (checksum_W174($msg) == TRUE && ($readedModel eq "Unknown" || $readedModel eq "W174")) {
- # VENTUS W174 Rain gauge
- # Documentation also at http://www.tfd.hu/tfdhu/files/wsprotocol/auriol_protocol_v20.pdf
- # send interval 36 seconds
- # * Format for Rain
- # * AAAAAAAA vXXB CCCC DDDD DDDD DDDD DDDD EEEE FFFF FFFF
- # * RC Type Rain Checksum
- # * A = Rolling Code /Device ID
- # * B = Message type (xyyx = NON temp/humidity data if yy = '11')
- # * v = 0: Sensor's battery voltage is normal, 1: Battery voltage is below ~2.6 V.
- # * XX = 11: Non temperature/humidity data. All other type data packets have this value in this field.
- # * C = fixed to 1100 for rain gauge
- # * D = Rain (bitvalue * 0.25 mm)
- # * E = Checksum
- # * F = 0000 0000 (W174!!!)
- my @a = split("", $msg);
- my $bitReverse = undef;
- my $bitUnreverse = undef;
- my $x = undef;
- my $bin3;
- foreach $x (@a) {
- $bin3=sprintf("%024b",hex($x));
- $bitReverse = $bitReverse . substr(reverse($bin3),0,4);
- $bitUnreverse = $bitUnreverse . sprintf( "%b", hex( substr($bin3,0,4) ) );
- }
- my $hexReverse = unpack("H*", pack ("B*", $bitReverse));
- my @aReverse = split("", $hexReverse); # Split reversed a again
- Log3 $hash,5, "CUL_TCM97001: $name original-msg: $msg , reversed nibbles: $hexReverse";
- Log3 $hash,5, "CUL_TCM97001: $name nibble 2: $aReverse[2] , nibble 3: $aReverse[3]";
- # Nibble 2 must be x110 for rain gauge
- # Nibble 3 must be 0x03 for rain gauge
- if ((hex($aReverse[2]) >> 1) == 3 && $aReverse[3] == 0x03) {
- Log3 $hash,4, "CUL_TCM97001: $name detected rain gauge message ok";
- $batbit = $aReverse[2] & 0b0001; # Bat bit normal=0, low=1
- Log3 $hash,4, "CUL_TCM97001: $name battery bit: $batbit";
- $batbit = ~$batbit & 0x1; # Bat bit negation
- $hasbatcheck = TRUE;
- my $rainticks = hex($aReverse[4]) + hex($aReverse[5]) * 16 + hex($aReverse[6]) * 256 + hex($aReverse[7]) * 4096;
- Log3 $hash,5, "CUL_TCM97001: $name rain gauge swing count: $rainticks";
- $rain = ($rainticks + ($rainticks & 1)) / 4; # 1 tick = 0,5 l/qm
- $model="W174";
- $hasrain = TRUE;
- # Sanity check
- if($def) {
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- my $hash = $def;
- my $timeSinceLastUpdate = ReadingsAge($hash->{NAME}, "state", 0);
- $name = $def->{NAME};
- if (defined($hash->{READINGS}{rain}{VAL})) {
- my $diffRain = 0;
- my $oldRain = $hash->{READINGS}{rain}{VAL};
- if ($rain > $oldRain) {
- $diffRain = ($rain - $oldRain);
- } else {
- $diffRain = ($oldRain - $rain);
- }
- $diffRain = sprintf("%.1f", $diffRain);
- Log3 $hash, 4, "CUL_TCM97001: $name old rain $oldRain, age $timeSinceLastUpdate, new rain $rain, diff rain $diffRain";
- my $maxDiffRain = $timeSinceLastUpdate / 60 + 1; # 1.0 Liter/Minute + 1.0
- $maxDiffRain = sprintf("%.1f", $maxDiffRain + 0.05); # round 0.1
- Log3 $hash, 4, "CUL_TCM97001: $name max difference rain $maxDiffRain l";
- if ($diffRain > $maxDiffRain) {
- Log3 $hash, 3, "CUL_TCM97001: $name ERROR - Rain diff too large (old $oldRain, new $rain, diff $diffRain)";
- return "";
- }
- }
- } else {
- Log3 $name, 2, "CUL_TCM97001 Unknown device $deviceCode, please define it";
- return "UNDEFINED $model" . substr($deviceCode, rindex($deviceCode,"_")) . " CUL_TCM97001 $deviceCode";
- }
- Log3 $hash,4, "CUL_TCM97001: $name rain total: $rain l/qm";
- $readedModel=$model;
- $packageOK = TRUE;
- }
- }
-
- if (checkCRC($msg) == TRUE && ($readedModel eq "Unknown" || $readedModel eq "TCM21....")) {
- # Long with tmp
- # All nibbles must be reversed
- # e.g. 154E800480 0001 0101 0100 1110 1000 0000 0000 0100 1000 0000
- # A B C D E F G H I
- # A+B = Addess
- # C Bit 1 Battery
- # D+E+F Temp
- # G+H Hum
- # I CRC
- #/* Documentation also at http://www.tfd.hu/tfdhu/files/wsprotocol/auriol_protocol_v20.pdf
- # * Message Format: (9 nibbles, 36 bits):
- # * Please note that bytes need to be reversed before processing!
- # *
- # * Format for Temperature Humidity
- # * AAAAAAAA BBBB CCCC CCCC CCCC DDDDDDDD EEEE
- # * RC Type Temperature___ Humidity Checksum
- # * A = Rolling Code / Device ID
- # * Device ID: AAAABBAA BB is used for channel, base channel is 01
- # * When channel selector is used, channel can be 10 (2) and 11 (3)
- # * B = Message type (xyyz = temp/humidity if yy <> '11') else wind/rain sensor
- # * x indicates battery status (0 normal, 1 voltage is below ~2.6 V)
- # * z 0 indicates regular transmission, 1 indicates requested by pushbutton
- # * C = Temperature (two's complement)
- # * D = Humidity BCD format
- # * E = Checksum
- # *
- # * Format for Rain
- # * AAAAAAAA BBBB CCCC DDDD DDDD DDDD DDDD EEEE
- # * RC Type Rain Checksum
- # * A = Rolling Code /Device ID
- # * B = Message type (xyyx = NON temp/humidity data if yy = '11')
- # * C = fixed to 1100 (C)
- # * D = Rain (bitvalue * 0.25 mm)
- # * E = Checksum
- # *
- # * Format for Windspeed
- # * AAAAAAAA BBBB CCCC CCCC CCCC DDDDDDDD EEEE
- # * RC Type Windspd Checksum
- # * A = Rolling Code
- # * B = Message type (xyyx = NON temp/humidity data if yy = '11')
- # * C = Fixed to 1000 0000 0000 (8)
- # * D = Windspeed (bitvalue * 0.2 m/s, correction for webapp = 3600/1000 * 0.2 * 100 = 72)
- # * E = Checksum
- # *
- # * Format for Winddirection & Windgust
- # * AAAAAAAA BBBB CCCD DDDD DDDD EEEEEEEE FFFF
- # * RC Type Winddir Windgust Checksum
- # * A = Rolling Code
- # * B = Message type (xyyx = NON temp/humidity data if yy = '11')
- # * C = Fixed to 111 (E)
- # * D = Wind direction
- # * E = Windgust (bitvalue * 0.2 m/s, correction for webapp = 3600/1000 * 0.2 * 100 = 72)
- # * F = Checksum
- # *********************************************************************************************
- # */
- my @a = split("", $msg);
- my $bitReverse = undef;
- my $bitUnreverse = undef;
- my $x = undef;
- my $bin3;
-
- foreach $x (@a) {
- $bin3=sprintf("%024b",hex($x));
- $bitReverse = $bitReverse . substr(reverse($bin3),0,4);
- $bitUnreverse = $bitUnreverse . sprintf( "%b", hex( substr($bin3,0,4) ) );
- }
- my $hexReverse = unpack("H*", pack ("B*", $bitReverse));
- #Split reversed a again
- my @aReverse = split("", $hexReverse);
- Log3 $hash,4, "CUL_TCM97001 hex:$hexReverse msg:$msg aR:@aReverse ";
-
- # Message type (xyyz = temp/humidity if yy <> '11') else wind/rain sensor
- # Message type (xyyx = NON temp/humidity data if yy = '11')
- $msgtype = substr(sprintf( "%04b", hex( substr( $msg,2,1))),1,2);
- Log3 $hash,4, "CUL_TCM97001 nib2:$msgtype aRev: $aReverse[2]";
-
- $msgtype = substr(sprintf( "%04b", hex( $aReverse[2])),1,2);
- Log3 $hash,4, "CUL_TCM97001 nib2R:$msgtype hexR: $hexReverse";
- if ( $msgtype ne "11") {
- Log3 $hash,4, "CUL_TCM97001 Temp/Hum Msgype: $msgtype nib3:$aReverse[3] ";
- if (hex($aReverse[5]) > 3) {
- # negative temp
- $temp = ((hex($aReverse[3]) + hex($aReverse[4]) * 16 + hex($aReverse[5]) * 256));
- $temp = (~$temp & 0x03FF) + 1;
- $temp = -$temp/10;
- } else {
- # positive temp
- $temp = (hex($aReverse[3]) + hex($aReverse[4]) * 16 + hex($aReverse[5]) * 256)/10;
- }
-
- $humidity = hex($aReverse[7]).hex($aReverse[6]);
- $hashumidity = TRUE;
-
- } else {
- # Wind/Rain/Guest
- Log3 $hash,4, "CUL_TCM97001 Wind/Rain/Guest Msgype: $msgtype nib3:$aReverse[3] ";
- # C = Fixed to 1000 0000 0000 Reverse 0001 0000 0000
- if ((hex($aReverse[3])== 0x1) && (hex($aReverse[4])== 0x0)) { # Windspeed
- $windSpeed = hex($aReverse[6]) + hex($aReverse[7]);
- $haswindspeed = TRUE;
- Log3 $hash,4, "CUL_TCM97001 windSpeed: $windSpeed ";
- }
-
- if ((hex($aReverse[3])== 0xF)) { # Windguest Reverse
- $windGuest = hex($aReverse[6]) + hex($aReverse[7]);
- $windDirection = hex($aReverse[4]) + hex($aReverse[5]) ;
- $windDirectionText = $winddir_name[$windDirection];
- $haswind = TRUE;
- Log3 $hash,4, "CUL_TCM97001 windGuest: $windGuest ";
- }
- if ((hex($aReverse[3])== 0x3)) { # Rain
- $rain = (hex($aReverse[4]) + hex($aReverse[5]) + hex($aReverse[6]) + hex($aReverse[7])) * 0.25;
- $hasrain = TRUE;
- Log3 $hash,4, "CUL_TCM97001 rain: $rain ";
- }
- }
-
- #if (checkValues($temp, $humidity)) {
- if (1) {
- $batbit = (hex($a[2]) & 0x8) >> 3;
- #$mode = (hex($a[2]) & 0x4) >> 2;
- $model="TCM21....";
- if ($deviceCode ne $idType1) # new naming convention
- {
- if ( $enableLongIDs == TRUE || (($longids != "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/))))
- {
- Log3 $hash,4, "CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="CUL_TCM97001_" . $model . "_" . $channel;
- }
- }
-
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
- if(!$def) {
- Log3 $name, 2, "CUL_TCM97001 Unknown device $deviceCode, please define it";
- return "UNDEFINED $model" . substr($deviceCode, rindex($deviceCode,"_")) . " CUL_TCM97001 $deviceCode";
- }
- $packageOK = TRUE;
- $hasbatcheck = TRUE;
- $readedModel=$model;
- } else {
- $name = "Unknown";
- }
-
- }
-
-
- if (checkCRC_GTWT02($msg) == TRUE && ($readedModel eq "GT_WT_02" || $readedModel eq "Type1" || $readedModel eq "Unknown")
- || checkCRC_Type1($msg) == TRUE && ($readedModel eq "Type1" || $readedModel eq "GT_WT_02" || $readedModel eq "Unknown")) {
- ### edited by elektron-bbs for Checksum
- #http://www.ludwich.de/ludwich/Temperatur.html
- #https://github.com/merbanan/rtl_433/issues/117
- # F F 0 0 F 9 5 5 F
- # 1111 1111 0000 0000 1111 1001 0101 0101 1111
- # A B C D E F G H I
- # A+B = Zufällige Code wechelt beim Batteriewechsel
- # C Bit 4 Battery, 3 Manual, 2+1 Channel
- # D+E+F Temperatur, wenn es negativ wird muss man negieren und dann 1 addieren, wie im ersten Post beschrieben.
- # G+H Hum - bit 0-7
- # I CRC
- #$def = $modules{CUL_TCM97001}{defptr}{$idType3};
-
- $temp = (hex($a[3].$a[4].$a[5])) & 0x3FF;
- my $negative = (hex($a[3])) & 0xC;
- if ($negative == 0xC) {
- $temp = (~$temp & 0x03FF) + 1;
- $temp = -$temp;
- }
- $temp = $temp / 10;
- $humidity = (hex($a[6].$a[7]) & 0x0FE) >> 1; # only the first 7 bits are the humidity
- if ($humidity > 100) {
- # HH - Workaround
- $humidity = 100;
- } elsif ($humidity < 20) {
- # LL - Workaround
- $humidity = 20;
- }
- if (checkValues($temp, $humidity)) {
- $channel = ((hex($a[2])) & 0x3) + 1;
- $batbit = ((hex($a[2]) & 0x8) != 0x8);
- $mode = (hex($a[2]) & 0x4) >> 2;
- if (checkCRC_GTWT02($msg) == TRUE) {
- $model="GT_WT_02";
- } else {
- $model="Type1";
- }
-
- if ($deviceCode ne $idType1) # new naming convention
- {
- if ( $enableLongIDs == TRUE || (($longids != "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/))))
- {
- Log3 $hash,4, "CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="CUL_TCM97001_" . $model . "_" . $channel;
- }
- }
-
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
- if(!$def) {
- Log3 $name, 2, "CUL_TCM97001 Unknown device $deviceCode, please define it";
- return "UNDEFINED $model" . substr($deviceCode, rindex($deviceCode,"_")) . " CUL_TCM97001 $deviceCode";
- }
- $hashumidity = TRUE;
- $hasbatcheck = TRUE;
- $haschannel = TRUE;
- $hasmode = TRUE;
- $packageOK = TRUE;
-
- $readedModel=$model;
- } else {
- $name = "Unknown";
- }
- }
-
-
- #Log3 $name, 4, "CUL_TCM97001: CRC for TCM21.... Failed, checking other protocolls";
- # Check for Prologue
- if ($readedModel eq "Prologue" || (hex($a[0]) == 0x9 && $readedModel eq "Unknown")) {
- # Protocol prologue start everytime with 1001
- # e.g. 91080F614C 1001 0001 0000 1000 0000 1111 0110 0001 0100 1100
- # A B C D E F G H I
- # A = Startbit 1001
- # B+C = Random Address
- # D Bit 4 Battery, 3 Manual, 2+1 Channel
- # E+F+G Bit 15+16 negativ temp, 14-0 temp
- # H+I Hum
- #$def = $modules{CUL_TCM97001}{defptr}{$idType3};
- #$def = $modules{CUL_TCM97001}{defptr}{$idType1};
-
- $temp = (hex($a[4].$a[5].$a[6])) & 0x3FFF;
- my $negative = (hex($a[4])) & 0xC;
- if ($negative == 0xC) {
- $temp = (~$temp & 0x03FF) + 1;
- $temp = -$temp;
- }
- $temp = $temp / 10;
- if (!(hex($a[7]) == 0xC && hex($a[8]) == 0xC)) {
- $humidity = hex($a[7].$a[8]);
- }
-
-
- if (checkValues($temp, $humidity)) {
- $channel = (hex($a[3])) & 0x3;
- $batbit = (hex($a[3]) & 0x8) >> 3;
- $batbit = ~$batbit & 0x1; # Bat bit umdrehen
- $mode = (hex($a[3]) & 0x4) >> 2;
-
- $model="Prologue";
-
- if ($deviceCode ne $idType1) # new naming convention
- {
- if ( $enableLongIDs == TRUE || (($longids != "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/))))
- {
- Log3 $hash,4, "CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="CUL_TCM97001_" . $model . "_" . $channel;
- }
- }
-
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
- if(!$def) {
- Log3 $name, 2, "CUL_TCM97001 Unknown device $deviceCode, please define it";
- return "UNDEFINED $model" . substr($deviceCode, rindex($deviceCode,"_")) . " CUL_TCM97001 $deviceCode";
- }
- if (defined($humidity)) {
- if ($humidity >= 20) {
- $hashumidity = TRUE;
- }
- }
- $hasbatcheck = TRUE;
- $hasmode = TRUE;
- $packageOK = TRUE;
- $haschannel = TRUE;
-
- $readedModel=$model;
- } else {
- $name = "Unknown";
- }
- }
-
- if ($readedModel eq "NC_WS" || (hex($a[0]) == 0x5 && $readedModel eq "Unknown")) {
- # Implementation from Femduino
- # PEARL NC7159, LogiLink WS0002
- # /--------------------------------- Sensdortype
- # / / ---------------------------- ID, changes after every battery change
- # / / /--------------------- Battery state 0 == Ok
- # / / / / ------------------ forced send
- # / / / / / ---------------- Channel (0..2)
- # / / / / / / -------------- neg Temp: if 1 then temp = temp - 2048
- # / / / / / / / ----------- Temp
- # / / / / / / / /-- unknown
- # / / / / / / / / / Humidity
- # 0101 0010 1001 0 0 00 0 010 0011 0000 1 101 1101
- # Bit 0 4 12 13 14 16 17 28 29 36
- #$def = $modules{CUL_TCM97001}{defptr}{$idType3};
- $temp = (hex($a[4].$a[5].$a[6])) & 0x7FFF;
- my $negative = (hex($a[4])) & 0x8;
- if ($negative == 0x8) {
- $temp = (~$temp & 0x07FF) + 1;
- $temp = -$temp;
- }
- $temp = $temp / 10;
-
- $humidity = hex($a[7].$a[8]) & 0x7F;
- if (checkValues($temp, $humidity)) {
- $model="NC_WS";
- $channel = (hex($a[3])) & 0x3;
- $batbit = (hex($a[3]) & 0x8) >> 3;
- $batbit = ~$batbit & 0x1; # Bat bit umdrehen
- $mode = (hex($a[3]) & 0x4) >> 2;
-
- if ($deviceCode ne $idType1) # new naming convention
- {
- if ( $enableLongIDs == TRUE || (($longids != "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/))))
- {
- Log3 $hash,4, "CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="CUL_TCM97001_" . $model . "_" . $channel;
- }
- }
-
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
-
- if(!$def) {
- Log3 $name, 2, "CUL_TCM97001 Unknown device $deviceCode, please define it";
- return "UNDEFINED $model" . substr($deviceCode, rindex($deviceCode,"_")) . " CUL_TCM97001 $deviceCode";
- }
- $hashumidity = TRUE;
- $hasbatcheck = TRUE;
- $hasmode = TRUE;
- $packageOK = TRUE;
- $haschannel = TRUE;
- $readedModel=$model;
- } else {
- $name = "Unknown";
- }
- }
- if ($readedModel eq "Rubicson" || (hex($a[2]) == 0x8 && $readedModel eq "Unknown")) {
- # Protocol Rubicson has as nibble C every time 1000
- # e.g. F4806B8E14 1111 0100 1000 0000 0110 1011 1000 1110 0001 0100
- # A B C D E F G H I
- # A+B = Random Address
- # C = Rubicson = 1000
- # D+E+F 12 bit temp
- # G+H+I Unknown
- $def = $modules{CUL_TCM97001}{defptr}{$idType1};
- if($def) {
- $name = $def->{NAME};
- }
- $temp = (hex($a[3].$a[4].$a[5])) & 0x3FF;
- my $negative = (hex($a[3])) & 0xC;
- if ($negative == 0xC) {
- $temp = (~$temp & 0x03FF) + 1;
- $temp = -$temp;
- }
- $temp = $temp / 10;
- if (checkValues($temp, 50)) {
- $model="Rubicson";
-
- if ($deviceCode ne $idType1) # new naming convention
- {
- if ( $enableLongIDs == TRUE || (($longids != "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/))))
- {
- Log3 $hash,4, "CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="CUL_TCM97001_" . $model . "_" . $channel;
- }
- }
-
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
-
- if(!$def) {
- Log3 $name, 2, "CUL_TCM97001 Unknown device $deviceCode, please define it";
- return "UNDEFINED $model" . substr($deviceCode, rindex($deviceCode,"_")) . " CUL_TCM97001 $deviceCode";
- }
- $packageOK = TRUE;
-
- $readedModel=$model;
- } else {
- $name = "Unknown";
- }
- }
- if ( (checkCRC4($msg) == TRUE) && (isRain($msg)==TRUE) &&($readedModel eq "PFR_130" || $readedModel eq "Unknown")) {
- # Implementation from Femduino
- # Pollin PFR_130)
- # nibbles n2, n6 and n7 hold the Rain fall ticks
- # /--------------------------------- Channel, changes after every battery change
- # / / ------------------------ Battery state 0 == Ok
- # / / /------------------------ ??Battery changed, Sync startet
- # / / / ----------------------- n2 lower two bits ->rain ticks
- # / / / / /------------------- neg Temp: if 1 then temp = temp - 4096
- # / / / / /-------------------- 12 Bit Temperature
- # / / / / / /----- n6,n7 rain ticks 8 bit (n2 & 0x03 n6 n7)
- # / / / / / / /---- n8, CRC (xor n0 to n7)
- # 0101 0101 1 0 00 0001 0000 1011 11000100 xxxx
- # Bit 0 8 9 10 12 24 32
- $def = $modules{CUL_TCM97001}{defptr}{$idType1};
- if($def) {
- $name = $def->{NAME};
- }
- $temp = (hex($a[3].$a[4].$a[5])) & 0x7FF;
- my $negative = (hex($a[3])) & 0x8;
- if ($negative == 0x8) {
- $temp = (~$temp & 0x07FF) + 1;
- $temp = -$temp;
- }
- $temp = $temp / 10;
- Log3 $name, 5, "CUL_TCM97001: PFR_130 Temp=$temp";
-
- # rain values Pollin PFR_130
- $rainticks = (hex($a[2].$a[6].$a[7])) & 0x3FF; #mask n2 n6 n7 for rain ticks
- Log3 $name, 5, "CUL_TCM97001: PFR_130 rainticks=$rainticks";
- $rainMM = $rainticks / 25 * .5; # rain height in mm/qm, verified against sensor receiver display
- Log3 $name, 5, "CUL_TCM97001: PFR_130 rain mm=$rainMM";
-
- if (checkValues($temp, 50)) {
- $batbit = (hex($a[2]) & 0x8) >> 3; # in auriol_protocol_v20.pdf bat bit is n2 & 0x08, same
- $batbit = ~$batbit & 0x1; # Bat bit umdrehen
- $mode = (hex($a[2]) & 0x4) >> 2; # in auriol_protocol_v20.pdf mode is: n2 & 0x01, different
- $trend = (hex($a[7]) & 0x3); # in auriol_protocol_v20.pdf there is no trend bit
- $model="PFR_130";
- my $deviceCode;
-
- if (!defined($modules{CUL_TCM97001}{defptr}{$idType1}))
- {
- if ( $enableLongIDs == TRUE || (($longids != "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/))))
- {
- $deviceCode="CUL_TCM97001_".$idType1;
- Log3 $hash,4, "CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="CUL_TCM97001_" . $model . "_" . $channel;
- }
- } else { # Fallback for already defined devices use old naming convention
- $deviceCode=$idType1;
- }
-
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
-
- if(!$def) {
- Log3 $name, 2, "CUL_TCM97001 Unknown device $deviceCode, please define it";
- return "UNDEFINED $model" . substr($deviceCode, rindex($deviceCode,"_")) . " CUL_TCM97001 $deviceCode";
- }
- $hasbatcheck = TRUE;
- $hastrend = TRUE;
- $packageOK = TRUE;
- $hasmode = TRUE;
-
- $readedModel=$model;
- } else {
- $name = "Unknown";
- }
- }
- if ( (isRain($msg)!=TRUE) && ($readedModel eq "AURIOL" || $readedModel eq "Unknown") && ($readedModel ne "PFR_130")) {
- # Implementation from Femduino
- # AURIOL (Lidl Version: 09/2013)
- # /--------------------------------- Channel, changes after every battery change
- # / / ------------------------ Battery state 1 == Ok
- # / / /------------------------ Battery changed, Sync startet
- # / / / ----------------------- Unknown
- # / / / / /--------------------- neg Temp: if 1 then temp = temp - 4096
- # / / / / /---------------------- 12 Bit Temperature
- # / / / / / /---------- ??? CRC
- # / / / / / / /---- Trend 10 == rising, 01 == falling
- # 0101 0101 1 0 00 0001 0000 1011 1100 01 00
- # Bit 0 8 9 10 12 24 30
- $def = $modules{CUL_TCM97001}{defptr}{$idType1};
- if($def) {
- $name = $def->{NAME};
- }
- $temp = (hex($a[3].$a[4].$a[5])) & 0x7FF;
- my $negative = (hex($a[3])) & 0x8;
- if ($negative == 0x8) {
- $temp = (~$temp & 0x07FF) + 1;
- $temp = -$temp;
- }
- $temp = $temp / 10;
- if (checkValues($temp, 50)) {
- $batbit = (hex($a[2]) & 0x8) >> 3;
- $batbit = ~$batbit & 0x1; # Bat bit umdrehen
- $mode = (hex($a[2]) & 0x4) >> 2;
- $trend = (hex($a[7]) & 0x3);
- $model="AURIOL";
- my $deviceCode;
-
- if (!defined($modules{CUL_TCM97001}{defptr}{$idType1}))
- {
- if ( $enableLongIDs == TRUE || (($longids != "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/))))
- {
- $deviceCode="CUL_TCM97001_".$idType1;
- Log3 $hash,4, "CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="CUL_TCM97001_" . $model . "_" . $channel;
- }
- } else { # Fallback for already defined devices use old naming convention
- $deviceCode=$idType1;
- }
-
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
-
- if(!$def) {
- Log3 $name, 2, "CUL_TCM97001 Unknown device $deviceCode, please define it";
- return "UNDEFINED $model" . substr($deviceCode, rindex($deviceCode,"_")) . " CUL_TCM97001 $deviceCode";
- }
- $hasbatcheck = TRUE;
- $hastrend = TRUE;
- $packageOK = TRUE;
- $hasmode = TRUE;
-
- $readedModel=$model;
- } else {
- $name = "Unknown";
- }
- }
-
- #if (($readedModel eq "Unknown" || $readedModel eq "KW9010")) {
- if (checkCRCKW9010($msg) == TRUE && ($readedModel eq "Unknown" || $readedModel eq "KW9010")) {
- # Re: Tchibo Wetterstation 433 MHz - KW9010
- # See also http://forum.arduino.cc/index.php?PHPSESSID=ffoeoe9qeuv7rf4fh0d637hd74&topic=136836.msg1536416#msg1536416
- # /------------------------------------- Random ID part one
- # / / -------------------------------- Channel switch
- # / / /------------------------------- Random ID part two
- # / / / / ---------------------------- Battery state 0 == Ok
- # / / / / / --------------------------- Trend (continous, rising, falling
- # / / / / / / ------------------------- forced send
- # / / / / / / / ----------------------- Temperature
- # / / / / / / / /-------------- Temperature sign bit. if 1 then temp = temp - 4096
- # / / / / / / / / /------------ Humidity
- # / / / / / / / / / /----- Checksum
- # 0110 00 10 1 00 1 000000100011 00001101 1101
- # 0110 01 00 0 10 1 100110001001 00001011 0101
- # Bit 0 4 6 8 9 11 12 24 32
- #
- #5922B07BC0 42 21.2 66
- # 0101 10 01 0 01 0 001010110000 01111011 1100 0000
- # 000011010100 11011110
- # 212 222-156=66
- my @a = split("", $msg);
- my $bitReverse = undef;
- my $x = undef;
- foreach $x (@a) {
- $bitReverse = $bitReverse . reverse(sprintf("%04b",hex($x)));
- }
- Log3 $hash, 5 , "KW9010 CRC Matched: ($bitReverse)";
-
- my $hexReverse = unpack("H*", pack ("B*", $bitReverse));
- Log3 $hash, 5 , "KW9010 CRC Hex Matched: $hexReverse";
- #Split reversed a again
- my @aReverse = split("", $hexReverse);
- if (hex($aReverse[5]) > 3) {
- # negative temp
- $temp = ((hex($aReverse[3]) + hex($aReverse[4]) * 16 + hex($aReverse[5]) * 256));
- $temp = (~$temp & 0x03FF) + 1;
- $temp = -$temp/10;
- } else {
- # positive temp
- $temp = (hex($aReverse[3]) + hex($aReverse[4]) * 16 + hex($aReverse[5]) * 256)/10;
- }
- $humidity = hex($aReverse[7].$aReverse[6]) - 156;
-
- #if (checkValues($temp, $humidity)) {
- if (1) {
- Log3 $hash, 5 , "KW9010 values are matching";
-
- $batbit = (hex($a[2]) & 0x8) >> 3;
- #$mode = (hex($a[2]) & 0x4) >> 2;
- $channel = ((hex($a[1])) & 0xC) >> 2;
- $mode = (hex($a[2]) & 0x1);
- $trend = (hex($a[2]) & 0x6) >> 1;
-
- $model="KW9010";
-
- if ($deviceCode ne $idType1) # new naming convention
- {
- if ( $enableLongIDs == TRUE || (($longids != "0") && ($longids eq "1" || $longids eq "ALL" || (",$longids," =~ m/,$model,/))))
- {
- Log3 $hash,4, "CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="CUL_TCM97001_" . $model . "_" . $channel;
- }
- }
-
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
- if(!$def) {
- Log3 $name, 2, "CUL_TCM97001 Unknown device $deviceCode, please define it";
- return "UNDEFINED $model" . substr($deviceCode, rindex($deviceCode,"_")) . " CUL_TCM97001 $deviceCode";
- }
- $hashumidity = TRUE;
- $packageOK = TRUE;
- $hasbatcheck = TRUE;
- $hastrend = TRUE;
- $haschannel = TRUE;
-
- $readedModel=$model;
- } else {
- Log3 $hash, 5 , "KW9010 t:$temp / h:$humidity mismatch";
-
- $name = "Unknown";
- }
- }
-
- }
-
-
- if ($packageOK == TRUE) {
- # save lastT, calc rainMM sum for day and hour
- my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
- my $lastDay=$mday;
- my $lastHour=$hour;
- my $rainSumDay=0;
- my $rainSumHour=0;
-
- if($def) {
- $def->{lastT} = $now;
- }
- readingsBeginUpdate($def);
- my ($val, $valH, $state);
-
- if (defined($temp)) {
- $msgtype = "temperature";
- $val = sprintf("%2.1f", ($temp) );
- $state="T: $val";
- # if ($hashumidity == TRUE) {
- # if ($model eq "Prologue") {
- # # plausibility check
- # my $oldhumidity = ReadingsVal($name, "humidity", "unknown");
- # if ($oldhumidity eq "unknown" || ($humidity+15 > $oldhumidity && $humidity-15 < $oldhumidity)) {
- # $hashumidity = TRUE;
- # } else {
- # $hashumidity = FALSE;
- # }
- # }
- # }
- }
- if ($model eq "PFR_130") {
- $lastDay = ReadingsVal($name, "lastDay", $lastDay);
- $lastHour = ReadingsVal($name, "lastHour", $lastHour);
- $rainSumDay=ReadingsVal($name, "RainD", $rainSumDay);
- $rainSumHour=ReadingsVal($name, "RainH", $rainSumHour);
-
- $msgtype = "temperature";
- $val = sprintf("%2.1f", ($temp) );
- $state="T: $val";
- Log3 $name, 5, "CUL_TCM97001 1. $lastDay : $lastHour : $rainSumDay : $rainSumHour";
- #rain Pollin PFR-130
- if($mday==$lastDay){
- #same day add rainMM
- $rainSumDay+=$rainMM;
- }else {
- #new day, start over
- $rainSumDay=$rainMM;
- }
- if($hour==$lastHour){
- $rainSumHour+=$rainMM;
- }else{
- $rainSumHour=$rainMM;
- }
-
- readingsBulkUpdate($def, "lastDay", $lastDay );
- readingsBulkUpdate($def, "lastHour", $lastHour );
- readingsBulkUpdate($def, "RainD", $rainSumDay );
- readingsBulkUpdate($def, "RainH", $rainSumHour );
-
- Log3 $name, 5, "CUL_TCM97001 2. $lastDay : $lastHour : $rainSumDay : $rainSumHour";
- $state="$state RainH: $rainSumHour RainD: $rainSumDay R: $rainticks Rmm: $rainMM";
- Log3 $name, 5, "CUL_TCM97001 $msgtype $name $id3 state: $state";
- } else {
- ### edited by elektron-bbs
- # W174 has no temperature
- if ($model ne "W174") {
- $msgtype = "temperature";
- $val = sprintf("%2.1f", ($temp) );
- $state="T: $val";
- # if ($hashumidity == TRUE) {
- # if ($model eq "Prologue") {
- # # plausibility check
- # my $oldhumidity = ReadingsVal($name, "humidity", "unknown");
- # if ($oldhumidity eq "unknown" || ($humidity+15 > $oldhumidity && $humidity-15 < $oldhumidity)) {
- # $hashumidity = TRUE;
- # } else {
- # $hashumidity = FALSE;
- # }
- # }
- # }
- }
- }
-
- #zusätzlich Daten für Wetterstation
- if ($hasrain == TRUE) {
- ### inserted by elektron-bbs
- #my $rain_old = ReadingsVal($name, "rain", "unknown");
- my $rain_old = ReadingsVal($name, "rain", 0);
- if ($rain != $rain_old) {
- readingsBulkUpdate($def, "israining", "yes");
- } else {
- readingsBulkUpdate($def, "israining", "no");
- }
- readingsBulkUpdate($def, "rain", $rain );
- $state = "R: $rain";
- $hasrain = FALSE;
- }
-
- if ($haswind == TRUE) {
- readingsBulkUpdate($def, "windGust", $windGuest );
- readingsBulkUpdate($def, "windDirection", $windDirection );
- #readingsBulkUpdate($def, "windDirectionDegree", $windDirection * 360 / 16);
- readingsBulkUpdate($def, "windDirectionText", $windDirectionText );
- $state = "Wg: $windGuest "." Wd: $windDirectionText ";
- $haswind = FALSE;
- }
-
- if ($haswindspeed == TRUE) {
- readingsBulkUpdate($def, "windSpeed", $windSpeed );
- $state = "Ws: $windSpeed ";
- $haswindspeed = FALSE;
- }
-
- if ($hashumidity == TRUE) {
- $msgtypeH = "humidity";
- $valH = $humidity;
- $state="$state H: $valH";
- Log3 $name, 4, "CUL_TCM97001 $msgtype $name $id3 T: $val H: $valH";
- } else {
- $msgtype = "other";
- Log3 $name, 4, "CUL_TCM97001 $msgtype $name $id3";
- #Log3 $name, 4, "CUL_TCM97001 $msgtype $name $id3 ";
- }
-
- if($hastrend) {
- my $readTrend = ReadingsVal($name, "trend", "unknown");
- if ($trend == 1) {
- if ($readTrend ne "falling") { readingsBulkUpdate($def, "trend", "falling"); }
- } else {
- if ($readTrend ne "rising") { readingsBulkUpdate($def, "trend", "rising"); }
- }
- }
- if ($hasbatcheck) {
- my $battery = ReadingsVal($name, "battery", "unknown");
- if ($batbit) {
- if ($battery ne "ok") { readingsBulkUpdate($def, "battery", "ok"); }
- } else {
- if ($battery ne "low") { readingsBulkUpdate($def, "battery", "low"); }
- }
- }
- if ($hasmode) {
- my $modeVal = ReadingsVal($name, "mode", "unknown");
- if ($mode) {
- if ($modeVal ne "forced") { readingsBulkUpdate($def, "mode", "forced"); }
- } else {
- if ($modeVal ne "normal") { readingsBulkUpdate($def, "mode", "normal"); }
- }
- }
- if ($haschannel) {
- my $readChannel = ReadingsVal($name, "channel", "");
- if (defined($readChannel) && $readChannel ne $channel) { readingsBulkUpdate($def, "channel", $channel); }
- }
- # if ($model eq "Prologue" || $model eq "Eurochron") {
- # # plausibility check
- # my $oldtemp = ReadingsVal($name, "temperature", "unknown");
- # if ($oldtemp eq "unknown" || ($val+5 > $oldtemp && $val-5 < $oldtemp)) {
- # readingsBulkUpdate($def, $msgtype, $val);
- # }
- # } else {
- readingsBulkUpdate($def, $msgtype, $val);
- # }
- if ($hashumidity == TRUE) {
- readingsBulkUpdate($def, $msgtypeH, $valH);
- }
-
- readingsBulkUpdate($def, "state", $state);
- # for testing only
- #my $rawlen = length($msg);
- #my $rawVal = substr($msg, 0, $rawlen-2);
- #readingsBulkUpdate($def, "RAW", $rawVal);
- readingsEndUpdate($def, 1);
- if(defined($rssi)) {
- $def->{RSSI} = $rssi;
- }
- $attr{$name}{model} = $model;
- return $name;
- } else {
- if (length($msg) == 8 || length($msg) == 10 || length($msg) == 12 || length($msg) == 14) {
- my $defUnknown = $modules{CUL_TCM97001}{defptr}{"CUL_TCM97001_Unknown"};
-
- if (!$defUnknown) {
- Log3 "Unknown", 2, "CUL_TCM97001 Unknown device Unknown, please define it";
- return "UNDEFINED Unknown CUL_TCM97001 CUL_TCM97001_Unknown";
- }
- $name = $defUnknown->{NAME};
- Log3 $name, 4, "CUL_TCM97001 Device not implemented yet name Unknown msg $msg";
- my $rawlen = length($msg);
- my $rawVal = substr($msg, 0, $rawlen-2);
- my $state="Code: $rawVal";
- if ($defUnknown) {
- $defUnknown->{lastT} = $now;
- }
- $attr{$name}{model} = $model;
- readingsBeginUpdate($defUnknown);
- readingsBulkUpdate($defUnknown, "state", $state);
- # for testing only
- #readingsBulkUpdate($defUnknown, "RAW", $rawVal);
- readingsEndUpdate($defUnknown, 1);
- if(defined($rssi)) {
- $defUnknown->{RSSI} = $rssi;
- }
- #my $defSvg = $defs{"SVG_CUL_TCM97001_Unknown"};
- #if ($defSvg) {
- # CommandDelete(undef, $defSvg->{NAME});
- #}
- return $name;
- }
- }
- return undef;
- }
- 1;
- =pod
- =item summary This module interprets temperature sensor messages.
- =item summary_DE Module verarbeitet empfangene Nachrichten von Temp-Sensoren.
- =begin html
- <a name="CUL_TCM97001"></a>
- <h3>CUL_TCM97001</h3>
- <ul>
- The CUL_TCM97001 module interprets temperature sensor messages received by a Device like CUL, CUN, SIGNALduino etc.<br>
- <br>
- <b>Supported models:</b>
- <ul>
- <li>TCM97...</li>
- <li>ABS700</li>
- <li>TCM21....</li>
- <li>Prologue</li>
- <li>Rubicson</li>
- <li>NC_WS</li>
- <li>GT_WT_02</li>
- <li>AURIOL</li>
- <li>Eurochron</li>
- <li>KW9010</li>
- </ul>
- <br>
- New received device packages are add in fhem category CUL_TCM97001 with autocreate.
- <br><br>
- <a name="CUL_TCM97001_Define"></a>
- <b>Define</b>
- <ul>The received devices created automatically.<br>
- The ID of the defive are the first two Hex values of the package as dezimal.<br>
- </ul>
- <br>
- <a name="CUL_TCM97001 Events"></a>
- <b>Generated events:</b>
- <ul>
- <li>temperature: The temperature</li>
- <li>humidity: The humidity (if available)</li>
- <li>battery: The battery state: low or ok (if available)</li>
- <li>channel: The Channelnumber (if available)</li>
- <li>trend: The temperature trend (if available)</li>
- </ul>
- <br>
- <b>Attributes</b>
- <ul>
- <li><a href="#IODev">IODev</a>
- Note: by setting this attribute you can define different sets of 8
- devices in FHEM, each set belonging to a Device which is capable of receiving the signals. It is important, however,
- that a device is only received by the defined IO Device, e.g. by using
- different Frquencies (433MHz vs 868MHz)
- </li>
- <li><a href="#do_not_notify">do_not_notify</a></li>
- <li><a href="#ignore">ignore</a></li>
- <li><a href="#model">model</a> (TCM97..., ABS700, TCM21...., Prologue, Rubicson, NC_WS, GT_WT_02, AURIOL, KW9010, Unknown)</li>
- <li><a href="#showtime">showtime</a></li>
- <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
- </ul>
- </ul>
- =end html
- =begin html_DE
- <a name="CUL_TCM97001"></a>
- <h3>CUL_TCM97001</h3>
- <ul>
- Das CUL_TCM97001 Module verarbeitet von einem IO Gerät (CUL, CUN, SIGNALDuino, etc.) empfangene Nachrichten von Temperatur \ Wind \ Rain - Sensoren.<br>
- <br>
- <b>Unterstütze Modelle:</b>
- <ul>
- <li>TCM97...</li>
- <li>ABS700</li>
- <li>TCM21....</li>
- <li>Prologue</li>
- <li>Rubicson</li>
- <li>NC_WS</li>
- <li>GT_WT_02</li>
- <li>AURIOL</li>
- <li>Eurochron</li>
- <li>KW9010</li>
- <li>W155 (wind/rain)</li>
- <li>PFR-130 (rain)</li>
- <li>W174 (rain)</li>
- </ul>
- <br>
- Neu empfangene Sensoren werden in der fhem Kategory CUL_TCM97001 per autocreate angelegt.
- <br><br>
- <a name="CUL_TCM97001_Define"></a>
- <b>Define</b>
- <ul>Die empfangenen Sensoren werden automatisch angelegt.<br>
- Die ID der angelgten Sensoren sind die ersten zwei HEX Werte des empfangenen Paketes in dezimaler Schreibweise.<br>
- </ul>
- <br>
- <a name="CUL_TCM97001 Events"></a>
- <b>Generierte Events:</b>
- <ul>
- <li>temperature: Die aktuelle Temperatur</li>
- <li>humidity: Die aktuelle Luftfeutigkeit (falls verfügbar)</li>
- <li>battery: Der Batteriestatus: low oder ok (falls verfügbar)</li>
- <li>channel: Kanalnummer (falls verfügbar)</li>
- <li>trend: Der Temperaturtrend (falls verfügbar)</li>
- <li>israining: Aussage Regen zwichen zwei Messungen (falls verfügbar)</li>
- <li>rain: Der Regenwert, eine fortlaufende Zahl bis zum Batteriewechsel (falls verfügbar)</li>
- </ul>
- <br>
- <b>Attribute</b>
- <ul>
- <li><a href="#IODev">IODev</a>
- Spezifiziert das physische Gerät, das die Ausstrahlung der Befehle für das
- "logische" Gerät ausführt. Ein Beispiel für ein physisches Gerät ist ein CUL.<br>
- </li>
- <li><a href="#do_not_notify">do_not_notify</a></li>
- <li><a href="#ignore">ignore</a></li>
- <li><a href="#model">model</a> (ABS700, AURIOL, GT_WT_02, KW9010, NC_WS, PFR-130, Prologue, Rubicson, TCM21...., TCM97…, Unknown, W174)</li>
- <li><a href="#showtime">showtime</a></li>
- <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
- </ul>
- </ul>
- =end html_DE
- =cut
|