diff --git a/fhem/CHANGED b/fhem/CHANGED index 535631fd6..9a25f278a 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,10 @@ # 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. + - bugfix: 72_FB_CALLMONITOR: replace all unicode placeholders correctly + in reverse search results + - feature: 72_FB_CALLMONITOR: block calls, that matches configured + blocking rules (deflections) from the FritzBox + (new attribute check-deflections), see commandref for details - changed: 98_Dooya: updated module - new: 98_Siro: New module for Siro blinds - bugfix: 73_UpsPico: Swap to Net::OpenSSH module and error message handling diff --git a/fhem/FHEM/72_FB_CALLMONITOR.pm b/fhem/FHEM/72_FB_CALLMONITOR.pm index df9a1357a..14f6047b6 100755 --- a/fhem/FHEM/72_FB_CALLMONITOR.pm +++ b/fhem/FHEM/72_FB_CALLMONITOR.pm @@ -31,6 +31,7 @@ package main; use strict; use warnings; use Time::HiRes qw(gettimeofday); +use Encode qw(encode); use Digest::MD5; use HttpUtils; use DevIo; @@ -61,6 +62,7 @@ FB_CALLMONITOR_Initialize($) "country-code ". "remove-leading-zero:0,1 ". "answMachine-is-missed-call:0,1 ". + "check-deflections:0,1 ". "reverse-search-cache-file ". "reverse-search:sortable-strict,phonebook,textfile,klicktel.de,dasoertliche.de,search.ch,dasschnelle.at ". "reverse-search-cache:0,1 ". @@ -341,16 +343,19 @@ FB_CALLMONITOR_Read($) my $name = $hash->{NAME}; my @array; - my $reverse_search = undef; + my $data = $buf; my $area_code = AttrVal($name, "local-area-code", ""); my $country_code = AttrVal($name, "country-code", "0049"); - my $external_number = undef; - + foreach $data (split(/;\r\n/m, $buf)) { chomp $data; - + + my $external_number = undef; + my $reverse_search = undef; + my $is_deflected = undef; + Log3 $name, 5, "FB_CALLMONITOR ($name) - received data: $data"; @array = split(";", $data); @@ -358,6 +363,8 @@ FB_CALLMONITOR_Read($) $external_number = $array[3] if(not $array[3] eq "0" and $array[1] eq "RING" and $array[3] ne ""); $external_number = $array[5] if($array[1] eq "CALL" and $array[3] ne ""); + $is_deflected = FB_CALLMONITOR_checkNumberForDeflection($hash, $external_number) if($array[1] eq "RING"); + if(defined($external_number)) { $external_number =~ s/^0// if(AttrVal($name, "remove-leading-zero", "0") eq "1"); @@ -394,7 +401,7 @@ FB_CALLMONITOR_Read($) Log3 $name, 4, "FB_CALLMONITOR ($name) - reverse search returned: $reverse_search" if(defined($reverse_search)); } - if($array[1] eq "CALL" or $array[1] eq "RING") + if($array[1] =~ /^CALL|RING$/) { delete($hash->{helper}{TEMP}{$array[2]}) if(exists($hash->{helper}{TEMP}{$array[2]})); @@ -406,10 +413,7 @@ FB_CALLMONITOR_Read($) { $hash->{helper}{TEMP}{$array[2]}{call_id} = $array[2]; } - } - if($array[1] =~ /^CALL|RING$/) - { $hash->{helper}{TEMP}{$array[2]}{external_number} = (defined($external_number) ? $external_number : "unknown"); $hash->{helper}{TEMP}{$array[2]}{external_name} = (defined($reverse_search) ? $reverse_search : "unknown"); $hash->{helper}{TEMP}{$array[2]}{internal_number} = $array[4]; @@ -426,6 +430,7 @@ FB_CALLMONITOR_Read($) { $hash->{helper}{TEMP}{$array[2]}{external_connection} = $array[5]; $hash->{helper}{TEMP}{$array[2]}{direction} = "incoming"; + $hash->{helper}{TEMP}{$array[2]}{".deflected"} = $is_deflected; } if($array[1] eq "CONNECT" and not exists($hash->{helper}{TEMP}{$array[2]}{internal_connection})) @@ -448,21 +453,27 @@ FB_CALLMONITOR_Read($) } $hash->{helper}{TEMP}{$array[2]}{".last-event"} = $array[1]; - - readingsBeginUpdate($hash); - readingsBulkUpdate($hash, "event", lc($array[1])); - - foreach my $key (keys %{$hash->{helper}{TEMP}{$array[2]}}) + + unless($hash->{helper}{TEMP}{$array[2]}{".deflected"}) { - readingsBulkUpdate($hash, $key, $hash->{helper}{TEMP}{$array[2]}{$key}) unless($key =~ /^\./); + readingsBeginUpdate($hash); + readingsBulkUpdate($hash, "event", lc($array[1])); + + foreach my $key (keys %{$hash->{helper}{TEMP}{$array[2]}}) + { + readingsBulkUpdate($hash, $key, $hash->{helper}{TEMP}{$array[2]}{$key}) unless($key =~ /^\./); + } + readingsEndUpdate($hash, 1); + } + else + { + Log3 $name, 4, "FB_CALLMONITOR ($name) - skipped creating readings/events due to deflection match"; } if($array[1] eq "DISCONNECT") { delete($hash->{helper}{TEMP}{$array[2]}) if(exists($hash->{helper}{TEMP}{$array[2]})); } - - readingsEndUpdate($hash, 1); } } @@ -837,17 +848,25 @@ FB_CALLMONITOR_reverseSearch($$) sub FB_CALLMONITOR_html2txt($) { my ($string) = @_; - + $string =~ s/ / /g; $string =~ s/&/&/g; $string =~ s/&pos;/'/g; - $string =~ s/(\xe4|ä|\\u00e4|\\u00E4)/ä/g; - $string =~ s/(\xc4|Ä|\\u00c4|\\u00C4)/Ä/g; - $string =~ s/(\xf6|ö|\\u00f6|\\u00F6)/ö/g; - $string =~ s/(\xd6|Ö|\\u00d6|\\u00D6)/Ö/g; - $string =~ s/(\xfc|ü|\\u00fc|\\u00FC)/ü/g; - $string =~ s/(\xdc|Ü|\\u00dc|\\u00DC)/Ü/g; - $string =~ s/(\xdf|ß|\\u00df|\\u00DF)/ß/g; + + + $string =~ s/(\xe4|ä)/ä/g; + $string =~ s/(\xc4|Ä)/Ä/g; + $string =~ s/(\xf6|ö)/ö/g; + $string =~ s/(\xd6|Ö)/Ö/g; + $string =~ s/(\xfc|ü)/ü/g; + $string =~ s/(\xdc|Ü)/Ü/g; + $string =~ s/(\xdf|ß)/ß/g; + $string =~ s/(\xdf|ß)/ß/g; + $string =~ s/(\xe1|á)/á/g; + $string =~ s/(\xe9|é)/é/g; + $string =~ s/(\xc1|Á)/Á/g; + $string =~ s/(\xc9|É)/É/g; + $string =~ s/\\u([a-f\d]{4})/encode('UTF-8',chr(hex($1)))/eig; $string =~ s/<[^>]+>//g; $string =~ s/<//g; @@ -856,6 +875,7 @@ sub FB_CALLMONITOR_html2txt($) return $string; } + ##################################### # writes reverse search result to the cache and if enabled to the cache file sub FB_CALLMONITOR_writeToCache($$$) @@ -1838,6 +1858,43 @@ sub FB_CALLMONITOR_encrypt($$) return (undef, $enc_pwd); } +sub FB_CALLMONITOR_checkNumberForDeflection($$) +{ + my ($hash, $number) = @_; + my $name = $hash->{NAME}; + + my $ret = 0; + + if(exists($hash->{helper}{DEFLECTIONS}) and AttrVal($name,"check-deflections",0)) + { + my $deflection_count = scalar keys %{$hash->{helper}{DEFLECTIONS}}; + + Log3 $name, 4, "FB_CALLMONITOR ($name) - check ".(defined($number) ? $number : "unknown number")." against deflection rules (".$deflection_count." rule".($deflection_count ==1 ? "" : "s").")"; + + foreach my $item (values %{$hash->{helper}{DEFLECTIONS}}) + { + next unless($item->{Enable}); # next if rule not enabled + next if(!$item->{Type}); + + if($item->{Type} eq "fromNumber" and $item->{Number} and $number) + { + my $tmp = $item->{Number}; + $ret = 1 if($number =~ /^0?$tmp/); + } + elsif($item->{Type} eq "fromPB" and $item->{PhonebookID} and $number) + { + $ret = 1 if(exists($hash->{helper}{PHONEBOOKS}) and exists($hash->{helper}{PHONEBOOKS}{$item->{PhonebookID}}) and exists($hash->{helper}{PHONEBOOKS}{$item->{PhonebookID}}{$number})); + } + elsif($item->{Type} eq "fromAnonymous") + { + $ret = 1 unless(defined($number)); + } + } + } + + Log3 $name, 4, "FB_CALLMONITOR ($name) - found matching deflection. call will be ignored" if($ret); + return $ret; +} 1; =pod @@ -1960,16 +2017,20 @@ sub FB_CALLMONITOR_encrypt($$)