From 2b9c39954c85b900cba0e67239ed97d2362c7b3e Mon Sep 17 00:00:00 2001 From: tpoitzsch <> Date: Sun, 23 Nov 2014 20:19:30 +0000 Subject: [PATCH] FRITZBOX: performance git-svn-id: https://svn.fhem.de/fhem/trunk@7052 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/72_FRITZBOX.pm | 269 ++++++++++++++++++++++++++------------- 1 file changed, 180 insertions(+), 89 deletions(-) diff --git a/fhem/FHEM/72_FRITZBOX.pm b/fhem/FHEM/72_FRITZBOX.pm index 9554da375..a783c56db 100644 --- a/fhem/FHEM/72_FRITZBOX.pm +++ b/fhem/FHEM/72_FRITZBOX.pm @@ -102,8 +102,8 @@ my %alarmDays = ( , 64 => "So" ); -my @radio=(); - +my @radio = (); + sub ########################################## FRITZBOX_Log($$$) { @@ -339,27 +339,28 @@ FRITZBOX_Init($) while ( $result ne "" || defined $hash->{READINGS}{$rName} ); # Dect Telefon + # %handset = (); foreach (1..6) { - # Dect-Telefonname - FRITZBOX_Init_Reading($hash, - "dect".$_, - "ctlmgr_ctl r telcfg settings/Foncontrol/User".$_."/Name"); # Dect-Interne Nummer - FRITZBOX_Init_Reading($hash, + my $intern = FRITZBOX_Init_Reading($hash, "dect".$_."_intern", "ctlmgr_ctl r telcfg settings/Foncontrol/User".$_."/Intern"); - # Dect-Internal Ring Tone - # FRITZBOX_Init_Reading($hash, - # "dect".$_."_intRingTone", - # "ctlmgr_ctl r telcfg settings/Foncontrol/User".$_."/IntRingTone"); + next + unless $intern ne ""; + # Dect-Telefonname + $result = FRITZBOX_Init_Reading($hash, + "dect".$_, + "ctlmgr_ctl r telcfg settings/Foncontrol/User".$_."/Name"); + $hash->{fhem}{$intern}{Name} = $result; # Handset manufacturer - my $brand = FRITZBOX_Init_Reading($hash, + $result = FRITZBOX_Init_Reading($hash, "dect".$_."_manufacturer", "ctlmgr_ctl r dect settings/Handset".($_-1)."/Manufacturer"); - if ($brand eq "AVM") - { - # Intrnal Ring Tone Name + $hash->{fhem}{$intern}{brand} = $result; + if ($result eq "AVM") + { + # Internal Ring Tone Name FRITZBOX_Init_Reading($hash , "dect".$_."_intRingTone" , "ctlmgr_ctl r telcfg settings/Foncontrol/User".$_."/IntRingTone" @@ -390,12 +391,12 @@ FRITZBOX_Init($) FRITZBOX_Init_Reading($hash , "dect".$_."_fwVersion" , "ctlmgr_ctl r dect settings/Handset".($_-1)."/FWVersion"); - # Phone Model - FRITZBOX_Init_Reading($hash + $result = FRITZBOX_Init_Reading($hash , "dect".$_."_model" , "ctlmgr_ctl r dect settings/Handset".($_-1)."/Model" , "model"); + $hash->{fhem}{$intern}{Model} = $result; } } @@ -414,6 +415,10 @@ FRITZBOX_Init($) # Alarm clock foreach (0..2) { + # Alarm clock name + FRITZBOX_Init_Reading($hash + , "alarm".($_+1) + , "ctlmgr_ctl r telcfg settings/AlarmClock".$_."/Name"); # Alarm clock state FRITZBOX_Init_Reading($hash , "alarm".($_+1)."_state" @@ -434,10 +439,6 @@ FRITZBOX_Init($) , "alarm".($_+1)."_wdays" , "ctlmgr_ctl r telcfg settings/AlarmClock".$_."/Weekdays" , "aldays"); - # Alarm clock name - FRITZBOX_Init_Reading($hash - , "alarm".($_+1)."_name" - , "ctlmgr_ctl r telcfg settings/AlarmClock".$_."/Name"); } # user profiles @@ -471,8 +472,8 @@ FRITZBOX_Init($) RemoveInternalTimer($hash); - # Get next data after 60 minutes - InternalTimer(gettimeofday() + 3600, "FRITZBOX_Init", $hash, 1); + # Get next data after 5 minutes + InternalTimer(gettimeofday() + 300, "FRITZBOX_Init", $hash, 1); } @@ -547,6 +548,77 @@ FRITZBOX_Init_Reading($$$@) } return $result; } +sub ########################################## +FRITZBOX_Update_Readings($@) +{ + my ($hash, $rName, $cmd, $replace) = @_; + $replace = "" + unless defined $replace; + my $result = FRITZBOX_Exec( $hash, $cmd); + if ($result ne "") { + if ($replace eq "altime") + { + $result = substr($result,0,2).":".substr($result,-2); + } + if ($replace eq "aldays") + { + if ($result == 0) + { + $result = "once"; + } + elsif ($result == 127) + { + $result = "daily"; + } + else + { + my $bitStr = $result; + $result = ""; + foreach (sort keys %alarmDays) + { + $result .= (($bitStr & $_) == $_) ? $alarmDays{$_}." " : ""; + } + } + } + if ($replace eq "alnumber") + { + } + elsif ($replace eq "fwupdate") + { + my $update = FRITZBOX_Exec( $hash, "ctlmgr_ctl r updatecheck status/update_available_hint"); + $result .= " (old)" + if $update == 1; + } + if ($replace eq "model") + { + $result = $fonModel{$result} + if defined $fonModel{$result}; + } + elsif ($replace eq "onoff") + { + $result =~ s/0/off/; + $result =~ s/1/on/; + } + elsif ($replace eq "radio") + { + $result = $radio[$result]; + } + elsif ($replace eq "ringtone") + { + $result = $ringTone{$result}; + } + elsif ($replace eq "timeinhours") + { + $result = sprintf "%d h %d min", int $result/3600, int( ($result %3600) / 60); + } + readingsBulkUpdate($hash, $rName, $result) + if $result; + } elsif (defined $hash->{READINGS}{$rName} ) + { + delete $hash->{READINGS}{$rName}; + } + return $result; +} sub ########################################## FRITZBOX_Ring($@) @@ -554,9 +626,8 @@ FRITZBOX_Ring($@) my ($hash, @val) = @_; my $name = $hash->{NAME}; - my $timeOut = 20; - $timeOut = $val[1] + 15 - if defined $val[1]; + $val[1] = 5 + unless defined $val[1]; if ( exists( $hash->{helper}{RUNNING_PID} ) ) { @@ -564,14 +635,17 @@ FRITZBOX_Ring($@) BlockingKill( $hash->{helper}{RUNNING_PID} ); delete($hash->{helper}{RUNNING_PID}); } - - $hash->{helper}{RUNNING_PID} = BlockingCall("FRITZBOX_Ring_Run", $name."|".join("|", @val), - "FRITZBOX_Ring_Done", $timeOut, + + my $timeout = $val[1] + 5; + my $handover = $name . "|" . join( "|", @val ); + + $hash->{helper}{RUNNING_PID} = BlockingCall("FRITZBOX_Ring_Run", $handover, + "FRITZBOX_Ring_Done", $timeout, "FRITZBOX_Ring_Aborted", $hash); } # end FRITZBOX_Ring sub ########################################## -FRITZBOX_Ring_Run($$) +FRITZBOX_Ring_Run($) { my ($string) = @_; my ($name, $intNo, $duration, $ringTone) = split /\|/, $string; @@ -583,18 +657,21 @@ FRITZBOX_Ring_Run($$) my $curIntRingTone; my $curCallerName; my $cmd; - - if (610<=$intNo && $intNo<=615) - { - $fonType = "DECT"; $fonTypeNo = $intNo - 609; - } - - return $name."|0|Error: Internal number '$intNo' not valid" + my @cmdArray; + + $fonType = $hash->{fhem}{$intNo}{brand}; + + return $name."|0|Error: Internal number '$intNo' not a DECT number" unless defined $fonType; + $fonTypeNo = $intNo - 609; + $duration = 5 unless defined $duration; + $ringTone = undef + if ($fonType ne "AVM" ); + if (defined $ringTone) { my $temp = $ringTone; @@ -603,60 +680,61 @@ FRITZBOX_Ring_Run($$) unless defined $ringTone; } - my $msg = $hash->{Message}; - $msg = "FHEM" - unless defined $msg; - + my $msg = AttrVal( $name, "defaultCallerName", "FHEM" ); my $ringWithIntern = AttrVal( $name, "ringWithIntern", 0 ); # uses name of virtual port 0 (dial port 1) to show message on ringing phone if ($ringWithIntern =~ /^(1|2)$/ ) { - $curCallerName = FRITZBOX_Exec( $hash, "ctlmgr_ctl r telcfg settings/MSN/Port".($ringWithIntern-1)."/Name"); - FRITZBOX_Exec( $hash, "ctlmgr_ctl w telcfg settings/MSN/Port".($ringWithIntern-1)."/Name '$msg'"); + @cmdArray = (); + push @cmdArray, "ctlmgr_ctl r telcfg settings/MSN/Port".($ringWithIntern-1)."/Name"; + push @cmdArray, "ctlmgr_ctl w telcfg settings/MSN/Port".($ringWithIntern-1)."/Name '$msg'"; + $result = FRITZBOX_Exec( $hash, \@cmdArray ); + $curCallerName = $result->[0]; + FRITZBOX_Log $hash, 4, "Change name of ringing number $ringWithIntern from '$curCallerName' to '$msg'"; } - if ($fonType eq "DECT" ) + +# Change ring tone of Fritz!Fons + if (defined $ringTone) { - return $name."|0|Error: Internal number ".$intNo." does not exist" - unless FRITZBOX_Exec( $hash, "ctlmgr_ctl r telcfg settings/Foncontrol/User".$fonTypeNo."/Intern"); - if (defined $ringTone) - { - $curIntRingTone = FRITZBOX_Exec( $hash, "ctlmgr_ctl r telcfg settings/Foncontrol/User".$fonTypeNo."/IntRingTone"); - FRITZBOX_Log $hash, 5, "Current internal ring tone of DECT ".$fonTypeNo." is ".$curIntRingTone; - FRITZBOX_Exec( $hash, "ctlmgr_ctl w telcfg settings/Foncontrol/User".$fonTypeNo."/IntRingTone ".$ringTone); - FRITZBOX_Log $hash, 5, "Set internal ring tone of DECT ".$fonTypeNo." to ".$ringTone; - } - if ( $ringWithIntern != 0 ) - { - FRITZBOX_Exec( $hash, "ctlmgr_ctl w telcfg settings/DialPort ".$ringWithIntern); - } - FRITZBOX_Log $hash, 5, "Ringing $intNo for $duration seconds"; - $cmd = "ctlmgr_ctl w telcfg command/Dial **".$intNo."\n"; - $cmd .= "sleep ".($duration+1)."\n"; - $cmd .= "ctlmgr_ctl w telcfg command/Hangup **".$intNo; - FRITZBOX_Exec( $hash, $cmd); - if ( $ringWithIntern != 0 ) - { - FRITZBOX_Exec( $hash, "ctlmgr_ctl w telcfg settings/DialPort 50"); - } - if (defined $ringTone) - { - FRITZBOX_Log $hash, 5, "Set internal ring tone of DECT ".$fonTypeNo." back to ".$curIntRingTone; - FRITZBOX_Exec( $hash, "ctlmgr_ctl w telcfg settings/Foncontrol/User".$fonTypeNo."/IntRingTone ".$curIntRingTone); - } + @cmdArray = (); + push @cmdArray, "ctlmgr_ctl r telcfg settings/Foncontrol/User".$fonTypeNo."/IntRingTone"; + push @cmdArray, "ctlmgr_ctl w telcfg settings/Foncontrol/User".$fonTypeNo."/IntRingTone ".$ringTone; + $result = FRITZBOX_Exec( $hash, \@cmdArray ); + $curIntRingTone = $result->[0]; + FRITZBOX_Log $hash, 4, "Change internal ring tone of DECT ".$fonTypeNo." from ".$curIntRingTone." to ".$ringTone; } - if ($ringWithIntern =~ /^(1|2)$/ ) +# Ring + FRITZBOX_Log $hash, 4, "Ringing $intNo for $duration seconds"; + @cmdArray = (); + push @cmdArray, "ctlmgr_ctl w telcfg settings/DialPort ".$ringWithIntern + if $ringWithIntern != 0 ; + push @cmdArray, "ctlmgr_ctl w telcfg command/Dial **".$intNo; + push @cmdArray, "sleep ".($duration+1); + push @cmdArray, "ctlmgr_ctl w telcfg command/Hangup **".$intNo; + FRITZBOX_Exec( $hash, \@cmdArray ); + +# Reset everything + @cmdArray = (); + push @cmdArray, "ctlmgr_ctl w telcfg settings/DialPort 50" + if $ringWithIntern != 0; + push @cmdArray, "ctlmgr_ctl w telcfg settings/MSN/Port".($ringWithIntern-1)."/Name '$curCallerName'" + if $ringWithIntern =~ /^(1|2)$/ ; + push @cmdArray, "ctlmgr_ctl w telcfg settings/Foncontrol/User".$fonTypeNo."/IntRingTone ".$curIntRingTone + if (defined $ringTone); + if (int @cmdArray >0) { - FRITZBOX_Exec( $hash, "ctlmgr_ctl w telcfg settings/MSN/Port".($ringWithIntern-1)."/Name '$curCallerName'"); + FRITZBOX_Log $hash, 4, "Reset all temporary changes"; + FRITZBOX_Exec( $hash, \@cmdArray ); } - return $name."|1|"; + return $name."|1|Ringing done"; } sub ########################################## -FRITZBOX_Ring_Done($$) +FRITZBOX_Ring_Done($) { my ($string) = @_; return unless defined $string; @@ -670,10 +748,14 @@ FRITZBOX_Ring_Done($$) { FRITZBOX_Log $hash, 1, $result; } + else + { + FRITZBOX_Log $hash, 4, $result; + } } sub ########################################## -FRITZBOX_Ring_Aborted($$) +FRITZBOX_Ring_Aborted($) { my ($hash) = @_; delete($hash->{helper}{RUNNING_PID}); @@ -771,24 +853,33 @@ FRITZBOX_ConvertRingTone ($@) sub ############################################ FRITZBOX_Exec($$) { - my ($hash, @cmd) = @_; + my ($hash, $cmd) = @_; - FRITZBOX_Log $hash, 5, "Execute '".(join "|", @cmd)."'"; - my $cmdStr = (join "\n", @cmd); - my $result = qx($cmdStr); - - if (int @cmd > 1) - { - my @resultArray = split "\n".$result;; - FRITZBOX_Log $hash, 5, "Result '".join "|", @resultArray."'"; - return @resultArray; - } - else + if (ref \$cmd eq "SCALAR") { + FRITZBOX_Log $hash, 5, "Execute '".$cmd."'"; + my $result = qx($cmd); chomp $result; FRITZBOX_Log $hash, 5, "Result '$result'"; return $result; } + elsif (ref \$cmd eq "REF") + { + if (int @{$cmd} >0 ) + { + FRITZBOX_Log $hash, 5, "Execute '".(join " | ", @{$cmd})."'"; + my $cmdStr = join "\necho ' |#|'\n", @{$cmd}; + $cmdStr .= "\necho ' |#|'"; + my $result = qx($cmdStr); + $result =~ s/\n|\r//g; + my @resultArray = split /\|#\|/, $result; + foreach (keys @resultArray) + { $resultArray[$_] =~ s/\s$//; + } + FRITZBOX_Log $hash, 5, "Result '".join (" | ", @resultArray)."' (count: ".int (@resultArray).")"; + return \@resultArray; + } + } } ##################################### @@ -885,7 +976,7 @@ FRITZBOX_Exec($$)
To ring a fon a caller must always be specified. Default of this modul is 50 "ISDN:Wählhilfe".
- To show a message (default is "FHEM") during a ring a free internal phone number can be specified here. + To show a message (default is "FHEM") during a ring the internal phone numbers 1 or 2 can be specified here.
  • defaultUploadDir <fritzBoxPath>