diff --git a/CHANGED b/CHANGED index 4eb2636e3..e48f554aa 100644 --- a/CHANGED +++ b/CHANGED @@ -1,5 +1,7 @@ 20.05.2019 00_SIGNALduino.pm: added check method for no break and fix PEARL WARNING +18.05.2019 + SD_ProtocolData.pm: added ID 96 Grothe Mistral 15.05.2019 00_SIGNALduino.pm: Drop-down list for cc1101_bWidth, cc1101_rAmpl and cc1101_sens 14.05.2019 diff --git a/FHEM/00_SIGNALduino.pm b/FHEM/00_SIGNALduino.pm index 10c286ff4..cd8ea450d 100644 --- a/FHEM/00_SIGNALduino.pm +++ b/FHEM/00_SIGNALduino.pm @@ -39,7 +39,7 @@ use constant { SDUINO_KEEPALIVE_MAXRETRY => 3, SDUINO_WRITEQUEUE_NEXT => 0.3, SDUINO_WRITEQUEUE_TIMEOUT => 2, - + SDUINO_DISPATCH_VERBOSE => 5, # default 5 SDUINO_MC_DISPATCH_VERBOSE => 5, # wenn kleiner 5, z.B. 3 dann wird vor dem dispatch mit loglevel 3 die ID und rmsg ausgegeben SDUINO_MC_DISPATCH_LOG_ID => '12.1', # die o.g. Ausgabe erfolgt nur wenn der Wert mit der ID uebereinstimmt @@ -155,7 +155,7 @@ my $clientsSIGNALduino = ":IT:" ."Fernotron:" ."SD_Keeloq:" ."SIGNALduino_un:" - ; + ; ## default regex match List for dispatching message to logical modules, can be updated during runtime because it is referenced my %matchListSIGNALduino = ( @@ -181,8 +181,8 @@ my %matchListSIGNALduino = ( "21:FS10" => '^P61#[A-F0-9]+', "22:Siro" => '^P72#[A-Fa-f0-9]+', "23:FHT" => "^81..(04|09|0d)..(0909a001|83098301|c409c401)..", - "24:FS20" => "^81..(04|0c)..0101a001", - "25:CUL_EM" => "^E0.................", + "24:FS20" => "^81..(04|0c)..0101a001", + "25:CUL_EM" => "^E0.................", "26:Fernotron" => '^P82#.*', "27:SD_BELL" => '^P(?:15|32|41|42|57|79)#.*', "28:SD_Keeloq" => '^P(?:87|88)#.*', @@ -220,7 +220,7 @@ SIGNALduino_Initialize($) $hash->{GetFn} = "SIGNALduino_Get"; $hash->{SetFn} = "SIGNALduino_Set"; $hash->{AttrFn} = "SIGNALduino_Attr"; - $hash->{AttrList} = + $hash->{AttrList} = "Clients MatchList do_not_notify:1,0 dummy:1,0" ." hexFile" ." initCommands" @@ -247,14 +247,14 @@ SIGNALduino_Initialize($) $hash->{ShutdownFn} = "SIGNALduino_Shutdown"; $hash->{FW_detailFn} = "SIGNALduino_FW_Detail"; $hash->{FW_deviceOverview} = 1; - + $hash->{msIdList} = (); $hash->{muIdList} = (); $hash->{mcIdList} = (); - + #our $attr; - + %ProtocolListSIGNALduino = SIGNALduino_LoadProtocolHash("$attr{global}{modpath}/FHEM/lib/SD_ProtocolData.pm"); if (exists($ProtocolListSIGNALduino{error}) ) { Log3 "SIGNALduino", 1, "Error loading Protocol Hash. Module is in inoperable mode error message:($ProtocolListSIGNALduino{error})"; @@ -266,7 +266,7 @@ SIGNALduino_Initialize($) # Predeclare Variables from other modules may be loaded later from fhem # our $FW_wname; -our $FW_ME; +our $FW_ME; # # Predeclare Variables from other modules may be loaded later from fhem @@ -278,9 +278,9 @@ our $FW_detail; # First Parameter is for filename (full or relativ path) to be loaded # # returns a hash with protocols if loaded without error. Returns a hash with {eror} => errormessage if there was an error - + sub SIGNALduino_LoadProtocolHash($) -{ +{ my $ret= lib::SD_Protocols::LoadHash($_[0]); return %$ret; } @@ -310,50 +310,50 @@ SIGNALduino_Define($$) Log3 undef, 2, $msg; return $msg; } - + DevIo_CloseDev($hash); my $name = $a[0]; - + if (!exists &round) { Log3 $name, 1, "$name: Signalduino can't be activated (sub round not found). Please update Fhem via update command"; return undef; } - + my $dev = $a[2]; #Debug "dev: $dev" if ($debug); #my $hardware=AttrVal($name,"hardware","nano"); #Debug "hardware: $hardware" if ($debug); - - + + if($dev eq "none") { Log3 $name, 1, "$name: device is none, commands will be echoed only"; $attr{$name}{dummy} = 1; #return undef; } - + if ($dev ne "none" && $dev =~ m/[a-zA-Z]/ && $dev !~ m/\@/) { # bei einer IP wird kein \@57600 angehaengt $dev .= "\@57600"; - } - + } + #$hash->{CMDS} = ""; $hash->{Clients} = $clientsSIGNALduino; $hash->{MatchList} = \%matchListSIGNALduino; $hash->{DeviceName} = $dev; - + my $ret=undef; - + InternalTimer(gettimeofday(), 'SIGNALduino_IdList',"sduino_IdList:$name",0); # verzoegern bis alle Attribute eingelesen sind - + if($dev ne "none") { $ret = DevIo_OpenDev($hash, 0, "SIGNALduino_DoInit", 'SIGNALduino_Connect'); } else { $hash->{DevState} = 'initialized'; readingsSingleUpdate($hash, "state", "opened", 1); } - + $hash->{DMSG}="nothing"; $hash->{LASTDMSG} = "nothing"; $hash->{LASTDMSGID} = "nothing"; @@ -388,9 +388,9 @@ SIGNALduino_Undef($$) { my ($hash, $arg) = @_; my $name = $hash->{NAME}; - - - + + + foreach my $d (sort keys %defs) { if(defined($defs{$d}) && @@ -404,9 +404,9 @@ SIGNALduino_Undef($$) } SIGNALduino_Shutdown($hash); - - DevIo_CloseDev($hash); - RemoveInternalTimer($hash); + + DevIo_CloseDev($hash); + RemoveInternalTimer($hash); return undef; } @@ -427,7 +427,7 @@ sub SIGNALduino_Set($@) { my ($hash, @a) = @_; - + return "\"set SIGNALduino\" needs at least one parameter" if(@a < 2); #SIGNALduino_Log3 $hash, 3, "SIGNALduino_Set called with params @a"; @@ -449,9 +449,9 @@ SIGNALduino_Set($@) #SIGNALduino_Log3 $hash, 3, "SIGNALduino_Set global set commands: ".Dumper(%sets); %my_sets = ( %my_sets, %{$hash->{additionalSets}} ) if ( defined($hash->{additionalSets}) ); - - - + + + if (!defined($my_sets{$a[1]})) { my $arguments = ' '; foreach my $arg (sort keys %my_sets) { @@ -468,17 +468,17 @@ SIGNALduino_Set($@) my $name = shift @a; my $cmd = shift @a; my $arg = join(" ", @a); - + if ($cmd =~ m/cc1101/ && $hasCC1101 == 0) { return "This command is only available with a cc1101 receiver"; } - + return "$name is not active, may firmware is not suppoted, please flash or reset" if ($cmd ne 'reset' && $cmd ne 'flash' && exists($hash->{DevState}) && $hash->{DevState} ne 'initialized'); if ($cmd =~ m/^cc1101_/) { $cmd = substr($cmd,7); } - + if($cmd eq "raw") { SIGNALduino_Log3 $name, 4, "set $name $cmd $arg"; #SIGNALduino_SimpleWrite($hash, $arg); @@ -495,12 +495,12 @@ SIGNALduino_Set($@) my $logFile = AttrVal("global", "logdir", "./log/") . "$hash->{TYPE}-Flash.log"; return "Please define your hardware! (attr $name hardware ) " if ($hardware eq ""); return "ERROR: argument failed! flash [hexFile|url]" if (!$args[0]); - - - + + + #SIGNALduino_Log3 $hash, 3, "SIGNALduino_Set choosen flash option: $args[0] of available: ".Dumper($my_sets{flash}); - + if( grep $args[0] eq $_ , split(",",$my_sets{flash}) ) { SIGNALduino_Log3 $hash, 3, "SIGNALduino_Set flash $args[0] try to fetch github assets for tag $args[0]"; @@ -509,10 +509,10 @@ SIGNALduino_Set($@) if ($hardware =~ /ESP/) { $ghurl =~ s//SIGNALESP/ ; } else { - $ghurl =~ s//SIGNALDuino/ ; + $ghurl =~ s//SIGNALDuino/ ; } SIGNALduino_Log3 $hash, 3, "SIGNALduino_Set flash $args[0] try to fetch release $ghurl"; - + my $http_param = { url => $ghurl, timeout => 5, @@ -521,11 +521,11 @@ SIGNALduino_Set($@) header => "User-Agent: perl_fhem\r\nAccept: application/json", # Den Header gemaess abzufragender Daten aendern callback => \&SIGNALduino_githubParseHttpResponse, # Diese Funktion soll das Ergebnis dieser HTTP Anfrage bearbeiten command => "getReleaseByTag" - + }; - HttpUtils_NonblockingGet($http_param); # Starten der HTTP Abfrage. Es gibt keinen Return-Code. + HttpUtils_NonblockingGet($http_param); # Starten der HTTP Abfrage. Es gibt keinen Return-Code. return; - } + } elsif(!$arg || $args[0] !~ m/^(\w|\/|.)+$/) { $hexFile = AttrVal($name, "hexFile", ""); if ($hexFile eq "") { @@ -541,9 +541,9 @@ SIGNALduino_Set($@) callback => \&SIGNALduino_ParseHttpResponse, # Diese Funktion soll das Ergebnis dieser HTTP Anfrage bearbeiten command => 'flash', }; - - HttpUtils_NonblockingGet($http_param); - return; + + HttpUtils_NonblockingGet($http_param); + return; } else { $hexFile = $args[0]; } @@ -553,9 +553,9 @@ SIGNALduino_Set($@) # Only for Arduino , not for ESP if ($hardware =~ m/(?:nano|mini|radino)/) { - + my $avrdudefound=0; - my $tool_name = "avrdude"; + my $tool_name = "avrdude"; for my $path ( split /:/, $ENV{PATH} ) { if ( -f "$path/$tool_name" && -x _ ) { $avrdudefound=1; @@ -569,7 +569,7 @@ SIGNALduino_Set($@) $log .= "hex file: $hexFile\n"; $log .= "port: $port\n"; $log .= "log file: $logFile\n"; - + my $flashCommand; if( !defined( $attr{$name}{flashCommand} ) ) { # check defined flashCommand from user | not, use standard flashCommand | yes, use user flashCommand SIGNALduino_Log3 $name, 5, "$hash->{TYPE} $name: flashCommand is not defined. standard used to flash."; @@ -582,26 +582,26 @@ SIGNALduino_Set($@) $flashCommand = $attr{$name}{flashCommand}; SIGNALduino_Log3 $name, 3, "$hash->{TYPE} $name: flashCommand is manual defined! $flashCommand"; } - - + + if($flashCommand ne "") { if (-e $logFile) { unlink $logFile; } - + DevIo_CloseDev($hash); $hash->{STATE} = "FIRMWARE UPDATE running"; $log .= "$name closed\n"; - + my $avrdude = $flashCommand; $avrdude =~ s/\Q[PORT]\E/$port/g; $avrdude =~ s/\Q[BAUDRATE]\E/$baudrate/g; $avrdude =~ s/\Q[HEXFILE]\E/$hexFile/g; $avrdude =~ s/\Q[LOGFILE]\E/$logFile/g; - + $log .= "command: $avrdude\n\n"; `$avrdude`; - + local $/=undef; if (-e $logFile) { open FILE, $logFile; @@ -614,21 +614,21 @@ SIGNALduino_Set($@) else { $log .= "WARNING: avrdude created no log file\n\n"; } - + } else { $log .= "\n\nNo flashCommand found. Please define this attribute.\n\n"; } - + DevIo_OpenDev($hash, 0, "SIGNALduino_DoInit", 'SIGNALduino_Connect'); $log .= "$name opened\n"; - + return undef; } else { return "Sorry, Flashing your ESP via Module is currently not supported."; } - + } elsif ($cmd =~ m/reset/i) { delete($hash->{initResetFlag}) if defined($hash->{initResetFlag}); return SIGNALduino_ResetDevice($hash); @@ -689,7 +689,7 @@ SIGNALduino_Set($@) SIGNALduino_WriteInit($hash); } elsif( $cmd eq "sendMsg" ) { SIGNALduino_Log3 $name, 5, "$name: sendmsg msg=$arg"; - + # Split args in serval variables my ($protocol,$data,$repeats,$clock,$frequency,$datalength,$dataishex); my $n=0; @@ -701,7 +701,7 @@ SIGNALduino_Set($@) $data = $s; if ( substr($s,0,2) eq "0x" ) { $dataishex=1; $data=substr($data,2); } else { $dataishex=0; } - + } else { if ($c eq 'R') { $repeats = substr($s,1); } elsif ($c eq 'C') { $clock = substr($s,1); } @@ -722,30 +722,30 @@ SIGNALduino_Set($@) } else { $frequency=""; } - + #print ("data = $data \n"); #print ("protocol = $protocol \n"); #print ("repeats = $repeats \n"); - + my %signalHash; my %patternHash; my $pattern=""; my $cnt=0; - + my $sendData; if (exists($ProtocolListSIGNALduino{$protocol}{format}) && $ProtocolListSIGNALduino{$protocol}{format} eq 'manchester') { #$clock = (map { $clock += $_ } @{$ProtocolListSIGNALduino{$protocol}{clockrange}}) / 2 if (!defined($clock)); - + $clock += $_ for(@{$ProtocolListSIGNALduino{$protocol}{clockrange}}); $clock = round($clock/2,0); if ($protocol == 43) { #$data =~ tr/0123456789ABCDEF/FEDCBA9876543210/; } - + my $intro = ""; my $outro = ""; - + $intro = $ProtocolListSIGNALduino{$protocol}{msgIntro} if ($ProtocolListSIGNALduino{$protocol}{msgIntro}); $outro = $ProtocolListSIGNALduino{$protocol}{msgOutro}.";" if ($ProtocolListSIGNALduino{$protocol}{msgOutro}); @@ -770,8 +770,8 @@ SIGNALduino_Set($@) $hash->{ITClock} = 250 if (!defined($hash->{ITClock})); # Todo: Klaeren wo ITClock verwendet wird und ob wir diesen Teil nicht auf Protokoll 3,4 und 17 minimieren $clock=$ProtocolListSIGNALduino{$protocol}{clockabs} > 1 ?$ProtocolListSIGNALduino{$protocol}{clockabs}:$hash->{ITClock}; } - - if ($dataishex == 1) + + if ($dataishex == 1) { # convert hex to bits my $hlen = length($data); @@ -780,16 +780,16 @@ SIGNALduino_Set($@) } SIGNALduino_Log3 $name, 5, "$name: sendmsg Preparing rawsend command for protocol=$protocol, repeats=$repeats, clock=$clock bits=$data"; - + foreach my $item (qw(preSync sync start one zero float pause end universal)) { #print ("item= $item \n"); next if (!exists($ProtocolListSIGNALduino{$protocol}{$item})); - + foreach my $p (@{$ProtocolListSIGNALduino{$protocol}{$item}}) { #print (" p = $p \n"); - + if (!exists($patternHash{$p})) { $patternHash{$p}=$cnt; @@ -801,10 +801,10 @@ SIGNALduino_Set($@) } } my @bits = split("", $data); - + my %bitconv = (1=>"one", 0=>"zero", 'D'=> "float", 'F'=> "float", 'P'=> "pause", 'U'=> "universal"); my $SignalData="D="; - + $SignalData.=$signalHash{preSync} if (exists($signalHash{preSync})); $SignalData.=$signalHash{sync} if (exists($signalHash{sync})); $SignalData.=$signalHash{start} if (exists($signalHash{start})); @@ -818,7 +818,7 @@ SIGNALduino_Set($@) $sendData = "SR;R=$repeats;$pattern$SignalData;$frequency"; } - + #SIGNALduino_SimpleWrite($hash, $sendData); SIGNALduino_AddSendQueue($hash,$sendData); SIGNALduino_Log3 $name, 4, "$name/set: sending via SendMsg: $sendData"; @@ -840,7 +840,7 @@ SIGNALduino_Get($@) my $name = $hash->{NAME}; return "$name is not active, may firmware is not suppoted, please flash or reset" if (exists($hash->{DevState}) && $hash->{DevState} ne 'initialized'); #my $name = $a[0]; - + SIGNALduino_Log3 $name, 5, "\"get $type\" needs at least one parameter" if(@a < 2); return "\"get $type\" needs at least one parameter" if(@a < 2); if(!defined($gets{$a[1]})) { @@ -850,48 +850,48 @@ SIGNALduino_Get($@) my $arg = ($a[2] ? $a[2] : ""); return "no command to send, get aborted." if (length($gets{$a[1]}[0]) == 0 && length($arg) == 0); - + if (($a[1] eq "ccconf" || $a[1] eq "ccreg" || $a[1] eq "ccpatable") && $hash->{version} && $hash->{version} !~ m/cc1101/) { return "This command is only available with a cc1101 receiver"; } - + my ($msg, $err); if ($a[1] eq "availableFirmware") { - + if ($missingModulSIGNALduino =~ m/JSON/ ) { SIGNALduino_Log3 $name, 1, "$name: get $a[1] failed. Pleas install Perl module JSON. Example: sudo apt-get install libjson-perl"; return "$a[1]: \n\nFetching from github is not possible. Please install JSON. Example:
sudo apt-get install libjson-perl"; - } - + } + my $channel=AttrVal($name,"updateChannelFW","stable"); my $hardware=AttrVal($name,"hardware",undef); - - my ($validHw) = $modules{$hash->{TYPE}}{AttrList} =~ /.*hardware:(.*?)\s/; + + my ($validHw) = $modules{$hash->{TYPE}}{AttrList} =~ /.*hardware:(.*?)\s/; SIGNALduino_Log3 $name, 1, "$name: $validHw"; - + if (!defined($hardware) || $validHw !~ /$hardware(?:,|$)/ ) { SIGNALduino_Log3 $name, 1, "$name: get $a[1] failed. Please set attribute hardware first"; return "$a[1]: \n\n$name: get $a[1] failed. Please choose one of $validHw attribute hardware"; - } - + } + SIGNALduino_querygithubreleases($hash); - + return "$a[1]: \n\nFetching $channel firmware versions for $hardware from github\n"; - + } - + if (IsDummy($name) && $a[1] ne "protocolIDs") { if ($arg =~ /^M[CcSU];.*/) { $arg="\002$arg\003"; ## Add start end end marker if not already there SIGNALduino_Log3 $name, 5, "$name/msg adding start and endmarker to message"; - + } if ($arg =~ /\002M.;.*;\003$/) { @@ -933,7 +933,7 @@ SIGNALduino_Get($@) } elsif ($arg eq '?') { my $ret; - + $ret = "dummy get raw\n\n"; $ret .= "raw message e.g. MS;P0=-392;P1=...\n"; $ret .= "dispatch message e.g. P7#6290DCF37\n"; @@ -960,26 +960,26 @@ SIGNALduino_Get($@) { # Arctec protocol SIGNALduino_Log3 $name, 5, "$name: calling set :sendmsg P17;R6#".substr($arg,2); - + SIGNALduino_Set($hash,$name,"sendMsg","P17#",substr($arg,2),"#R6"); return "$a[0] $a[1] => $arg"; } - + } elsif ($a[1] eq "protocolIDs") { return SIGNALduino_FW_getProtocolList($name); - - + + #return "$a[1]: \n\n$ret\nIds with modules: $moduleId"; - } + } #SIGNALduino_SimpleWrite($hash, $gets{$a[1]}[0] . $arg); SIGNALduino_AddSendQueue($hash, $gets{$a[1]}[0] . $arg); $hash->{getcmd}->{cmd}=$a[1]; $hash->{getcmd}->{asyncOut}=$hash->{CL}; $hash->{getcmd}->{timenow}=time(); - + return undef; # We will exit here, and give an output only, if asny output is supported. If this is not supported, only the readings are updated } @@ -990,15 +990,15 @@ sub SIGNALduino_parseResponse($$$) my $msg = shift; my $name=$hash->{NAME}; - + $msg =~ s/[\r\n]//g; - if($cmd eq "cmds") + if($cmd eq "cmds") { # nice it up $msg =~ s/$name cmds =>//g; $msg =~ s/.*Use one of//g; - } - elsif($cmd eq "uptime") + } + elsif($cmd eq "uptime") { # decode it #$msg = hex($msg); # /125; only for col or coc $msg = sprintf("%d %02d:%02d:%02d", $msg/86400, ($msg%86400)/3600, ($msg%3600)/60, $msg%60); @@ -1030,7 +1030,7 @@ sub SIGNALduino_parseResponse($$$) my $val = hex(substr($msg,6)); my $arg = $hash->{getcmd}->{arg}; my $ob = $val & 0x0f; - + my ($bits, $bw) = (0,0); OUTERLOOP: for (my $e = 0; $e < 4; $e++) { @@ -1068,7 +1068,7 @@ sub SIGNALduino_parseResponse($$$) # $msg .= "$patable{$CC1101Frequency}{$dB} $dB\n"; # } } - + return $msg; } @@ -1080,7 +1080,7 @@ SIGNALduino_ResetDevice($) my ($hash) = @_; my $name = $hash->{NAME}; - SIGNALduino_Log3 $hash, 3, "$name reset"; + SIGNALduino_Log3 $hash, 3, "$name reset"; DevIo_CloseDev($hash); my $ret = DevIo_OpenDev($hash, 0, "SIGNALduino_DoInit", 'SIGNALduino_Connect'); @@ -1094,11 +1094,11 @@ SIGNALduino_CloseDevice($) my ($hash) = @_; my $name = $hash->{NAME}; - SIGNALduino_Log3 $hash, 2, "$name closed"; + SIGNALduino_Log3 $hash, 2, "$name closed"; RemoveInternalTimer($hash); DevIo_CloseDev($hash); readingsSingleUpdate($hash, "state", "closed", 1); - + return undef; } @@ -1114,34 +1114,34 @@ SIGNALduino_DoInit($) my ($ver, $try) = ("", 0); #Dirty hack to allow initialisation of DirectIO Device for some debugging and tesing SIGNALduino_Log3 $hash, 1, "$name/define: ".$hash->{DEF}; - + delete($hash->{disConnFlag}) if defined($hash->{disConnFlag}); - + RemoveInternalTimer("HandleWriteQueue:$name"); @{$hash->{QUEUE}} = (); $hash->{sendworking} = 0; - + if (($hash->{DEF} !~ m/\@directio/) and ($hash->{DEF} !~ m/none/) ) { SIGNALduino_Log3 $hash, 1, "$name/init: ".$hash->{DEF}; $hash->{initretry} = 0; RemoveInternalTimer($hash); - + #SIGNALduino_SimpleWrite($hash, "XQ"); # Disable receiver InternalTimer(gettimeofday() + SDUINO_INIT_WAIT_XQ, "SIGNALduino_SimpleWrite_XQ", $hash, 0); - + InternalTimer(gettimeofday() + SDUINO_INIT_WAIT, "SIGNALduino_StartInit", $hash, 0); } # Reset the counter delete($hash->{XMIT_TIME}); delete($hash->{NR_CMD_LAST_H}); - - - - - - + + + + + + return; return undef; } @@ -1152,7 +1152,7 @@ SIGNALduino_DoInit($) sub SIGNALduino_SimpleWrite_XQ($) { my ($hash) = @_; my $name = $hash->{NAME}; - + SIGNALduino_Log3 $hash, 3, "$name/init: disable receiver (XQ)"; SIGNALduino_SimpleWrite($hash, "XQ"); #DevIo_SimpleWrite($hash, "XQ\n",2); @@ -1164,7 +1164,7 @@ sub SIGNALduino_StartInit($) my ($hash) = @_; my $name = $hash->{NAME}; $hash->{version} = undef; - + SIGNALduino_Log3 $name,3 , "$name/init: get version, retry = " . $hash->{initretry}; if ($hash->{initretry} >= SDUINO_INIT_MAXRETRY) { $hash->{DevState} = 'INACTIVE'; @@ -1197,7 +1197,7 @@ sub SIGNALduino_CheckCmdResp($) my $name = $hash->{NAME}; my $msg = undef; my $ver; - + if ($hash->{version}) { $ver = $hash->{version}; if ($ver !~ m/SIGNAL(duino|ESP)/) { @@ -1247,8 +1247,8 @@ sub SIGNALduino_XmitLimitCheck($$) { my ($hash,$fn) = @_; - - + + return if ($fn !~ m/^(is|SR).*/); my $now = time(); @@ -1300,7 +1300,7 @@ SIGNALduino_Write($$$) $msg = SIGNALduino_PreparingSend_FS20_FHT(73, 12, $msg); } SIGNALduino_Log3 $name, 5, "$name/write: sending via Set $fn $msg"; - + SIGNALduino_Set($hash,$name,$fn,$msg); } @@ -1309,11 +1309,11 @@ sub SIGNALduino_AddSendQueue($$) { my ($hash, $msg) = @_; my $name = $hash->{NAME}; - + push(@{$hash->{QUEUE}}, $msg); - + #SIGNALduino_Log3 $hash , 5, Dumper($hash->{QUEUE}); - + SIGNALduino_Log3 $hash, 5,"AddSendQueue: " . $hash->{NAME} . ": $msg (" . @{$hash->{QUEUE}} . ")"; InternalTimer(gettimeofday() + 0.1, "SIGNALduino_HandleWriteQueue", "HandleWriteQueue:$name") if (@{$hash->{QUEUE}} == 1 && $hash->{sendworking} == 0); } @@ -1324,7 +1324,7 @@ SIGNALduino_SendFromQueue($$) { my ($hash, $msg) = @_; my $name = $hash->{NAME}; - + if($msg ne "") { SIGNALduino_XmitLimitCheck($hash,$msg); #DevIo_SimpleWrite($hash, $msg . "\n", 2); @@ -1333,7 +1333,7 @@ SIGNALduino_SendFromQueue($$) if ($msg =~ m/^S(R|C|M);/) { $hash->{getcmd}->{cmd} = 'sendraw'; SIGNALduino_Log3 $hash, 4, "$name SendrawFromQueue: msg=$msg"; # zu testen der Queue, kann wenn es funktioniert auskommentiert werden - } + } elsif ($msg eq "C99") { $hash->{getcmd}->{cmd} = 'ccregAll'; } @@ -1342,7 +1342,7 @@ SIGNALduino_SendFromQueue($$) ############## # Write the next buffer not earlier than 0.23 seconds # else it will be sent too early by the SIGNALduino, resulting in a collision, or may the last command is not finished - + if (defined($hash->{getcmd}->{cmd}) && $hash->{getcmd}->{cmd} eq 'sendraw') { InternalTimer(gettimeofday() + SDUINO_WRITEQUEUE_TIMEOUT, "SIGNALduino_HandleWriteQueue", "HandleWriteQueue:$name"); } else { @@ -1357,16 +1357,16 @@ SIGNALduino_HandleWriteQueue($) my($param) = @_; my(undef,$name) = split(':', $param); my $hash = $defs{$name}; - + #my @arr = @{$hash->{QUEUE}}; - + $hash->{sendworking} = 0; # es wurde gesendet - + if (defined($hash->{getcmd}->{cmd}) && $hash->{getcmd}->{cmd} eq 'sendraw') { SIGNALduino_Log3 $name, 4, "$name/HandleWriteQueue: sendraw no answer (timeout)"; delete($hash->{getcmd}); } - + if(@{$hash->{QUEUE}}) { my $msg= shift(@{$hash->{QUEUE}}); @@ -1394,14 +1394,14 @@ SIGNALduino_Read($) my $debug = AttrVal($name,"debug",0); my $SIGNALduinodata = $hash->{PARTIAL}; - SIGNALduino_Log3 $name, 5, "$name/RAW READ: $SIGNALduinodata/$buf" if ($debug); + SIGNALduino_Log3 $name, 5, "$name/RAW READ: $SIGNALduinodata/$buf" if ($debug); $SIGNALduinodata .= $buf; while($SIGNALduinodata =~ m/\n/) { my $rmsg; ($rmsg,$SIGNALduinodata) = split("\n", $SIGNALduinodata, 2); $rmsg =~ s/\r//; - + if ($rmsg =~ m/^\002(M(s|u|o);.*;)\003/) { $rmsg =~ s/^\002//; # \002 am Anfang entfernen my @msg_parts = split(";",$rmsg); @@ -1412,8 +1412,8 @@ SIGNALduino_Read($) my $mH; my $part = ""; my $partD; - SIGNALduino_Log3 $name, 5, "$name/RAW rmsg: $rmsg"; - + SIGNALduino_Log3 $name, 5, "$name/RAW rmsg: $rmsg"; + foreach my $msgPart (@msg_parts) { next if ($msgPart eq ""); $m0 = substr($msgPart,0,1); @@ -1460,7 +1460,7 @@ SIGNALduino_Read($) elsif ($m0 eq "o" || $m0 eq "m") { $part .= "$m0$m1;"; } - elsif ($m1 =~ m/^[0-9A-Z]{1,2}$/) { # bei 1 oder 2 Hex Ziffern nach Dez wandeln + elsif ($m1 =~ m/^[0-9A-Z]{1,2}$/) { # bei 1 oder 2 Hex Ziffern nach Dez wandeln $part .= "$m0=" . hex($m1) . ";"; } elsif ($m0 =~m/[0-9a-zA-Z]/) { @@ -1499,7 +1499,7 @@ SIGNALduino_Read($) $hash->{keepalive}{retry} = 0; } SIGNALduino_Log3 $name, 5, "$name/msg READ: regexp=$regexp cmd=$hash->{getcmd}->{cmd} msg=$rmsg"; - + if ($hash->{getcmd}->{cmd} eq 'version') { my $msg_start = index($rmsg, 'V 3.'); if ($msg_start > 0) { @@ -1531,7 +1531,7 @@ SIGNALduino_Read($) delete($hash->{getcmd}); } } else { - SIGNALduino_Log3 $name, 4, "$name/msg READ: Received answer ($rmsg) for ". $hash->{getcmd}->{cmd}." does not match $regexp"; + SIGNALduino_Log3 $name, 4, "$name/msg READ: Received answer ($rmsg) for ". $hash->{getcmd}->{cmd}." does not match $regexp"; } } } @@ -1543,9 +1543,9 @@ SIGNALduino_Read($) sub SIGNALduino_KeepAlive($){ my ($hash) = @_; my $name = $hash->{NAME}; - + return if ($hash->{DevState} eq 'disconnected'); - + #SIGNALduino_Log3 $name,4 , "$name/KeepAliveOk: " . $hash->{keepalive}{ok}; if (!$hash->{keepalive}{ok}) { delete($hash->{getcmd}); @@ -1571,7 +1571,7 @@ sub SIGNALduino_KeepAlive($){ SIGNALduino_Log3 $name,4 , "$name/keepalive ok, retry = " . $hash->{keepalive}{retry}; } $hash->{keepalive}{ok} = 0; - + InternalTimer(gettimeofday() + SDUINO_KEEPALIVE_TIMEOUT, "SIGNALduino_KeepAlive", $hash); } @@ -1582,7 +1582,7 @@ sub SIGNALduino_KeepAlive($){ ## Parses a HTTP Response for example for flash via http download sub SIGNALduino_ParseHttpResponse { - + my ($param, $err, $data) = @_; my $hash = $param->{hash}; my $name = $hash->{NAME}; @@ -1593,29 +1593,29 @@ sub SIGNALduino_ParseHttpResponse } elsif($param->{code} eq "200" && $data ne "") # wenn die Abfrage erfolgreich war ($data enthaelt die Ergebnisdaten des HTTP Aufrufes) { - + SIGNALduino_Log3 $name, 3, "url ".$param->{url}." returned: ".length($data)." bytes Data"; # Eintrag fuers Log - + if ($param->{command} eq "flash") { my $filename; - + if ($param->{httpheader} =~ /Content-Disposition: attachment;.?filename=\"?([-+.\w]+)?\"?/) - { + { $filename = $1; } else { # Filename via path if not specifyied via Content-Disposition ($filename = $param->{path}) =~s/.*\///; } - + SIGNALduino_Log3 $name, 3, "$name: Downloaded $filename firmware from ".$param->{host}; SIGNALduino_Log3 $name, 5, "$name: Header = ".$param->{httpheader}; - - + + $filename = "FHEM/firmware/" . $filename; open(my $file, ">", $filename) or die $!; print $file $data; close $file; - + # Den Flash Befehl mit der soebene heruntergeladenen Datei ausfuehren #SIGNALduino_Log3 $name, 3, "calling set ".$param->{command}." $filename"; # Eintrag fuers Log @@ -1637,7 +1637,7 @@ sub SIGNALduino_splitMsg my $txt = shift; my $delim = shift; my @msg_parts = split(/$delim/,$txt); - + return @msg_parts; } # $value - $set <= $tolerance @@ -1666,7 +1666,7 @@ sub SIGNALduino_FillPatternLookupTable { } else { ${$rtext} = ""; return 0; - + } } @@ -1674,7 +1674,7 @@ sub SIGNALduino_FillPatternLookupTable { # - - - - - - - - - - - - #=item SIGNALduino_PatternExists() #This functons, needs reference to $hash, @array of values to search and %patternList where to find the matches. -# +# # Will return -1 if pattern is not found or a string, containing the indexes which are in tolerance and have the smallest gap to what we searched # =cut @@ -1686,45 +1686,45 @@ sub SIGNALduino_PatternExists { my ($hash,$search,$patternList,$data) = @_; #my %patternList=$arg3; - #Debug "plist: ".Dumper($patternList) if($debug); + #Debug "plist: ".Dumper($patternList) if($debug); #Debug "searchlist: ".Dumper($search) if($debug); - + my $searchpattern; - my $valid=1; + my $valid=1; my @pstr; my $debug = AttrVal($hash->{NAME},"debug",0); - + my $i=0; - + my $maxcol=0; - - foreach $searchpattern (@{$search}) # z.B. [1, -4] + + foreach $searchpattern (@{$search}) # z.B. [1, -4] { #my $patt_id; # Calculate tolernace for search #my $tol=abs(abs($searchpattern)>=2 ?$searchpattern*0.3:$searchpattern*1.5); my $tol=abs(abs($searchpattern)>3 ? abs($searchpattern)>16 ? $searchpattern*0.18 : $searchpattern*0.3 : 1); #tol is minimum 1 or higer, depending on our searched pulselengh - - Debug "tol: looking for ($searchpattern +- $tol)" if($debug); - + + Debug "tol: looking for ($searchpattern +- $tol)" if($debug); + my %pattern_gap ; #= {}; # Find and store the gap of every pattern, which is in tolerance %pattern_gap = map { $_ => abs($patternList->{$_}-$searchpattern) } grep { abs($patternList->{$_}-$searchpattern) <= $tol} (keys %$patternList); - if (scalar keys %pattern_gap > 0) + if (scalar keys %pattern_gap > 0) { Debug "index => gap in tol (+- $tol) of pulse ($searchpattern) : ".Dumper(\%pattern_gap) if($debug); # Extract fist pattern, which is nearst to our searched value my @closestidx = (sort {$pattern_gap{$a} <=> $pattern_gap{$b}} keys %pattern_gap); - + my $idxstr=""; my $r=0; - - while (my ($item) = splice(@closestidx, 0, 1)) + + while (my ($item) = splice(@closestidx, 0, 1)) { - $pstr[$i][$r]=$item; + $pstr[$i][$r]=$item; $r++; Debug "closest pattern has index: $item" if($debug); } @@ -1732,14 +1732,14 @@ sub SIGNALduino_PatternExists } else { # search is not found, return -1 return -1; - last; + last; } $i++; #return ($valid ? $pstr : -1); # return $pstr if $valid or -1 - + #foreach $patt_id (keys %$patternList) { - #Debug "$patt_id. chk ->intol $patternList->{$patt_id} $searchpattern $tol"; + #Debug "$patt_id. chk ->intol $patternList->{$patt_id} $searchpattern $tol"; #$valid = SIGNALduino_inTol($patternList->{$patt_id}, $searchpattern, $tol); #if ( $valid) #one pulse found in tolerance, search next one #{ @@ -1752,21 +1752,21 @@ sub SIGNALduino_PatternExists #last if (!$valid); ## Exit loop if a complete iteration has not found anything } my @results = (''); - + foreach my $subarray (@pstr) { @results = map {my $res = $_; map $res.$_, @$subarray } @results; } - + foreach my $search (@results) { Debug "looking for substr $search" if($debug); - + return $search if (index( ${$data}, $search) >= 0); } - + return -1; - + #return ($valid ? @results : -1); # return @pstr if $valid or -1 } @@ -1775,20 +1775,20 @@ sub SIGNALduino_MatchSignalPattern($\@\%\@$){ my ( $hash, $signalpattern, $patternList, $data_array, $idx) = @_; my $name = $hash->{NAME}; - #print Dumper($patternList); - #print Dumper($idx); - #Debug Dumper($signalpattern) if ($debug); + #print Dumper($patternList); + #print Dumper($idx); + #Debug Dumper($signalpattern) if ($debug); my $tol="0.2"; # Tolerance factor my $found=0; my $debug = AttrVal($hash->{NAME},"debug",0); - + foreach ( @{$signalpattern} ) { - #Debug " $idx check: ".$patternList->{$data_array->[$idx]}." == ".$_; - Debug "$name: idx: $idx check: abs(". $patternList->{$data_array->[$idx]}." - ".$_.") > ". ceil(abs($patternList->{$data_array->[$idx]}*$tol)) if ($debug); - + #Debug " $idx check: ".$patternList->{$data_array->[$idx]}." == ".$_; + Debug "$name: idx: $idx check: abs(". $patternList->{$data_array->[$idx]}." - ".$_.") > ". ceil(abs($patternList->{$data_array->[$idx]}*$tol)) if ($debug); + #print "\n";; - #if ($patternList->{$data_array->[$idx]} ne $_ ) + #if ($patternList->{$data_array->[$idx]} ne $_ ) ### Nachkommastelle von ceil!!! if (!defined( $patternList->{$data_array->[$idx]})){ Debug "$name: Error index ($idx) does not exist!!" if ($debug); @@ -1806,7 +1806,7 @@ sub SIGNALduino_MatchSignalPattern($\@\%\@$){ { return $idx; ## Return new Index Position } - + } @@ -1841,11 +1841,11 @@ sub SIGNALduino_Split_Message($$) my $clockabs; my $mcbitnum; my $rssi; - + my @msg_parts = SIGNALduino_splitMsg($rmsg,';'); ## Split message parts by ";" my %ret; my $debug = AttrVal($name,"debug",0); - + foreach (@msg_parts) { #Debug "$name: checking msg part:( $_ )" if ($debug); @@ -1857,17 +1857,17 @@ sub SIGNALduino_Split_Message($$) } elsif ($_ =~ m/^P\d=-?\d{2,}/ or $_ =~ m/^[SL][LH]=-?\d{2,}/) #### Extract Pattern List from array { - $_ =~ s/^P+//; - $_ =~ s/^P\d//; + $_ =~ s/^P+//; + $_ =~ s/^P\d//; my @pattern = split(/=/,$_); - + $patternList{$pattern[0]} = $pattern[1]; Debug "$name: extracted pattern @pattern \n" if ($debug); } elsif($_ =~ m/D=\d+/ or $_ =~ m/^D=[A-F0-9]+/) #### Message from array { - $_ =~ s/D=//; + $_ =~ s/D=//; $rawData = $_ ; Debug "$name: extracted data $rawData\n" if ($debug); $ret{rawData} = $rawData; @@ -1894,10 +1894,10 @@ sub SIGNALduino_Split_Message($$) Debug "$name: extracted number of $mcbitnum bits\n" if ($debug);; $ret{mcbitnum} = $mcbitnum; } - + elsif($_ =~ m/^C=\d+/) #### Message from array { - $_ =~ s/C=//; + $_ =~ s/C=//; $clockabs = $_ ; Debug "$name: extracted absolute clock $clockabs \n" if ($debug); $ret{clockabs} = $clockabs; @@ -1913,7 +1913,7 @@ sub SIGNALduino_Split_Message($$) } #print "$_\n"; } - $ret{pattern} = {%patternList}; + $ret{pattern} = {%patternList}; return %ret; } @@ -1924,15 +1924,15 @@ sub SIGNALduno_Dispatch($$$$$) { my ($hash, $rmsg, $dmsg, $rssi, $id) = @_; my $name = $hash->{NAME}; - + if (!defined($dmsg)) { SIGNALduino_Log3 $name, 5, "$name Dispatch: dmsg is undef. Skipping dispatch call"; return; } - + #SIGNALduino_Log3 $name, 5, "$name: Dispatch DMSG: $dmsg"; - + my $DMSGgleich = 1; if ($dmsg eq $hash->{LASTDMSG}) { SIGNALduino_Log3 $name, SDUINO_DISPATCH_VERBOSE, "$name Dispatch: $dmsg, test gleich"; @@ -1950,7 +1950,7 @@ sub SIGNALduno_Dispatch($$$$$) if ($DMSGgleich) { #Dispatch if dispatchequals is provided in protocol definition or only if $dmsg is different from last $dmsg, or if 2 seconds are between transmits - if ( (SIGNALduino_getProtoProp($id,'dispatchequals',0) eq 'true') || ($hash->{DMSG} ne $dmsg) || ($hash->{TIME}+2 < time() ) ) { + if ( (SIGNALduino_getProtoProp($id,'dispatchequals',0) eq 'true') || ($hash->{DMSG} ne $dmsg) || ($hash->{TIME}+2 < time() ) ) { $hash->{MSGCNT}++; $hash->{TIME} = time(); $hash->{DMSG} = $dmsg; @@ -1961,7 +1961,7 @@ sub SIGNALduno_Dispatch($$$$$) return if (substr($dmsg,0,1) eq 'U'); # Fuer $dmsg die mit U anfangen ist kein Dispatch notwendig, da es dafuer kein Modul gibt klein u wird dagegen dispatcht } #readingsSingleUpdate($hash, "state", $hash->{READINGS}{state}{VAL}, $event); - + $hash->{RAWMSG} = $rmsg; my %addvals = ( DMSG => $dmsg, @@ -1980,20 +1980,20 @@ sub SIGNALduno_Dispatch($$$$$) } $dmsg = lc($dmsg) if ($id eq '74' or $id eq '74.1'); # 10_FS20.pm accepted only lower case hex SIGNALduino_Log3 $name, SDUINO_DISPATCH_VERBOSE, "$name Dispatch: $dmsg, $rssi dispatch"; - Dispatch($hash, $dmsg, \%addvals); ## Dispatch to other Modules - + Dispatch($hash, $dmsg, \%addvals); ## Dispatch to other Modules + } else { SIGNALduino_Log3 $name, 4, "$name Dispatch: $dmsg, Dropped due to short time or equal msg"; } } } -# param #1 is name of definition +# param #1 is name of definition # param #2 is protocol id # param #3 is dispatched message to check against # # returns 1 if message matches modulematch + development attribute/whitelistIDs -# returns 0 if message does not match modulematch +# returns 0 if message does not match modulematch # return -1 if message is not activated via whitelistIDs but has developID=m flag sub SIGNALduino_moduleMatch { @@ -2002,7 +2002,7 @@ sub SIGNALduino_moduleMatch my $dmsg = shift; my $debug = AttrVal($name,"debug",0); my $modMatchRegex=SIGNALduino_getProtoProp($id,"modulematch",undef); - + if (!defined($modMatchRegex) || $dmsg =~ m/$modMatchRegex/) { Debug "$name: modmatch passed for: $dmsg" if ($debug); my $developID = SIGNALduino_getProtoProp($id,"developId",""); @@ -2011,7 +2011,7 @@ sub SIGNALduino_moduleMatch SIGNALduino_Log3 $name, 3, "$name: ID=$id skipped dispatch (developId=m). To use, please add $id to the attr whitelist_IDs"; return -1; } - return 1; # return 1 da modulematch gefunden wurde + return 1; # return 1 da modulematch gefunden wurde } return 0; } @@ -2021,35 +2021,35 @@ SIGNALduino_Parse_MS($$$$%) { my ($hash, $iohash, $name, $rmsg,%msg_parts) = @_; - my $syncidx=$msg_parts{syncidx}; - my $clockidx=$msg_parts{clockidx}; + my $syncidx=$msg_parts{syncidx}; + my $clockidx=$msg_parts{clockidx}; my $rssi=$msg_parts{rssi}; my $rawData=$msg_parts{rawData}; my %patternList; my $rssiStr= ""; - + if (defined($rssi)) { $rssi = ($rssi>=128 ? (($rssi-256)/2-74) : ($rssi/2-74)); # todo: passt dies so? habe ich vom 00_cul.pm $rssiStr= " RSSI = $rssi" } - + #Debug "Message splitted:"; #Debug Dumper(\@msg_parts); my $debug = AttrVal($iohash->{NAME},"debug",0); - + if (defined($clockidx) and defined($syncidx)) { - + ## Make a lookup table for our pattern index ids #Debug "List of pattern:"; my $clockabs= $msg_parts{pattern}{$msg_parts{clockidx}}; - return undef if ($clockabs == 0); + return undef if ($clockabs == 0); $patternList{$_} = round($msg_parts{pattern}{$_}/$clockabs,1) for keys %{$msg_parts{pattern}}; - - - #Debug Dumper(\%patternList); + + + #Debug Dumper(\%patternList); #my $syncfact = $patternList{$syncidx}/$patternList{$clockidx}; #$syncfact=$patternList{$syncidx}; @@ -2061,16 +2061,16 @@ SIGNALduino_Parse_MS($$$$%) ## Find matching protocols my $id; my $message_dispatched=0; - + IDLOOP: foreach $id (@{$hash->{msIdList}}) { - + Debug "Testing against Protocol id $id -> $ProtocolListSIGNALduino{$id}{name}" if ($debug); # Check Clock if is it in range if ($ProtocolListSIGNALduino{$id}{clockabs} > 0) { if (!SIGNALduino_inTol($ProtocolListSIGNALduino{$id}{clockabs},$clockabs,$clockabs*0.30)) { - Debug "protocClock=$ProtocolListSIGNALduino{$id}{clockabs}, msgClock=$clockabs is not in tol=" . $clockabs*0.30 if ($debug); + Debug "protocClock=$ProtocolListSIGNALduino{$id}{clockabs}, msgClock=$clockabs is not in tol=" . $clockabs*0.30 if ($debug); next; } elsif ($debug) { Debug "protocClock=$ProtocolListSIGNALduino{$id}{clockabs}, msgClock=$clockabs is in tol=" . $clockabs*0.30; @@ -2078,7 +2078,7 @@ SIGNALduino_Parse_MS($$$$%) } Debug "Searching in patternList: ".Dumper(\%patternList) if($debug); - + my %patternLookupHash=(); my %endPatternLookupHash=(); my $signal_width= @{$ProtocolListSIGNALduino{$id}{one}}; @@ -2086,13 +2086,13 @@ SIGNALduino_Parse_MS($$$$%) my $message_start; foreach my $key (qw(sync one zero float) ) { next if (!exists($ProtocolListSIGNALduino{$id}{$key})); - + if (!SIGNALduino_FillPatternLookupTable($hash,\@{$ProtocolListSIGNALduino{$id}{$key}},\$symbol_map{$key},\%patternList,\$rawData,\%patternLookupHash,\%endPatternLookupHash,\$return_text)) { Debug sprintf("%s pattern not found",$key) if ($debug); next IDLOOP if ($key ne "float") ; } - + if ($key eq "sync") { $message_start =index($rawData,$return_text)+length($return_text); @@ -2107,7 +2107,7 @@ SIGNALduino_Parse_MS($$$$%) Debug sprintf("Found matched %s with indexes: (%s)",$key,$return_text) if ($debug); } next if (scalar keys %patternLookupHash == 0); # Keine Eingträge im patternLookupHash - + SIGNALduino_Log3 $name, 4, "$name: Matched MS Protocol id $id -> $ProtocolListSIGNALduino{$id}{name}"; my @bit_msg; # array to store decoded signal bits @@ -2136,10 +2136,10 @@ SIGNALduino_Parse_MS($$$$%) last; } } - - + + Debug "$name: decoded message raw (@bit_msg), ".@bit_msg." bits\n" if ($debug); - + #Check converted message against lengths my ($rcode, $rtxt) = SIGNALduino_TestLength(undef,$id,scalar @bit_msg,""); if (!$rcode) @@ -2148,7 +2148,7 @@ SIGNALduino_Parse_MS($$$$%) next; } my $padwith = lib::SD_Protocols::checkProperty($id,'paddingbits',4); - + my $i=0; while (scalar @bit_msg % $padwith > 0) ## will pad up full nibbles per default or full byte if specified in protocol { @@ -2156,45 +2156,45 @@ SIGNALduino_Parse_MS($$$$%) $i++; } Debug "$name padded $i bits to bit_msg array" if ($debug); - + if ($i == 0) { SIGNALduino_Log3 $name, 5, "$name: dispatching bits: @bit_msg"; } else { SIGNALduino_Log3 $name, 5, "$name: dispatching bits: @bit_msg with $i Paddingbits 0"; } - + my $evalcheck = (SIGNALduino_getProtoProp($id,"developId","") =~ 'p') ? 1 : undef; ($rcode,my @retvalue) = SIGNALduino_callsub('postDemodulation',$ProtocolListSIGNALduino{$id}{postDemodulation},$evalcheck,$name,@bit_msg); next if ($rcode < 1 ); #SIGNALduino_Log3 $name, 5, "$name: postdemodulation value @retvalue"; - + @bit_msg = @retvalue; undef(@retvalue); undef($rcode); - + my $dmsg = SIGNALduino_b2h(join "", @bit_msg); my $postamble = $ProtocolListSIGNALduino{$id}{postamble}; $dmsg = "$dmsg".$postamble if (defined($postamble)); $dmsg = "$ProtocolListSIGNALduino{$id}{preamble}"."$dmsg" if (defined($ProtocolListSIGNALduino{$id}{preamble})); - - + + #my ($rcode,@retvalue) = SIGNALduino_callsub('preDispatchfunc',$ProtocolListSIGNALduino{$id}{preDispatchfunc},$name,$dmsg); #next if (!$rcode); #$dmsg = @retvalue; #undef(@retvalue); undef($rcode); - + if ( SIGNALduino_moduleMatch($name,$id,$dmsg) == 1) { $message_dispatched++; SIGNALduino_Log3 $name, 4, "$name: Decoded matched MS Protocol id $id dmsg $dmsg length " . scalar @bit_msg . " $rssiStr"; SIGNALduno_Dispatch($hash,$rmsg,$dmsg,$rssi,$id); - } - + } + } - + return 0 if (!$message_dispatched); - + return $message_dispatched; - + } } @@ -2214,7 +2214,7 @@ sub SIGNALduino_padbits(\@$) # - - - - - - - - - - - - #=item SIGNALduino_getProtoProp() #This functons, will return a value from the Protocolist and check if the key exists and a value is defined optional you can specify a optional default value that will be reurned -# +# # returns "" if the var is not defined # =cut # $id, $propertyname, @@ -2222,7 +2222,7 @@ sub SIGNALduino_padbits(\@$) sub SIGNALduino_getProtoProp { my ($id,$propNameLst,$default) = @_; - + #my $id = shift; #my $propNameLst = shift; return $ProtocolListSIGNALduino{$id}{$propNameLst} if exists($ProtocolListSIGNALduino{$id}{$propNameLst}) && defined($ProtocolListSIGNALduino{$id}{$propNameLst}); @@ -2244,31 +2244,31 @@ sub SIGNALduino_Parse_MU($$$$@) my $message_dispatched=0; my $debug = AttrVal($iohash->{NAME},"debug",0); my $rssiStr= ""; - + if (defined($rssi)) { $rssi = ($rssi>=128 ? (($rssi-256)/2-74) : ($rssi/2-74)); # todo: passt dies so? habe ich vom 00_cul.pm $rssiStr= " RSSI = $rssi" } - + Debug "$name: processing unsynced message\n" if ($debug); my $clockabs = 1; #Clock will be fetched from Protocol if possible #$patternListRaw{$_} = floor($msg_parts{pattern}{$_}/$clockabs) for keys $msg_parts{pattern}; $patternListRaw{$_} = $msg_parts{pattern}{$_} for keys %{$msg_parts{pattern}}; - + if (defined($clockidx)) { - + ## Make a lookup table for our pattern index ids - #Debug "List of pattern:"; #Debug Dumper(\%patternList); + #Debug "List of pattern:"; #Debug Dumper(\%patternList); ## Find matching protocols my $id; - + IDLOOP: foreach $id (@{$hash->{muIdList}}) { - + $clockabs= $ProtocolListSIGNALduino{$id}{clockabs}; my %patternList; $rawData=$msg_parts{rawData}; @@ -2279,32 +2279,32 @@ sub SIGNALduino_Parse_MU($$$$@) { SIGNALduino_Log3 $name, 5, "$name: Error: Unknown filtermethod=$method. Please define it in file $0"; next; - } else { + } else { SIGNALduino_Log3 $name, 5, "$name: for MU Protocol id $id, applying filterfunc $method"; no strict "refs"; - (my $count_changes,$rawData,my %patternListRaw_tmp) = $method->($name,$id,$rawData,%patternListRaw); + (my $count_changes,$rawData,my %patternListRaw_tmp) = $method->($name,$id,$rawData,%patternListRaw); use strict "refs"; - %patternList = map { $_ => round($patternListRaw_tmp{$_}/$clockabs,1) } keys %patternListRaw_tmp; + %patternList = map { $_ => round($patternListRaw_tmp{$_}/$clockabs,1) } keys %patternListRaw_tmp; } } else { - %patternList = map { $_ => round($patternListRaw{$_}/$clockabs,1) } keys %patternListRaw; + %patternList = map { $_ => round($patternListRaw{$_}/$clockabs,1) } keys %patternListRaw; } - - + + Debug "Testing against Protocol id $id -> $ProtocolListSIGNALduino{$id}{name}" if ($debug); Debug "Searching in patternList: ".Dumper(\%patternList) if($debug); my $startStr=""; # Default match if there is no start pattern available my $message_start=0 ; my $startLogStr=""; - + if (exists($ProtocolListSIGNALduino{$id}{start}) && defined($ProtocolListSIGNALduino{$id}{start}) && ref($ProtocolListSIGNALduino{$id}{start}) eq 'ARRAY') # wenn start definiert ist, dann startStr ermitteln und in rawData suchen und in der rawData alles bis zum startStr abschneiden { Debug "msgStartLst: ".Dumper(\@{$ProtocolListSIGNALduino{$id}{start}}) if ($debug); - - + + if ( ($startStr=SIGNALduino_PatternExists($hash,\@{$ProtocolListSIGNALduino{$id}{start}},\%patternList,\$rawData)) eq -1) { SIGNALduino_Log3 $name, 5, "$name: start pattern for MU Protocol id $id -> $ProtocolListSIGNALduino{$id}{name} not found, aborting"; @@ -2312,7 +2312,7 @@ sub SIGNALduino_Parse_MU($$$$@) } Debug "startStr is: $startStr" if ($debug); $message_start = index($rawData, $startStr); - if ( $message_start == -1) + if ( $message_start == -1) { Debug "startStr $startStr not found." if ($debug); next; @@ -2322,10 +2322,10 @@ sub SIGNALduino_Parse_MU($$$$@) Debug "rawData = $rawData" if ($debug); Debug "startStr $startStr found. Message starts at $message_start" if ($debug); SIGNALduino_Log3 $name, 5, "$name: substr: $rawData"; # todo: entfernen - } - + } + } - + my %patternLookupHash=(); my %endPatternLookupHash=(); my $pstr=""; @@ -2334,10 +2334,10 @@ sub SIGNALduino_Parse_MU($$$$@) my $floatRegex =""; my $return_text=""; my $signalRegex="(?:"; - + foreach my $key (qw(one zero float) ) { next if (!exists($ProtocolListSIGNALduino{$id}{$key})); - + if (!SIGNALduino_FillPatternLookupTable($hash,\@{$ProtocolListSIGNALduino{$id}{$key}},\$symbol_map{$key},\%patternList,\$rawData,\%patternLookupHash,\%endPatternLookupHash,\$return_text)) { Debug sprintf("%s pattern not found",$key) if ($debug); @@ -2347,26 +2347,26 @@ sub SIGNALduino_Parse_MU($$$$@) if ($key eq "one") { $signalRegex .= $return_text; - + } else { $signalRegex .= "|$return_text"; - + } } $signalRegex .= ")"; SIGNALduino_Log3 $name, 4, "$name: Fingerprint for MU Protocol id $id -> $ProtocolListSIGNALduino{$id}{name} matches, trying to demodulate"; - + my $signal_width= @{$ProtocolListSIGNALduino{$id}{one}}; my $length_min = $ProtocolListSIGNALduino{$id}{length_min}; my $length_max = ""; $length_max = $ProtocolListSIGNALduino{$id}{length_max} if (exists($ProtocolListSIGNALduino{$id}{length_max})); - + $signalRegex .= "{$length_min,}"; - + if (exists($ProtocolListSIGNALduino{$id}{reconstructBit})) { - + $signalRegex .= "(?:" . join("|",keys %endPatternLookupHash) . ")?"; } Debug "signalRegex is $signalRegex " if ($debug); @@ -2374,31 +2374,31 @@ sub SIGNALduino_Parse_MU($$$$@) my $nrRestart=0; my $nrDispatch=0; my $regex="(?:$startStr)($signalRegex)"; - + while ( $rawData =~ m/$regex/g) { my $length_str=""; $nrRestart++; - SIGNALduino_Log3 $name, 5, "part is $1 starts at position $-[0] and ends at ". pos $rawData; - + SIGNALduino_Log3 $name, 5, "part is $1 starts at position $-[0] and ends at ". pos $rawData; + my @pairs = unpack "(a$signal_width)*", $1; - + if (exists($ProtocolListSIGNALduino{$id}{length_max}) && scalar @pairs > $ProtocolListSIGNALduino{$id}{length_max}) # ist die Nachricht zu lang? { SIGNALduino_Log3 $name, 5, "$name: $nrRestart. skip demodulation (length ".scalar @pairs." is to long) at Pos $-[0] regex ($regex)"; next; } - + if ($nrRestart == 1) { - SIGNALduino_Log3 $name, 5, "$name: Starting demodulation ($startLogStr " . "regex: $regex Pos $message_start) length_min_max (".$length_min."..".$length_max.") length=".scalar @pairs; + SIGNALduino_Log3 $name, 5, "$name: Starting demodulation ($startLogStr " . "regex: $regex Pos $message_start) length_min_max (".$length_min."..".$length_max.") length=".scalar @pairs; } else { SIGNALduino_Log3 $name, 5, "$name: $nrRestart. try demodulation$length_str at Pos $-[0]"; } - - - - + + + + my @bit_msg=(); # array to store decoded signal bits - + foreach my $sigStr (@pairs) { if (exists $patternLookupHash{$sigStr}) { @@ -2410,37 +2410,37 @@ sub SIGNALduino_Parse_MU($$$$@) SIGNALduino_Log3 $name, 4, "$name: last part pair=$sigStr reconstructed, bit=$lastbit"; } } - + Debug "$name: demodulated message raw (@bit_msg), ".@bit_msg." bits\n" if ($debug); my $evalcheck = (SIGNALduino_getProtoProp($id,"developId","") =~ 'p') ? 1 : undef; my ($rcode,@retvalue) = SIGNALduino_callsub('postDemodulation',$ProtocolListSIGNALduino{$id}{postDemodulation},$evalcheck,$name,@bit_msg); - + next if ($rcode < 1 ); @bit_msg = @retvalue; undef(@retvalue); undef($rcode); - - my $dispmode="hex"; + + my $dispmode="hex"; $dispmode="bin" if (SIGNALduino_getProtoProp($id,"dispatchBin",0) == 1 ); - + my $padwith = lib::SD_Protocols::checkProperty($id,'paddingbits',4); while (scalar @bit_msg % $padwith > 0) ## will pad up full nibbles per default or full byte if specified in protocol { push(@bit_msg,'0'); Debug "$name: padding 0 bit to bit_msg array" if ($debug); - } + } my $dmsg = join ("", @bit_msg); my $bit_length=scalar @bit_msg; @bit_msg=(); # clear bit_msg array $dmsg = SIGNALduino_b2h($dmsg) if (SIGNALduino_getProtoProp($id,"dispatchBin",0) == 0 ); - + $dmsg =~ s/^0+// if ( SIGNALduino_getProtoProp($id,"remove_zero",0) ); - + $dmsg=sprintf("%s%s%s",SIGNALduino_getProtoProp($id,"preamble",""),$dmsg,SIGNALduino_getProtoProp($id,"postamble","")); SIGNALduino_Log3 $name, 5, "$name: dispatching $dispmode: $dmsg"; - + if ( SIGNALduino_moduleMatch($name,$id,$dmsg) == 1) { $nrDispatch++; @@ -2450,15 +2450,15 @@ sub SIGNALduino_Parse_MU($$$$@) { last; } - } + } } SIGNALduino_Log3 $name, 5, "$name: $nrRestart. try, regex ($regex) did not match" if ($nrRestart == 0); $message_dispatched=$message_dispatched+$nrDispatch; } - return $message_dispatched; - + return $message_dispatched; + } } @@ -2482,13 +2482,13 @@ SIGNALduino_Parse_MC($$$$@) if (defined($rssi)) { $rssi = ($rssi>=128 ? (($rssi-256)/2-74) : ($rssi/2-74)); # todo: passt dies so? habe ich vom 00_cul.pm } - + return undef if (!$clock); #my $protocol=undef; #my %patternListRaw = %msg_parts{patternList}; - + Debug "$name: processing manchester messag len:".length($rawData) if ($debug); - + my $hlen = length($rawData); my $blen; #if (defined($mcbitnum)) { @@ -2497,10 +2497,10 @@ SIGNALduino_Parse_MC($$$$@) $blen = $hlen * 4; #} my $id; - + my $rawDataInverted; ($rawDataInverted = $rawData) =~ tr/0123456789ABCDEF/FEDCBA9876543210/; # Some Manchester Data is inverted - + foreach $id (@{$hash->{mcIdList}}) { #next if ($blen < $ProtocolListSIGNALduino{$id}{length_min} || $blen > $ProtocolListSIGNALduino{$id}{length_max}); @@ -2514,7 +2514,7 @@ SIGNALduino_Parse_MC($$$$@) } else { SIGNALduino_Log3 $name, 4, "$name: Found manchester Protocol id $id clock $clock -> $ProtocolListSIGNALduino{$id}{name}"; } - + my $polarityInvert = 0; if (exists($ProtocolListSIGNALduino{$id}{polarity}) && ($ProtocolListSIGNALduino{$id}{polarity} eq 'invert')) { @@ -2526,14 +2526,14 @@ SIGNALduino_Parse_MC($$$$@) } if ($polarityInvert == 1) { - $bitData= unpack("B$blen", pack("H$hlen", $rawDataInverted)); - + $bitData= unpack("B$blen", pack("H$hlen", $rawDataInverted)); + } else { - $bitData= unpack("B$blen", pack("H$hlen", $rawData)); + $bitData= unpack("B$blen", pack("H$hlen", $rawData)); } Debug "$name: extracted data $bitData (bin)\n" if ($debug); ## Convert Message from hex to bits SIGNALduino_Log3 $name, 5, "$name: extracted data $bitData (bin)"; - + my $method; if (!exists $ProtocolListSIGNALduino{$id}{method}) { $method = \&main::SIGNALduino_MCRAW; @@ -2546,7 +2546,7 @@ SIGNALduino_Parse_MC($$$$@) my ($rcode,$res) = $method->($name,$bitData,$id,$mcbitnum); if ($rcode != -1) { $dmsg = $res; - $dmsg=$ProtocolListSIGNALduino{$id}{preamble}.$dmsg if (defined($ProtocolListSIGNALduino{$id}{preamble})); + $dmsg=$ProtocolListSIGNALduino{$id}{preamble}.$dmsg if (defined($ProtocolListSIGNALduino{$id}{preamble})); my $modulematch; if (defined($ProtocolListSIGNALduino{$id}{modulematch})) { $modulematch = $ProtocolListSIGNALduino{$id}{modulematch}; @@ -2573,14 +2573,14 @@ SIGNALduino_Parse_MC($$$$@) } } else { $res="undef" if (!defined($res)); - SIGNALduino_Log3 $name, 5, "$name: protocol does not match return from method: ($res)" ; + SIGNALduino_Log3 $name, 5, "$name: protocol does not match return from method: ($res)" ; } } else { SIGNALduino_Log3 $name, 3, "$name: Error: defined methode are NOT exist! Please check it!"; return 0; } } - + } return 0 if (!$message_dispatched); return 1; @@ -2593,8 +2593,8 @@ SIGNALduino_Parse($$$$@) my ($hash, $iohash, $name, $rmsg, $initstr) = @_; #print Dumper(\%ProtocolListSIGNALduino); - - + + if (!($rmsg=~ s/^\002(M.;.*;)\003/$1/)) # Check if a Data Message arrived and if it's complete (start & end control char are received) { # cut off start end end character from message for further processing they are not needed SIGNALduino_Log3 $name, AttrVal($name,"noMsgVerbose",5), "$name/noMsg Parse: $rmsg"; @@ -2605,24 +2605,24 @@ SIGNALduino_Parse($$$$@) $hash->{keepalive}{ok} = 1; $hash->{keepalive}{retry} = 0; } - + my $debug = AttrVal($iohash->{NAME},"debug",0); - - + + Debug "$name: incoming message: ($rmsg)\n" if ($debug); - + if (AttrVal($name, "rawmsgEvent", 0)) { DoTrigger($name, "RAWMSG " . $rmsg); } - + my %signal_parts=SIGNALduino_Split_Message($rmsg,$name); ## Split message and save anything in an hash %signal_parts #Debug "raw data ". $signal_parts{rawData}; - - + + my $dispatched; # Message Synced type -> M# - if (@{$hash->{msIdList}} && $rmsg=~ m/^MS;(P\d=-?\d+;){3,8}D=\d+;CP=\d;SP=\d;/) + if (@{$hash->{msIdList}} && $rmsg=~ m/^MS;(P\d=-?\d+;){3,8}D=\d+;CP=\d;SP=\d;/) { $dispatched= SIGNALduino_Parse_MS($hash, $iohash, $name, $rmsg,%signal_parts); } @@ -2632,7 +2632,7 @@ SIGNALduino_Parse($$$$@) $dispatched= SIGNALduino_Parse_MU($hash, $iohash, $name, $rmsg,%signal_parts); } # Manchester encoded Data -> MC - elsif (@{$hash->{mcIdList}} && $rmsg=~ m/^M[cC];.*;/) + elsif (@{$hash->{mcIdList}} && $rmsg=~ m/^M[cC];.*;/) { $dispatched= SIGNALduino_Parse_MC($hash, $iohash, $name, $rmsg,%signal_parts); } @@ -2640,14 +2640,14 @@ SIGNALduino_Parse($$$$@) Debug "$name: unknown Messageformat, aborting\n" if ($debug); return undef; } - + if ( AttrVal($hash->{NAME},"verbose","0") > 4 && !$dispatched) { my $notdisplist; my @lines; if (defined($hash->{unknownmessages})) { - $notdisplist=$hash->{unknownmessages}; + $notdisplist=$hash->{unknownmessages}; @lines = split ('#', $notdisplist); # or whatever } push(@lines,FmtDateTime(time())."-".$rmsg); @@ -2673,7 +2673,7 @@ SIGNALduino_Ready($) $hash->{DevState} = 'disconnected'; return DevIo_OpenDev($hash, 1, "SIGNALduino_DoInit", 'SIGNALduino_Connect') } - + # This is relevant for windows/USB only my $po = $hash->{USBDev}; my ($BlockingFlags, $InBytes, $OutBytes, $ErrorFlags); @@ -2688,9 +2688,9 @@ sub SIGNALduino_WriteInit($) { my ($hash) = @_; - + # todo: ist dies so ausreichend, damit die Aenderungen uebernommen werden? - SIGNALduino_AddSendQueue($hash,"WS36"); # SIDLE, Exit RX / TX, turn off frequency synthesizer + SIGNALduino_AddSendQueue($hash,"WS36"); # SIDLE, Exit RX / TX, turn off frequency synthesizer SIGNALduino_AddSendQueue($hash,"WS34"); # SRX, Enable RX. Perform calibration first if coming from IDLE and MCSM0.FS_AUTOCAL=1. } @@ -2702,7 +2702,7 @@ SIGNALduino_SimpleWrite(@) return if(!$hash); if($hash->{TYPE} eq "SIGNALduino_RFR") { # Prefix $msg with RRBBU and return the corresponding SIGNALduino hash. - ($hash, $msg) = SIGNALduino_RFR_AddPrefix($hash, $msg); + ($hash, $msg) = SIGNALduino_RFR_AddPrefix($hash, $msg); } my $name = $hash->{NAME}; @@ -2724,10 +2724,10 @@ SIGNALduino_Attr(@) my ($cmd,$name,$aName,$aVal) = @_; my $hash = $defs{$name}; my $debug = AttrVal($name,"debug",0); - + $aVal= "" if (!defined($aVal)); SIGNALduino_Log3 $name, 4, "$name: Calling Getting Attr sub with args: $cmd $aName = $aVal"; - + if( $aName eq "Clients" ) { ## Change clientList $hash->{Clients} = $aVal; $hash->{Clients} = $clientsSIGNALduino if( !$hash->{Clients}) ; ## Set defaults @@ -2740,7 +2740,7 @@ SIGNALduino_Attr(@) SIGNALduino_Log3 $name, 2, $name .": $aVal: ". $@; } } - + if( ref($match_list) eq 'HASH' ) { $hash->{MatchList} = $match_list; } else { @@ -2752,7 +2752,7 @@ SIGNALduino_Attr(@) { SIGNALduino_Log3 $name, 3, "$name: setting Verbose to: " . $aVal; $hash->{unknownmessages}="" if $aVal <4; - + } elsif ($aName eq "debug") { @@ -2816,28 +2816,28 @@ SIGNALduino_Attr(@) if (exists $attr{$name}{flashCommand}) { delete $attr{$name}{flashCommand};} } } - + return undef; } sub SIGNALduino_FW_Detail($@) { my ($FW_wname, $name, $room, $pageHash) = @_; - + my $hash = $defs{$name}; - + my @dspec=devspec2array("DEF=.*fakelog"); my $lfn = $dspec[0]; my $fn=$defs{$name}->{TYPE}."-Flash.log"; - + my $ret = "
Information menu "; if (-s AttrVal("global", "logdir", "./log/") .$fn) - { + { my $flashlogurl="$FW_ME/FileLog_logWrapper?dev=$lfn&type=text&file=$fn"; - + $ret .= ""; @@ -2845,15 +2845,15 @@ sub SIGNALduino_FW_Detail($@) { } my $protocolURL="$FW_ME/FileLog_logWrapper?dev=$lfn&type=text&file=$fn"; - + $ret.=""; $ret .= '
"; $ret .= "Last Flashlog<\/a>"; $ret .= "Display protocollist
- +