From e922daabb2c8bf4aa3eebd5ec3516b0451e6ee78 Mon Sep 17 00:00:00 2001 From: HomeAuto_User <> Date: Mon, 23 Nov 2020 21:27:08 +0000 Subject: [PATCH] 14_SD_BELL.pm: revised code git-svn-id: https://svn.fhem.de/fhem/trunk@23222 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 1 + fhem/FHEM/14_SD_BELL.pm | 799 ++++++++++++++++++++-------------------- 2 files changed, 407 insertions(+), 393 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 05fe792b2..3a0c1b719 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,6 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - change: 14_SD_BELL: revised code Perl::Critic - feature: 14_SD_UT.pm model Novy_840039: added cmd reset_clean_led revised code Perl::Critic diff --git a/fhem/FHEM/14_SD_BELL.pm b/fhem/FHEM/14_SD_BELL.pm index 730e97d46..b4fdea45c 100644 --- a/fhem/FHEM/14_SD_BELL.pm +++ b/fhem/FHEM/14_SD_BELL.pm @@ -3,7 +3,8 @@ # # The file is part of the SIGNALduino project. # The purpose of this module is to support many wireless BELL devices. -# 2018 - 2020 - HomeAuto_User & elektron-bbs +# +# 2018-2020 - HomeAuto_User, elektron-bbs # #################################################################################################################################### # - wireless doorbell TCM_234759 Tchibo [Protocol 15] length 12-20 (3-5) @@ -42,60 +43,60 @@ use lib::SD_Protocols; ### HASH for all modul models ### my %models = ( - # keys(model) => values - "unknown" => { hex_lengh => "99", # length only for comparison - Protocol => "00", - doubleCode => "no" - }, - "TCM_234759" => { hex_lengh => "3,4,5", - Protocol => "15", - doubleCode => "no" - }, - "FreeTec_PE-6946" => { hex_lengh => "6", - Protocol => "32", - doubleCode => "no" - }, - "Elro_DB200_/_KANGTAI_/_unitec" => { hex_lengh => "8", - Protocol => "41", - doubleCode => "yes" - }, - "Pollin_551227" => { hex_lengh => "7", - Protocol => "42", - doubleCode => "no" - }, - "FG_/_Basic-Serie" => { hex_lengh => "6", - Protocol => "57", - doubleCode => "no" - }, - "Heidemann_|_Heidemann_HX_|_VTX-BELL" => { hex_lengh => "3", - Protocol => "79", - doubleCode => "no" - }, - "Grothe_Mistral_SE_01" => { hex_lengh => "6", # length of device def, not message!!! message length = "10" - Protocol => "96", - doubleCode => "no" - }, - "Grothe_Mistral_SE_03" => { hex_lengh => "6", # length of device def, not message!!! message length = "12" - Protocol => "96", - doubleCode => "no" - }, - "GEA-028DB" => { hex_lengh => "4", - Protocol => "98", - doubleCode => "no" - }, + # keys(model) => values + 'unknown' => { hex_lengh => '99', # length only for comparison + Protocol => '00', + doubleCode => 'no' + }, + 'TCM_234759' => { hex_lengh => '3,4,5', + Protocol => '15', + doubleCode => 'no' + }, + 'FreeTec_PE-6946' => { hex_lengh => '6', + Protocol => '32', + doubleCode => 'no' + }, + 'Elro_DB200_/_KANGTAI_/_unitec' => { hex_lengh => '8', + Protocol => '41', + doubleCode => 'yes' + }, + 'Pollin_551227' => { hex_lengh => '7', + Protocol => '42', + doubleCode => 'no' + }, + 'FG_/_Basic-Serie' => { hex_lengh => '6', + Protocol => '57', + doubleCode => 'no' + }, + 'Heidemann_|_Heidemann_HX_|_VTX-BELL' => { hex_lengh => '3', + Protocol => '79', + doubleCode => 'no' + }, + 'Grothe_Mistral_SE_01' => { hex_lengh => '6', # length of device def, not message!!! message length = '10' + Protocol => '96', + doubleCode => 'no' + }, + 'Grothe_Mistral_SE_03' => { hex_lengh => '6', # length of device def, not message!!! message length = '12' + Protocol => '96', + doubleCode => 'no' + }, + 'GEA-028DB' => { hex_lengh => '4', + Protocol => '98', + doubleCode => 'no' + }, ); sub SD_BELL_Initialize($) { - my ($hash) = @_; - $hash->{Match} = "^P(?:15|32|41|42|57|79|96|98)#.*"; - $hash->{DefFn} = "SD_BELL::Define"; - $hash->{UndefFn} = "SD_BELL::Undef"; - $hash->{ParseFn} = "SD_BELL::Parse"; - $hash->{SetFn} = "SD_BELL::Set"; - $hash->{AttrFn} = "SD_BELL::Attr"; - $hash->{AttrList} = "repeats:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,20,25,30 IODev do_not_notify:1,0 ignore:0,1 showtime:1,0 model:".join(",", sort keys %models) . " $main::readingFnAttributes"; - $hash->{AutoCreate} = {"SD_BELL.*" => {FILTER => "%NAME", autocreateThreshold => "4:180", GPLOT => ""}}; + my ($hash) = @_; + $hash->{Match} = '^P(?:15|32|41|42|57|79|96|98)#.*'; + $hash->{DefFn} = 'SD_BELL::Define'; + $hash->{UndefFn} = 'SD_BELL::Undef'; + $hash->{ParseFn} = 'SD_BELL::Parse'; + $hash->{SetFn} = 'SD_BELL::Set'; + $hash->{AttrFn} = 'SD_BELL::Attr'; + $hash->{AttrList} = 'repeats:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,20,25,30 IODev do_not_notify:1,0 ignore:0,1 showtime:1,0 model:'.join(',', sort keys %models) . " $main::readingFnAttributes"; + $hash->{AutoCreate} = {'SD_BELL.*' => {FILTER => '%NAME', autocreateThreshold => '4:180', GPLOT => ''}}; } ### unterer Teil ### @@ -107,330 +108,342 @@ use POSIX; use GPUtils qw(:all); # wird für den Import der FHEM Funktionen aus der fhem.pl benötigt -my $missingModul = ""; +my $missingModul = ''; ## Import der FHEM Funktionen BEGIN { - GP_Import(qw( - AssignIoPort - AttrVal - attr - defs - IOWrite - InternalVal - Log3 - modules - readingsBeginUpdate - readingsBulkUpdate - readingsDelete - readingsEndUpdate - readingsSingleUpdate - )) + GP_Import(qw( + AssignIoPort + AttrVal + attr + defs + IOWrite + InternalVal + Log3 + modules + readingsBeginUpdate + readingsBulkUpdate + readingsDelete + readingsEndUpdate + readingsSingleUpdate + )) }; ################################### sub Define($$) { - my ($hash, $def) = @_; - my @a = split("[ \t][ \t]*", $def); - my $hash_name; - my $name = $hash->{NAME}; - my $protocol = $a[2]; - my $hex_lengh = length($a[3]); - my $doubleCode = "no"; + my ($hash, $def) = @_; + my @a = split("[ \t][ \t]*", $def); + my $hash_name; + my $name = $hash->{NAME}; + my $protocol = $a[2]; + my $hex_lengh = length($a[3]); + my $doubleCode = 'no'; + my $iodevice; + my $ioname; - #Log3 $name, 3, "SD_BELL_Def name=$a[0] protocol=$protocol HEX-Value=$a[3] hex_lengh=$hex_lengh"; + #Log3 $name, 3, "SD_BELL_Def name=$a[0] protocol=$protocol HEX-Value=$a[3] hex_lengh=$hex_lengh"; - # Argument 0 1 2 3 4 - return "SD_BELL: wrong syntax: define SD_BELL " if(int(@a) < 3 || int(@a) > 5); - ### checks - doubleCode yes ### - return "SD_BELL: wrong $a[2]" if not($a[2] =~ /^(?:15|32|41|42|57|79|96|98)/s); - return "SD_BELL: wrong HEX-Value! Protocol $a[2] HEX-Value <$a[3]> not HEX (0-9 | a-f | A-F)" if (($protocol != 41) && not $a[3] =~ /^[0-9a-fA-F]*$/s); - return "SD_BELL: wrong HEX-Value! Protocol $a[2] HEX-Value <$a[3]> not HEX (0-9 | a-f | A-F) or length wrong!" if (($protocol == 41) && not $a[3] =~ /^[0-9a-fA-F]{8}_[0-9a-fA-F]{8}$/s); + # Argument 0 1 2 3 4 + return 'SD_BELL: wrong syntax: define SD_BELL ' if(int(@a) < 3 || int(@a) > 5); + ### checks - doubleCode yes ### + return "SD_BELL: wrong $a[2]" if not($a[2] =~ /^(?:15|32|41|42|57|79|96|98)/xms); + return "SD_BELL: wrong HEX-Value! Protocol $a[2] HEX-Value <$a[3]> not HEX (0-9 | a-f | A-F)" if (($protocol != 41) && not $a[3] =~ /^[0-9a-fA-F]*$/xms); + return "SD_BELL: wrong HEX-Value! Protocol $a[2] HEX-Value <$a[3]> not HEX (0-9 | a-f | A-F) or length wrong!" if (($protocol == 41) && not $a[3] =~ /^[0-9a-fA-F]{8}_[0-9a-fA-F]{8}$/xms); - ($hash_name) = grep { $models{$_}{Protocol} eq $protocol } keys %models; # search protocol --> model - $doubleCode = $models{$hash_name}{doubleCode}; # read note doubleCode + ($hash_name) = grep { $models{$_}{Protocol} eq $protocol } keys %models; # search protocol --> model + $doubleCode = $models{$hash_name}{doubleCode}; # read note doubleCode - $hash->{doubleCode} = "Code alternates between two RAWMSG" if($protocol == 41); - $hash->{lastMSG} = ""; - $hash->{bitMSG} = ""; - my $iodevice = $a[4] if($a[4]); + $hash->{doubleCode} = 'Code alternates between two RAWMSG' if($protocol == 41); + $hash->{lastMSG} = ''; + $hash->{bitMSG} = ''; + $iodevice = $a[4] if($a[4]); - $modules{SD_BELL}{defptr}{$hash->{DEF}} = $hash; - my $ioname = $modules{SD_BELL}{defptr}{ioname} if (exists $modules{SD_BELL}{defptr}{ioname} && not $iodevice); - $iodevice = $ioname if not $iodevice; + $modules{SD_BELL}{defptr}{$hash->{DEF}} = $hash; + $ioname = $modules{SD_BELL}{defptr}{ioname} if (exists $modules{SD_BELL}{defptr}{ioname} && not $iodevice); + $iodevice = $ioname if not $iodevice; - ### Attributes | model set after codesyntax ### - $attr{$name}{model} = $hash_name if ( not exists($attr{$name}{model}) ); # set model, if only undef --> new def - $attr{$name}{room} = "SD_BELL" if ( not exists( $attr{$name}{room} ) ); # set room, if only undef --> new def + ### Attributes | model set after codesyntax ### + $attr{$name}{model} = $hash_name if ( not exists($attr{$name}{model}) ); # set model, if only undef --> new def + $attr{$name}{room} = 'SD_BELL' if ( not exists( $attr{$name}{room} ) ); # set room, if only undef --> new def - AssignIoPort($hash, $iodevice); + AssignIoPort($hash, $iodevice); } ################################### sub Set($$$@) { - my ( $hash, $name, @a ) = @_; - my $cmd = $a[0]; - my $ioname = $hash->{IODev}{NAME}; - my $model = AttrVal($name, "model", "unknown"); - my @split = split(" ", $hash->{DEF}); - my @splitCode = ""; # for doubleCode - my $protocol = $split[0]; - my $repeats = AttrVal($name,'repeats', '5'); - my $doubleCodeCheck; - my $ret = undef; + my ( $hash, $name, @a ) = @_; + my $cmd = $a[0]; + my $ioname = $hash->{IODev}{NAME}; + my $model = AttrVal($name, 'model', 'unknown'); + my @split = split(' ', $hash->{DEF}); + my @splitCode = ''; # for doubleCode + my $protocol = $split[0]; + my $repeats = AttrVal($name,'repeats', '5'); + my $doubleCodeCheck; + my $ret = undef; - if ($cmd eq "?") { - $ret .= "ring:noArg"; - $ret .= " Alarm:noArg" if ($protocol == 96); # only Grothe_Mistral_SE - } else { - if ($protocol == 96) {; # only Grothe_Mistral_SE - # set sduino434 raw SC;;R=5;;SR;;R=1;;P0=1500;;P1=-215;;D=01;;SM;;R=1;;C=215;;D=47104762003F;; - my $msg = "SC;;R="; - $msg .= $repeats; - $msg .= ";SR;R=1;P0=1500;P1=-215;D=01;SM;R=1;C=215;D=47"; - my $id = $split[1]; - $id = sprintf('%06X', hex(substr($id,0,6)) | 0x800000) if ($cmd eq "Alarm"); # set alarm bit - $msg .= $id; - my $checksum = sprintf('%02X', ((0x47 + hex(substr($id,0,2)) + hex(substr($id,2,2)) + hex(substr($id,4,2))) & 0xFF)); - $msg .= $checksum; - my $model = AttrVal($name,'model', 'Grothe_Mistral_SE_01'); - $msg .= "3F" if ($model eq "Grothe_Mistral_SE_03"); # only Grothe_Mistral_SE_03 - $msg .= ";"; - IOWrite($hash, 'raw', $msg); - Log3 $name, 4, "$ioname: $name $msg"; - } else { - my $rawDatasend = $split[1]; # hex value from def without protocol - if ($rawDatasend =~ /[0-9a-fA-F]_[0-9a-fA-F]/s) { # check doubleCode in def - $doubleCodeCheck = 1; - @splitCode = split("_", $rawDatasend); - $rawDatasend = $splitCode[0]; - } else { - $doubleCodeCheck = 0; - } + if ($cmd eq '?') { + $ret .= 'ring:noArg'; + $ret .= ' Alarm:noArg' if ($protocol == 96); # only Grothe_Mistral_SE + } else { + if ($protocol == 96) {; # only Grothe_Mistral_SE + # set sduino434 raw SC;;R=5;;SR;;R=1;;P0=1500;;P1=-215;;D=01;;SM;;R=1;;C=215;;D=47104762003F;; + my $msg = 'SC;;R='; + $msg .= $repeats; + $msg .= ';SR;R=1;P0=1500;P1=-215;D=01;SM;R=1;C=215;D=47'; + my $id = $split[1]; + $id = sprintf('%06X', hex(substr($id,0,6)) | 0x800000) if ($cmd eq 'Alarm'); # set alarm bit + $msg .= $id; + my $checksum = sprintf('%02X', ((0x47 + hex(substr($id,0,2)) + hex(substr($id,2,2)) + hex(substr($id,4,2))) & 0xFF)); + $msg .= $checksum; + my $model = AttrVal($name,'model', 'Grothe_Mistral_SE_01'); + $msg .= '3F' if ($model eq 'Grothe_Mistral_SE_03'); # only Grothe_Mistral_SE_03 + $msg .= ';'; + IOWrite($hash, 'raw', $msg); + Log3 $name, 4, "$ioname: $name $msg"; + } else { + my $rawDatasend = $split[1]; # hex value from def without protocol + if ($rawDatasend =~ /[0-9a-fA-F]_[0-9a-fA-F]/xms) { # check doubleCode in def + $doubleCodeCheck = 1; + @splitCode = split('_', $rawDatasend); + $rawDatasend = $splitCode[0]; + } else { + $doubleCodeCheck = 0; + } - Log3 $name, 4, "$ioname: SD_BELL_Set_doubleCodeCheck doubleCodeCheck=$doubleCodeCheck splitCode[0]=$rawDatasend"; - - my $hlen = length($rawDatasend); - my $blen = $hlen * 4; - my $bitData = unpack("B$blen", pack("H$hlen", $rawDatasend)); - my $msg = "P$protocol#" . $bitData; - - if ($model eq "Heidemann_|_Heidemann_HX_|_VTX-BELL") { - $msg .= "#R135"; - } else { - $msg .= "#R$repeats"; - } + Log3 $name, 4, "$ioname: SD_BELL_Set_doubleCodeCheck doubleCodeCheck=$doubleCodeCheck splitCode[0]=$rawDatasend"; - Log3 $name, 4, "$ioname: $name sendMsg=$msg"; - IOWrite($hash, 'sendMsg', $msg); - } - } - Log3 $name, 3, "$ioname: $name set $cmd" if ($cmd ne "?"); - readingsSingleUpdate($hash, "state" , $cmd, 1) if ($cmd ne "?"); - return $ret; + my $hlen = length($rawDatasend); + my $blen = $hlen * 4; + my $bitData = unpack("B$blen", pack("H$hlen", $rawDatasend)); + my $msg = "P$protocol#" . $bitData; + + if ($model eq 'Heidemann_|_Heidemann_HX_|_VTX-BELL') { + $msg .= '#R135'; + } else { + $msg .= "#R$repeats"; + } + + Log3 $name, 4, "$ioname: $name sendMsg=$msg"; + IOWrite($hash, 'sendMsg', $msg); + } + } + Log3 $name, 3, "$ioname: $name set $cmd" if ($cmd ne '?'); + readingsSingleUpdate($hash, 'state' , $cmd, 1) if ($cmd ne '?'); + return $ret; } ################################### sub Undef($$) { - my ($hash, $name) = @_; - delete($modules{SD_BELL}{defptr}{$hash->{DEF}}) if(defined($hash->{DEF}) && defined($modules{SD_BELL}{defptr}{$hash->{DEF}})); - delete($modules{SD_BELL}{defptr}{doubleCode}) if(defined($modules{SD_BELL}{defptr}{defptr}{doubleCode})); - delete($modules{SD_BELL}{defptr}{doubleCode_Time}) if(defined($modules{SD_BELL}{defptr}{defptr}{doubleCode_Time})); - return undef; + my ($hash, $name) = @_; + + if(defined($hash->{DEF}) && defined($modules{SD_BELL}{defptr}{$hash->{DEF}})) { + delete($modules{SD_BELL}{defptr}{$hash->{DEF}}); + } + + if(defined($modules{SD_BELL}{defptr}{defptr}{doubleCode})) { + delete($modules{SD_BELL}{defptr}{doubleCode}); + } + + if(defined($modules{SD_BELL}{defptr}{defptr}{doubleCode_Time})) { + delete($modules{SD_BELL}{defptr}{doubleCode_Time}); + } + + return; } ################################### sub Parse($$) { - my ($iohash, $msg) = @_; - my $ioname = $iohash->{NAME}; - my ($protocol,$rawData) = split("#",$msg); - $protocol=~ s/^[u|U|P](\d+)/$1/; # extract protocol ID, $1 = ID - my $hlen = length($rawData); - my $blen = $hlen * 4; - my $bitData = unpack("B$blen", pack("H$hlen", $rawData)); - my $doubleCode_known = "0"; # marker, RAWMSG known in defpr - my ($hash_name) = grep { $models{$_}{Protocol} eq $protocol } keys %models; # search protocol --> model - my $deviceCode = $rawData; - my $devicedef; - my $state = "ring"; - my $bat; + my ($iohash, $msg) = @_; + my $ioname = $iohash->{NAME}; + my ($protocol,$rawData) = split('#',$msg); + $protocol=~ s/^[u|U|P](\d+)/$1/; # extract protocol ID, $1 = ID + my $hlen = length($rawData); + my $blen = $hlen * 4; + my $bitData = unpack("B$blen", pack("H$hlen", $rawData)); + my $doubleCode_known = '0'; # marker, RAWMSG known in defpr + my ($hash_name) = grep { $models{$_}{Protocol} eq $protocol } keys %models; # search protocol --> model + my $deviceCode = $rawData; + my $devicedef; + my $state = 'ring'; + my $bat; - Log3 $iohash, 4, "$ioname: SD_BELL_Parse protocol $protocol $hash_name doubleCode=".$models{$hash_name}{doubleCode}." rawData=$rawData"; + Log3 $iohash, 4, "$ioname: SD_BELL_Parse protocol $protocol $hash_name doubleCode=".$models{$hash_name}{doubleCode}." rawData=$rawData"; - ## loop to view SD_BELL defined defptr ## - if ($protocol == 41) { - foreach my $d(sort keys %{$modules{SD_BELL}{defptr}}) { - Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol defptr - $d is defined!" if ($d =~ /$protocol/s); - if ($d =~ /$rawData/s) { - my @doubleCode = split(" ",$d); # split two RAWMSG from protocol in def 41 BA7983D3_3286D393 - $doubleCode_known = $doubleCode[1]; # RAWMSG are in split RAWMSG - Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol defptr - $rawData is already registered!" - } - } + ## loop to view SD_BELL defined defptr ## + if ($protocol == 41) { + foreach my $d(sort keys %{$modules{SD_BELL}{defptr}}) { + Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol defptr - $d is defined!" if ($d =~ /$protocol/xms); + if ($d =~ /$rawData/xms) { + my @doubleCode = split(' ',$d); # split two RAWMSG from protocol in def 41 BA7983D3_3286D393 + $doubleCode_known = $doubleCode[1]; # RAWMSG are in split RAWMSG + Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol defptr - $rawData is already registered!" + } + } - $modules{SD_BELL}{defptr}{doubleCode_Time} = 0 if (!exists $modules{SD_BELL}{defptr}{doubleCode_Time}); - Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - doubleCode_Time_old=".$modules{SD_BELL}{defptr}{doubleCode_Time}." Time_now=".time()." Diff=".(time()-$modules{SD_BELL}{defptr}{doubleCode_Time}); + $modules{SD_BELL}{defptr}{doubleCode_Time} = 0 if (!exists $modules{SD_BELL}{defptr}{doubleCode_Time}); + Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - doubleCode_Time_old=".$modules{SD_BELL}{defptr}{doubleCode_Time}.' Time_now='.time().' Diff='.(time()-$modules{SD_BELL}{defptr}{doubleCode_Time}); - if ((time() - $modules{SD_BELL}{defptr}{doubleCode_Time} > 15) && $doubleCode_known eq "0") { # max timediff 15 seconds - Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - pointer not exists!" if (not exists $modules{SD_BELL}{defptr}{doubleCode}); - Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - pointer ".$modules{SD_BELL}{defptr}{doubleCode}." deleted! RAWMSG too old!" if (exists $modules{SD_BELL}{defptr}{doubleCode}); - delete ($modules{SD_BELL}{defptr}{doubleCode}) if (exists $modules{SD_BELL}{defptr}{doubleCode}); - $modules{SD_BELL}{defptr}{doubleCode_Time} = time(); # set time for new RAWMSG - return ""; - } + if ((time() - $modules{SD_BELL}{defptr}{doubleCode_Time} > 15) && $doubleCode_known eq '0') { # max timediff 15 seconds + Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - pointer not exists!" if (not exists $modules{SD_BELL}{defptr}{doubleCode}); + Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - pointer ".$modules{SD_BELL}{defptr}{doubleCode}.' deleted! RAWMSG too old!' if (exists $modules{SD_BELL}{defptr}{doubleCode}); + delete ($modules{SD_BELL}{defptr}{doubleCode}) if (exists $modules{SD_BELL}{defptr}{doubleCode}); + $modules{SD_BELL}{defptr}{doubleCode_Time} = time(); # set time for new RAWMSG + return ''; + } - ### doubleCode yes and RAWMSG are unknown in def ### - if ($models{$hash_name}{doubleCode} eq "yes" && $doubleCode_known eq "0") { # !defs - Log3 $iohash, 3, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - doubleCode known $doubleCode_known in defptr. autocreate are not complete finish!"; + ### doubleCode yes and RAWMSG are unknown in def ### + if ($models{$hash_name}{doubleCode} eq 'yes' && $doubleCode_known eq '0') { # !defs + Log3 $iohash, 3, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - doubleCode known $doubleCode_known in defptr. autocreate are not complete finish!"; - if (exists $modules{SD_BELL}{defptr}{doubleCode}) { - Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - pointer data already exists!"; - } else { - $modules{SD_BELL}{defptr}{doubleCode} = $rawData."_doubleCode"; # first RAWMSG | reset marker, RAWMSG other - $modules{SD_BELL}{defptr}{doubleCode_Time} = time(); # set time from new RAWMSG - Log3 $iohash, 3, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - ".$modules{SD_BELL}{defptr}{doubleCode}." new defined!"; - return ""; - } + if (exists $modules{SD_BELL}{defptr}{doubleCode}) { + Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - pointer data already exists!"; + } else { + $modules{SD_BELL}{defptr}{doubleCode} = $rawData.'_doubleCode'; # first RAWMSG | reset marker, RAWMSG other + $modules{SD_BELL}{defptr}{doubleCode_Time} = time(); # set time from new RAWMSG + Log3 $iohash, 3, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - ".$modules{SD_BELL}{defptr}{doubleCode}.' new defined!'; + return ''; + } - if ($modules{SD_BELL}{defptr}{doubleCode} =~ /_doubleCode/s ) { # check of 2 RAWMSG - my @doubleCode = split("_",$modules{SD_BELL}{defptr}{doubleCode}); + if ($modules{SD_BELL}{defptr}{doubleCode} =~ /_doubleCode/s ) { # check of 2 RAWMSG + my @doubleCode = split('_',$modules{SD_BELL}{defptr}{doubleCode}); - # Codes - common ground unknown !! # - #################################### - # user RAWMSG - # 1791D593 BA2885D3 - # me RAMSG - # 754485D3 08E8D593 ?? - # 08E8D593 754485D3 ?? - # 3286D393 BA7983D3 - # BA7983D3 3286D393 + # Codes - common ground unknown !! # + #################################### + # user RAWMSG + # 1791D593 BA2885D3 + # me RAMSG + # 754485D3 08E8D593 ?? + # 08E8D593 754485D3 ?? + # 3286D393 BA7983D3 + # BA7983D3 3286D393 - # my $check_4 = 0; - # $check_4 = 1 if (abs(hex(substr($doubleCode[0],4,1)) - hex(substr($rawData,4,1))) == 5); - # my $check_5 = 0; - # $check_5 = 1 if (substr($doubleCode[0],5,1) eq substr($rawData,5,1)); - # my $check_6 = 0; - # $check_6 = 1 if (abs(hex(substr($doubleCode[0],6,1)) - hex(substr($rawData,6,1))) == 4); - # my $check_7 = 0; - # $check_7 = 1 if (substr($doubleCode[0],7,1) eq substr($rawData,7,1)); + # my $check_4 = 0; + # $check_4 = 1 if (abs(hex(substr($doubleCode[0],4,1)) - hex(substr($rawData,4,1))) == 5); + # my $check_5 = 0; + # $check_5 = 1 if (substr($doubleCode[0],5,1) eq substr($rawData,5,1)); + # my $check_6 = 0; + # $check_6 = 1 if (abs(hex(substr($doubleCode[0],6,1)) - hex(substr($rawData,6,1))) == 4); + # my $check_7 = 0; + # $check_7 = 1 if (substr($doubleCode[0],7,1) eq substr($rawData,7,1)); - # if ($check_4 != 1 || $check_5 != 1 || $check_6 != 1 || $check_7 != 1) { - # Log3 $iohash, 3, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - RAWMSG check failed ($check_4 $check_5 $check_6 $check_7)"; - # return ""; - # } + # if ($check_4 != 1 || $check_5 != 1 || $check_6 != 1 || $check_7 != 1) { + # Log3 $iohash, 3, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - RAWMSG check failed ($check_4 $check_5 $check_6 $check_7)"; + # return ''; + # } - ### messages are verified ### - if ($modules{SD_BELL}{defptr}{doubleCode} =~ /$rawData/s) { # check, part known - Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - $rawData is already known!"; - } else { # new part - $modules{SD_BELL}{defptr}{doubleCode} = $doubleCode[0]."_".$rawData; - Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - $rawData part two for defptr find!"; - } - Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - ".$modules{SD_BELL}{defptr}{doubleCode}." complete for defptr"; - $deviceCode = $modules{SD_BELL}{defptr}{doubleCode}; - $devicedef = $protocol . " " .$deviceCode; - } else { - if ($modules{SD_BELL}{defptr}{doubleCode} =~ /$rawData/s) { # check RAWMSG known - Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - $rawData already registered! The system search the second code."; - $deviceCode = $modules{SD_BELL}{defptr}{doubleCode}; - $devicedef = $protocol . " " .$deviceCode; - } else { - Log3 $iohash, 3, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - RAWMSG $rawData failed! Other MSG are registered!"; # Error detections, another bit - return ""; - } - } - ### doubleCode yes and RAWMSG are known in def ### - } elsif ($models{$hash_name}{doubleCode} eq "yes" && $doubleCode_known ne "0") { - $devicedef = $protocol . " " .$doubleCode_known; # variant two, RAWMSG in a different order - Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - $devicedef ready to define!"; # Error detections, another bit - } + ### messages are verified ### + if ($modules{SD_BELL}{defptr}{doubleCode} =~ /$rawData/xms) { # check, part known + Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - $rawData is already known!"; + } else { # new part + $modules{SD_BELL}{defptr}{doubleCode} = $doubleCode[0].'_'.$rawData; + Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - $rawData part two for defptr find!"; + } + Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - ".$modules{SD_BELL}{defptr}{doubleCode}.' complete for defptr'; + $deviceCode = $modules{SD_BELL}{defptr}{doubleCode}; + $devicedef = $protocol . ' ' .$deviceCode; + } else { + if ($modules{SD_BELL}{defptr}{doubleCode} =~ /$rawData/xms) { # check RAWMSG known + Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - $rawData already registered! The system search the second code."; + $deviceCode = $modules{SD_BELL}{defptr}{doubleCode}; + $devicedef = $protocol . ' ' .$deviceCode; + } else { + Log3 $iohash, 3, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - RAWMSG $rawData failed! Other MSG are registered!"; # Error detections, another bit + return ''; + } + } + ### doubleCode yes and RAWMSG are known in def ### + } elsif ($models{$hash_name}{doubleCode} eq 'yes' && $doubleCode_known ne '0') { + $devicedef = $protocol . ' ' .$doubleCode_known; # variant two, RAWMSG in a different order + Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol doubleCode - $devicedef ready to define!"; # Error detections, another bit + } - ### doubleCode no - P42 must be cut manually because message has no separator ### - } elsif ($protocol == 42) { - ## only for RAWMSG receive from device - if ($hlen > 7) { - $deviceCode = substr($deviceCode,0,7); - } - ## if RAWMSG send from nano, not cut - $devicedef = $protocol . " " .$deviceCode; - Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol - $rawData alone"; + ### doubleCode no - P42 must be cut manually because message has no separator ### + } elsif ($protocol == 42) { + ## only for RAWMSG receive from device + if ($hlen > 7) { + $deviceCode = substr($deviceCode,0,7); + } + ## if RAWMSG send from nano, not cut + $devicedef = $protocol . ' ' .$deviceCode; + Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol - $rawData alone"; - ### Grothe_Mistral_SE 01 or 03 length 10 or 12 nibble ### - } elsif ($protocol == 96) { - my $checksum = ((hex(substr($rawData,0,2)) + hex(substr($rawData,2,2)) + hex(substr($rawData,4,2)) + hex(substr($rawData,6,2))) & 0xFF); - if ($checksum != hex(substr($rawData,8,2))) { - Log3 $iohash, 3, "$ioname: SD_BELL_Parse Grothe_Mistral_SE $deviceCode - ERROR checksum $checksum"; - return ""; - } - $deviceCode = sprintf('%06X', hex(substr($rawData,2,6)) & 0x7FFFFF); # mask alarm bit - $devicedef = $protocol . " " .$deviceCode; - $state = "Alarm" if (substr($bitData,8,1) eq "1"); - $bat = substr($bitData,41,1) eq "0" ? "ok" : "low" if ($hlen == 12); # only Grothe_Mistral_SE_03 - Log3 $iohash, 4, "$ioname: SD_BELL_Parse Grothe_Mistral_SE P$protocol - $rawData"; + ### Grothe_Mistral_SE 01 or 03 length 10 or 12 nibble ### + } elsif ($protocol == 96) { + my $checksum = ((hex(substr($rawData,0,2)) + hex(substr($rawData,2,2)) + hex(substr($rawData,4,2)) + hex(substr($rawData,6,2))) & 0xFF); + if ($checksum != hex(substr($rawData,8,2))) { + Log3 $iohash, 3, "$ioname: SD_BELL_Parse Grothe_Mistral_SE $deviceCode - ERROR checksum $checksum"; + return ''; + } + $deviceCode = sprintf('%06X', hex(substr($rawData,2,6)) & 0x7FFFFF); # mask alarm bit + $devicedef = $protocol . ' ' .$deviceCode; + $state = 'Alarm' if (substr($bitData,8,1) eq '1'); + $bat = substr($bitData,41,1) eq '0' ? 'ok' : 'low' if ($hlen == 12); # only Grothe_Mistral_SE_03 + Log3 $iohash, 4, "$ioname: SD_BELL_Parse Grothe_Mistral_SE P$protocol - $rawData"; - ### doubleCode no without P41 ### - } else { - $devicedef = $protocol . " " .$deviceCode; - Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol - $rawData alone"; - } + ### doubleCode no without P41 ### + } else { + $devicedef = $protocol . ' ' .$deviceCode; + Log3 $iohash, 4, "$ioname: SD_BELL_Parse Check P$protocol - $rawData alone"; + } - my $def = $modules{SD_BELL}{defptr}{$devicedef}; - $modules{SD_BELL}{defptr}{ioname} = $ioname; + my $def = $modules{SD_BELL}{defptr}{$devicedef}; + $modules{SD_BELL}{defptr}{ioname} = $ioname; - if(!$def) { - Log3 $iohash, 1, "$ioname: SD_BELL_Parse UNDEFINED BELL detected, Protocol ".$protocol." code " . $deviceCode; - return "UNDEFINED SD_BELL_$deviceCode SD_BELL $protocol $deviceCode"; - } + if(!$def) { + Log3 $iohash, 1, "$ioname: SD_BELL_Parse UNDEFINED BELL detected, Protocol ".$protocol.' code ' . $deviceCode; + return "UNDEFINED SD_BELL_$deviceCode SD_BELL $protocol $deviceCode"; + } - my $hash = $def; - my $name = $hash->{NAME}; - $hash->{lastMSG} = $rawData; - $hash->{bitMSG} = $bitData; + my $hash = $def; + my $name = $hash->{NAME}; + $hash->{lastMSG} = $rawData; + $hash->{bitMSG} = $bitData; - ### Grothe_Mistral_SE 01 or 03 length 10 or 12 nibble (only by first message) ### - if ($protocol == 96 && $hash->{STATE} eq "???") { - $attr{$name}{model} = "Grothe_Mistral_SE_01" if ($hlen == 10); - $attr{$name}{model} = "Grothe_Mistral_SE_03" if ($hlen == 12); - } + ### Grothe_Mistral_SE 01 or 03 length 10 or 12 nibble (only by first message) ### + if ($protocol == 96 && $hash->{STATE} eq '???') { + $attr{$name}{model} = 'Grothe_Mistral_SE_01' if ($hlen == 10); + $attr{$name}{model} = 'Grothe_Mistral_SE_03' if ($hlen == 12); + } - my $model = AttrVal($name, "model", "unknown"); - Log3 $name, 4, "$ioname: SD_BELL_Parse $name model=$model state=$state ($rawData)"; + my $model = AttrVal($name, 'model', 'unknown'); + Log3 $name, 4, "$ioname: SD_BELL_Parse $name model=$model state=$state ($rawData)"; - readingsBeginUpdate($hash); - readingsBulkUpdate($hash, "state", $state); - readingsBulkUpdate($hash, "batteryState", $bat) if (defined($bat) && length($bat) > 0) ; - readingsEndUpdate($hash, 1); # Notify is done by Dispatch + readingsBeginUpdate($hash); + readingsBulkUpdate($hash, 'state', $state); + readingsBulkUpdate($hash, 'batteryState', $bat) if (defined($bat) && length($bat) > 0) ; + readingsEndUpdate($hash, 1); # Notify is done by Dispatch - return $name; + return $name; } ################################### sub Attr(@) { - my ($cmd, $name, $attrName, $attrValue) = @_; - my $hash = $defs{$name}; - my $typ = $hash->{TYPE}; - my $ioDev = InternalVal($name, "LASTInputDev", undef); - my $state; - my $oldmodel = AttrVal($name, "model", "unknown"); + my ($cmd, $name, $attrName, $attrValue) = @_; + my $hash = $defs{$name}; + my $typ = $hash->{TYPE}; + my $ioDev = InternalVal($name, 'LASTInputDev', undef); + my $state; + my $oldmodel = AttrVal($name, 'model', 'unknown'); - my @hex_lengh_def = split(" ", $defs{$name}->{DEF}); - my $hex_lengh = length($hex_lengh_def[1]); - my $check_ok = 0; - #Log3 $name, 3, "SD_BELL_Attr cmd=$cmd attrName=$attrName attrValue=$attrValue oldmodel=$oldmodel"; + my @hex_lengh_def = split(' ', $defs{$name}->{DEF}); + my $hex_lengh = length($hex_lengh_def[1]); + my $check_ok = 0; + #Log3 $name, 3, "SD_BELL_Attr cmd=$cmd attrName=$attrName attrValue=$attrValue oldmodel=$oldmodel"; - if ($cmd eq "set" && $attrName eq "model" && $attrValue ne $oldmodel) { ### set new attr - $check_ok = 1 if ($models{$attrValue}{hex_lengh} =~ /($hex_lengh)/); - return "SD_BELL: ERROR! You want to choose the $oldmodel model to $attrValue.\nPlease check your selection. Your HEX-Value in DEF with a length of " .$hex_lengh. " are not allowed on this model!" if ($check_ok != 1 && $hex_lengh != 0); - Log3 $name, 3, "SD_BELL_Attr $cmd $attrName to $attrValue from $oldmodel"; - } + if ($cmd eq 'set' && $attrName eq 'model' && $attrValue ne $oldmodel) { ### set new attr + $check_ok = 1 if ($models{$attrValue}{hex_lengh} =~ /($hex_lengh)/xms); + return "SD_BELL: ERROR! You want to choose the $oldmodel model to $attrValue.\nPlease check your selection. Your HEX-Value in DEF with a length of " .$hex_lengh. ' are not allowed on this model!' if ($check_ok != 1 && $hex_lengh != 0); + Log3 $name, 3, "SD_BELL_Attr $cmd $attrName to $attrValue from $oldmodel"; + } - if ($cmd eq "del" && $attrName eq "model") { ### delete readings - readingsSingleUpdate($hash, "state" , "Please define a model for the correct processing",1); - } + if ($cmd eq 'del' && $attrName eq 'model') { ### delete readings + readingsSingleUpdate($hash, 'state' , 'Please define a model for the correct processing',1); + } - return undef; + return; } 1; @@ -443,47 +456,47 @@ sub Attr(@) {

