| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930 |
- # 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 16274 2018-02-25 20:42:39Z 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 " .
- "max-deviation-temp:1,2,3,4,5,6,7,8,9,10,15,20,25,30,35,40,45,50 ".
- "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 checkCRC4 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 checkCRC4 OK for msg=($msg)";
- return TRUE;
- }
- Log3 "checkCRC4", 5, "CUL_TCM97001 checkCRC4 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, "CUL_TCM97001 isRain 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, "CUL_TCM97001 isRain for msg=($msg) = FALSE";
- return FALSE;
- }
- Log3 "isRain", 5, "CUL_TCM97001 isRain for msg=($msg) = TRUE";
- return TRUE;
- }
- #
- # CRC Check for KW9010....
- #
- sub checkCRCKW9010 {
- my $msg = shift;
- Log3 "CUL_TCM97001", 5 , "CUL_TCM97001 checkCRCKW9010 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 , "CUL_TCM97001 checkCRCKW9010 calc crc is: $CRC";
- Log3 "CUL_TCM97001", 5 , "CUL_TCM97001 checkCRCKW9010 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 $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 $iodev = $hash->{NAME};
- 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, "$iodev: CUL_TCM97001 $name $id3 ($msg) length: $l RSSI: $rssi";
- } else {
- Log3 $name, 4, "$iodev: 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($iodev,'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 "ABS700") {
- $temp = (hex($a[2].$a[3]) & 0x7F)+(hex($a[5])/10);
- if ((hex($a[2]) & 0x8) == 0x8) {
- $temp = -$temp;
- }
-
- # Sanity check temperature
- if($def) {
- my $timeSinceLastUpdate = ReadingsAge($iodev, "state", 0);
- if ($timeSinceLastUpdate < 0) {
- $timeSinceLastUpdate *= -1;
- }
- if (defined($hash->{READINGS}{temperature}{VAL})) {
- my $diffTemp = 0;
- my $oldTemp = $hash->{READINGS}{temperature}{VAL};
- my $maxdeviation = AttrVal($name, "max-deviation-temp", 1); # default 1 K
- if ($temp > $oldTemp) {
- $diffTemp = ($temp - $oldTemp);
- } else {
- $diffTemp = ($oldTemp - $temp);
- }
- $diffTemp = sprintf("%.1f", $diffTemp);
- Log3 $name, 4, "$iodev: $name old temp $oldTemp, age $timeSinceLastUpdate, new temp $temp, diff temp $diffTemp";
- my $maxDiffTemp = $timeSinceLastUpdate / 60 + $maxdeviation; # maxdeviation + 1.0 Kelvin/Minute
- $maxDiffTemp = sprintf("%.1f", $maxDiffTemp + 0.05); # round 0.1
- Log3 $name, 4, "$iodev: $name max difference temperature $maxDiffTemp K";
- if ($diffTemp > $maxDiffTemp) {
- Log3 $name, 3, "$iodev: $name ERROR - Temp diff too large (old $oldTemp, new $temp, diff $diffTemp)";
- return "";
- }
- }
- }
- 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, "$iodev: CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="$iodev: CUL_TCM97001_" . $model;
- }
- } else {
- $deviceCode=$tcm97id;
- }
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
- if(!$def) {
- Log3 $name, 2, "$iodev: 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;
- }
- }
-
- 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, "$iodev: CUL_TCM97001 Mode: manual triggert";
- } else {
- Log3 $name, 5, "$iodev: CUL_TCM97001 Mode: auto triggert";
- }
- if ($unknown) {
- Log3 $name, 5, "$iodev: 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, "$iodev: CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="$iodev: CUL_TCM97001_" . $model;
- }
- } else {
- $deviceCode=$tcm97id;
- }
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
-
-
-
- if(!$def) {
- Log3 $name, 2, "$iodev: 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;
- }
- }
- } 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, "$iodev: 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, "$iodev: 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, "$iodev: 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, "$iodev: 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, "$iodev: 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, "$iodev: 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, "$iodev: 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, "$iodev: CUL_TCM97001 $name original-msg: $msg , reversed nibbles: $hexReverse";
- Log3 $hash,5, "$iodev: 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, "$iodev: CUL_TCM97001 $name detected rain gauge message ok";
- $batbit = $aReverse[2] & 0b0001; # Bat bit normal=0, low=1
- Log3 $hash,4, "$iodev: 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, "$iodev: 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($iodev, "state", 0);
- if ($timeSinceLastUpdate < 0) {
- $timeSinceLastUpdate *= -1;
- }
- $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, "$iodev: 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, "$iodev: CUL_TCM97001 $name max difference rain $maxDiffRain l";
- if ($diffRain > $maxDiffRain) {
- Log3 $hash, 3, "$iodev: CUL_TCM97001 $name ERROR - Rain diff too large (old $oldRain, new $rain, diff $diffRain)";
- return "";
- }
- }
- } else {
- Log3 $name, 2, "$iodev: CUL_TCM97001 Unknown device $deviceCode, please define it";
- return "UNDEFINED $model" . substr($deviceCode, rindex($deviceCode,"_")) . " CUL_TCM97001 $deviceCode";
- }
- Log3 $hash,4, "$iodev: 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, "$iodev: 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, "$iodev: CUL_TCM97001 nib2:$msgtype aRev: $aReverse[2]";
-
- $msgtype = substr(sprintf( "%04b", hex( $aReverse[2])),1,2);
- Log3 $hash,4, "$iodev: CUL_TCM97001 nib2R:$msgtype hexR: $hexReverse";
- if ( $msgtype ne "11") {
- Log3 $hash,4, "$iodev: 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, "$iodev: 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, "$iodev: 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, "$iodev: 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, "$iodev: CUL_TCM97001 rain: $rain ";
- }
- }
-
- ### edited by @HomeAutoUser
- if (checkValues($temp, $humidity) == TRUE) { # unplausibel Werte sonst teilweise
- $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, "$iodev: CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="$iodev: CUL_TCM97001_" . $model . "_" . $channel;
- }
- }
-
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
- if(!$def) {
- Log3 $name, 2, "$iodev: 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, "$iodev: CUL_TCM97001 using longid: $longids model: $model";
- } else {
- $deviceCode="$iodev: CUL_TCM97001_" . $model . "_" . $channel;
- }
- }
-
- $def = $modules{CUL_TCM97001}{defptr}{$deviceCode};
- if($def) {
- $name = $def->{NAME};
- }
- if(!$def) {
- Log3 $name, 2, "$iodev: 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, "$iodev: 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, "$iodev: 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, "$iodev: 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, "$iodev: 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, "$iodev: 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, "$iodev: 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, "$iodev: 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, "$iodev: CUL_TCM97001 PFR_130 rainticks=$rainticks";
- $rainMM = $rainticks / 25 * .5; # rain height in mm/qm, verified against sensor receiver display
- Log3 $name, 5, "$iodev: 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, "$iodev: 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, "$iodev: 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, "$iodev: 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, "$iodev: 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 , "$iodev: KW9010 CRC Matched: ($bitReverse)";
-
- my $hexReverse = unpack("H*", pack ("B*", $bitReverse));
- Log3 $hash, 5 , "$iodev: 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;
-
- ### edited by @HomeAutoUser
- if (checkValues($temp, $humidity) == 1) { # unplausibel Werte sonst teilweise
- Log3 $hash, 5 , "$iodev: 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, "$iodev: 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, "$iodev: 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 , "$iodev: KW9010 t:$temp / h:$humidity mismatch";
-
- $name = "Unknown";
- }
- }
-
- }
-
- # Ignoriere dieses Gerät. Das Gerät wird keine FileLogs/notifys triggern, empfangene Befehle
- # werden stillschweigend ignoriert. Das Gerät wird weder in der Device-List angezeigt,
- # noch wird es in Befehlen mit "Wildcard"-Namenspezifikation (siehe devspec) erscheinen.
- return "" if(IsIgnored($name)); # wenn Attribut "ignore" gesetzt ist, werden alle Ausgaben ignoriert
-
- 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, "$iodev: 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, "$iodev: CUL_TCM97001 2. $lastDay : $lastHour : $rainSumDay : $rainSumHour";
- $state="$state RainH: $rainSumHour RainD: $rainSumDay R: $rainticks Rmm: $rainMM";
- Log3 $name, 5, "$iodev: 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, "$iodev: CUL_TCM97001 $msgtype $name $id3 T: $val H: $valH";
- } else {
- if ($model eq "W174") {
- $msgtype = "other";
- }
- Log3 $name, 4, "$iodev: 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, "$iodev: CUL_TCM97001 Unknown device Unknown, please define it";
- return "UNDEFINED Unknown CUL_TCM97001 CUL_TCM97001_Unknown";
- }
- $name = $defUnknown->{NAME};
- Log3 $name, 4, "$iodev: 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>ABS700</li>
- <li>AURIOL</li>
- <li>Eurochron</li>
- <li>GT_WT_02</li>
- <li>KW9010</li>
- <li>NC_WS</li>
- <li>TCM21....</li>
- <li>TCM97...</li>
- <li>PFR-130 (rain)</li>
- <li>Prologue</li>
- <li>Rubicson</li>
- <li>W155 (wind/rain)</li>
- <li>W174 (rain)</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> (ABS700, AURIOL, GT_WT_02, KW9010, NC_WS, PFR-130, Prologue, Rubicson, TCM21...., TCM97…, Unknown, W174)</li>
- <li>max-deviation-temp: (default:1, allowed values: 1,2,3,4,5,6,7,8,9,10,15,20,25,30,35,40,45,50)</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>ABS700</li>
- <li>AURIOL</li>
- <li>Eurochron</li>
- <li>GT_WT_02</li>
- <li>KW9010</li>
- <li>NC_WS</li>
- <li>TCM21....</li>
- <li>TCM97...</li>
- <li>PFR-130 (rain)</li>
- <li>Prologue</li>
- <li>Rubicson</li>
- <li>W155 (wind/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>max-deviation-temp: (Default:1, erlaubte Werte: 1,2,3,4,5,6,7,8,9,10,15,20,25,30,35,40,45,50)<br>
- Maximal erlaubte Abweichung der gemessenen Temperatur zum vorhergehenden Wert in Kelvin.<br></li>
- <li><a href="#showtime">showtime</a></li>
- <li><a href="#readingFnAttributes">readingFnAttributes</a></li>
- </ul>
- </ul>
- =end html_DE
- =cut
|