SD_BELL

    The module SD_BELL is a universal module of the SIGNALduino for different bells.

    - Currently, the following models are supported: -
      -
    • wireless doorbell TCM 234759 Tchibo [Protocol 15]
    • -
    • FreeTec PE-6946 [Protocol 32]
    • -
    • Elro (Smartwares) Doorbell DB200 / 16 melodies - unitec Modell:98156+98YK [Protocol 41]
    • -
    • Pollin 551227 [Protocol 42]
    • -
    • m-e doorbell fuer FG- and Basic-Serie [Protocol 57]
    • -
    • Heidemann | Heidemann HX | VTX-BELL_Funkklingel [Protocol 79]
    • -
    • Grothe Mistral SE 01.1 (40 bit), 03.1 (48 bit) [Protocol 96]
    • -
    • GEA-028DB [Protokoll 98]
    • -
      - Special feature Protocol 41, 2 different codes will be sent one after the other! -

    -
    + Currently, the following models are supported: +
      +
    • wireless doorbell TCM 234759 Tchibo [Protocol 15]
    • +
    • FreeTec PE-6946 [Protocol 32]
    • +
    • Elro (Smartwares) Doorbell DB200 / 16 melodies - unitec Modell:98156+98YK [Protocol 41]
    • +
    • Pollin 551227 [Protocol 42]
    • +
    • m-e doorbell fuer FG- and Basic-Serie [Protocol 57]
    • +
    • Heidemann | Heidemann HX | VTX-BELL_Funkklingel [Protocol 79]
    • +
    • Grothe Mistral SE 01.1 (40 bit), 03.1 (48 bit) [Protocol 96]
    • +
    • GEA-028DB [Protokoll 98]
    • +
      + Special feature Protocol 41, 2 different codes will be sent one after the other! +

    +
    - Define
    -
      define <NAME> SD_BELL <protocol> <hex-adresse>

      - Examples: -
        - define <NAME> SD_BELL 32 68C1DA
        - define <NAME> SD_BELL 41 754485D3_08E8D593
        - define <NAME> SD_BELL 79 A3C
        -

    + Define
    +
      define <NAME> SD_BELL <protocol> <hex-adresse>

      + Examples: +
        + define <NAME> SD_BELL 32 68C1DA
        + define <NAME> SD_BELL 41 754485D3_08E8D593
        + define <NAME> SD_BELL 79 A3C
        +

    - Set
    -
      ring

    - - Get
    -
      N/A

    - - Attribute
    - - - -
      -
    • model
      - The attribute indicates the model type of your device.
    -
    • repeats
      - This attribute can be used to adjust how many repetitions are sent. Default is 5.
      - (For the model Heidemann_|_Heidemann_HX_|_VTX-BELL, the value repeats is fixed at 135!)

    -
    + Set
    +
      ring

    + + Get
    +
      N/A

    + + Attribute
    + + + +
      +
    • model
      + The attribute indicates the model type of your device.
    +
    • repeats
      + This attribute can be used to adjust how many repetitions are sent. Default is 5.
      + (For the model Heidemann_|_Heidemann_HX_|_VTX-BELL, the value repeats is fixed at 135!)

    +
=end html =begin html_DE @@ -491,47 +504,47 @@ sub Attr(@) {

SD_BELL

    Das Modul SD_BELL ist ein Universalmodul vom SIGNALduino für verschiedene Klingeln.

    - Derzeit werden folgende Modelle untersützt: -
      -
    • wireless doorbell TCM 234759 Tchibo [Protokoll 15]
    • -
    • FreeTec PE-6946 [Protokoll 32]
    • -
    • Elro (Smartwares) Doorbell DB200 / 16 Melodien - unitec Modell:98156+98YK [Protokoll 41]
    • -
    • Pollin 551227 [Protokoll 42]
    • -
    • m-e doorbell für FG- und Basic-Serie [Protokoll 57]
    • -
    • Heidemann | Heidemann HX | VTX-BELL_Funkklingel [Protokoll 79]
    • -
    • Grothe Mistral SE 01.1 (40 bit), 03.1 (48 bit) [Protokoll 96]
    • -
    • GEA-028DB [Protokoll 98]
    • -
      - Besonderheit Protokoll 41, es sendet 2 verschiedene Codes nacheinader! -

    -
    + Derzeit werden folgende Modelle untersützt: +
      +
    • wireless doorbell TCM 234759 Tchibo [Protokoll 15]
    • +
    • FreeTec PE-6946 [Protokoll 32]
    • +
    • Elro (Smartwares) Doorbell DB200 / 16 Melodien - unitec Modell:98156+98YK [Protokoll 41]
    • +
    • Pollin 551227 [Protokoll 42]
    • +
    • m-e doorbell für FG- und Basic-Serie [Protokoll 57]
    • +
    • Heidemann | Heidemann HX | VTX-BELL_Funkklingel [Protokoll 79]
    • +
    • Grothe Mistral SE 01.1 (40 bit), 03.1 (48 bit) [Protokoll 96]
    • +
    • GEA-028DB [Protokoll 98]
    • +
      + Besonderheit Protokoll 41, es sendet 2 verschiedene Codes nacheinader! +

    +
    - Define
    -
      define <NAME> SD_BELL <Protokoll> <Hex-Adresse>

      - Beispiele: -
        - define <NAME> SD_BELL 32 68C1DA
        - define <NAME> SD_BELL 41 754485D3_08E8D593
        - define <NAME> SD_BELL 79 A3C
        -

    + Define
    +
      define <NAME> SD_BELL <Protokoll> <Hex-Adresse>

      + Beispiele: +
        + define <NAME> SD_BELL 32 68C1DA
        + define <NAME> SD_BELL 41 754485D3_08E8D593
        + define <NAME> SD_BELL 79 A3C
        +

    - Set
    -
      ring

    - - Get
    -
      N/A

    - - Attribute
    - - - -
      -
    • model
      - Das Attribut bezeichnet den Modelltyp Ihres Gerätes.
    -
    • repeats
      - Mit diesem Attribut kann angepasst werden, wie viele Wiederholungen gesendet werden. Standard ist 5.
      - (Bei dem Model Heidemann_|_Heidemann_HX_|_VTX-BELL ist der Wert repeats fest auf 135 gesetzt unabhäning vom eingestellten Attribut!)

    -
    + Set
    +
      ring

    + + Get
    +
      N/A

    + + Attribute
    + + + +
      +
    • model
      + Das Attribut bezeichnet den Modelltyp Ihres Gerätes.
    +
    • repeats
      + Mit diesem Attribut kann angepasst werden, wie viele Wiederholungen gesendet werden. Standard ist 5.
      + (Bei dem Model Heidemann_|_Heidemann_HX_|_VTX-BELL ist der Wert repeats fest auf 135 gesetzt unabhäning vom eingestellten Attribut!)

    +
=end html_DE =cut