diff --git a/fhem/CHANGED b/fhem/CHANGED index 62f94662b..a04a7be18 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,9 @@ # 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. + - feature: FB_CALLLIST: new attribute answMachine-is-missed-call to treat + treat incoming calls, which were taken by an + an answering machine, as "missed call". Only + relevant for list-type "missed-call". - change: FB_CALLMONITOR: reading "missed_call_line" will not be triggered anymore. Use internal_number instead, which contains the same content diff --git a/fhem/FHEM/72_FB_CALLLIST.pm b/fhem/FHEM/72_FB_CALLLIST.pm index 03b9ffff1..5e8f7179a 100755 --- a/fhem/FHEM/72_FB_CALLLIST.pm +++ b/fhem/FHEM/72_FB_CALLLIST.pm @@ -54,6 +54,7 @@ FB_CALLLIST_Initialize($) "list-type:all,incoming,outgoing,missed-calls,completed,active " . "time-format-string ". "list-order:ascending,descending ". + "answMachine-is-missed-call:0,1 ". "language:de,en ". "disable:0,1 ". "disabledForIntervals ". @@ -96,7 +97,7 @@ sub FB_CALLLIST_Define($$) } $hash->{FB} = $callmonitor; - $hash->{NOTIFYDEV} = $callmonitor; + $hash->{NOTIFYDEV} = "global,".$callmonitor; $hash->{STATE} = 'Initialized'; $hash->{helper}{DEFAULT_COLUMN_ORDER} = "row,state,timestamp,name,number,internal,external,connection,duration"; @@ -207,13 +208,6 @@ sub FB_CALLLIST_Attr($@) return "invalid external mapping table: $value"; } } - elsif($attrib eq "list-type") - { - if($value and $value =~ /^incoming|outgoing|missed-call|completed|active$/) - { - $attr{$name}{$attrib} = $value; - } - } } elsif($cmd eq "del") { @@ -234,18 +228,6 @@ sub FB_CALLLIST_Attr($@) delete($hash->{helper}{EXTERNAL_MAP}) if(exists($hash->{helper}{EXTERNAL_MAP})); } } - - if($init_done) - { - # delete all outdated calls according to attribute list-type, internal-number-filter and number-of-calls - FB_CALLLIST_cleanupList($hash); - - # Inform all FHEMWEB clients - FB_CALLLIST_updateFhemWebClients($hash); - - # save current list state to file/configDB - FB_CALLLIST_saveList($hash); - } } ##################################### @@ -289,27 +271,38 @@ sub FB_CALLLIST_Notify($$) { my ($hash,$d) = @_; - return undef if(!defined($hash)); - + return undef if(!defined($hash) or !defined($d)); + return undef if(IsDisabled($hash->{NAME})); + my $name = $hash->{NAME}; - - return undef if(IsDisabled($name)); + + if($d->{NAME} eq "global") + { + if(grep(m/^(?:ATTR $name .*|DELETEATTR $name .*|INITIALIZED|REREADCFG)$/, @{$d->{CHANGED}})) + { + Log 3, "checked"; + # delete all outdated calls according to attribute list-type, internal-number-filter and number-of-calls + FB_CALLLIST_cleanupList($hash); + + # Inform all FHEMWEB clients + FB_CALLLIST_updateFhemWebClients($hash); + + # save current list state to file/configDB + FB_CALLLIST_saveList($hash); + } + return undef; + } my $fb = $d->{NAME}; - if ($fb ne $hash->{FB}) - { - return undef; - } - - return if(!grep(m/^event:/, @{$d->{CHANGED}})); + return undef if($fb ne $hash->{FB}); + return undef if(!grep(m/^event:/, @{$d->{CHANGED}})); my $event = ReadingsVal($fb, "event", undef); my $call_id = ReadingsVal($fb, "call_id", undef); Log3 $name, 4, "FB_CALLLIST ($name) - start processing event $event for Call-ID $call_id"; - if(exists($hash->{helper}{LAST_EVENT}) and exists($hash->{helper}{LAST_CALL_ID}) and $event eq $hash->{helper}{LAST_EVENT} and $call_id eq $hash->{helper}{LAST_CALL_ID}) { Log3 $name, 4, "FB_CALLLIST ($name) - already processed event $event for Call-ID $call_id, skipping..."; @@ -353,7 +346,6 @@ sub FB_CALLLIST_Notify($$) $data->{direction} = ReadingsVal($fb, "direction", undef); $data->{running_call} = 1; $data->{call_id} = $call_id; - $data->{last_event} = $event; if($data->{direction} eq "outgoing") { @@ -377,7 +369,6 @@ sub FB_CALLLIST_Notify($$) if($event eq "connect") { $data->{internal_connection} = ReadingsVal($fb, "internal_connection", undef) if($data->{direction} eq "incoming"); - $data->{last_event} = $event; Log3 $name, 5, "FB_CALLLIST ($name) - processed connect event for call id $call_id"; } @@ -391,14 +382,13 @@ sub FB_CALLLIST_Notify($$) $data->{missed_call} = 1; } - $data->{last_event} = $event; - delete($data->{running_call}) if(defined($data->{running_call})); Log3 $name, 5, "FB_CALLLIST ($name) - processed disconnect event for call id $call_id"; } - + $data->{last_event} = $event; + # clean up the list FB_CALLLIST_cleanupList($hash); @@ -453,7 +443,7 @@ sub FB_CALLLIST_cleanupList($) @list = grep { ($hash->{helper}{DATA}{$_}{direction} ne "outgoing") or ($hash->{helper}{DATA}{$_}{direction} eq "outgoing" and ++$count > $limit) } sort {$b <=> $a} keys %{$hash->{helper}{DATA}} if($listtype eq "outgoing"); - @list = grep { ((not $hash->{helper}{DATA}{$_}{running_call}) and (not $hash->{helper}{DATA}{$_}{missed_call}) or $hash->{helper}{DATA}{$_}{direction} eq "outgoing") or ($hash->{helper}{DATA}{$_}{direction} eq "incoming" and $hash->{helper}{DATA}{$_}{missed_call} and ++$count > $limit) } sort {$b <=> $a} keys %{$hash->{helper}{DATA}} if($listtype eq "missed-calls"); + @list = grep { ($hash->{helper}{DATA}{$_}{direction} eq "outgoing") or (!$hash->{helper}{DATA}{$_}{running_call} and not (((!$hash->{helper}{DATA}{$_}{missed_call} and AttrVal($name, "answMachine-is-missed-call", "0") eq "1" and $hash->{helper}{DATA}{$_}{internal_connection} =~ /^Answering_Machine/) or $hash->{helper}{DATA}{$_}{missed_call}) and not ++$count > $limit)) } sort {$b <=> $a} keys %{$hash->{helper}{DATA}} if($listtype eq "missed-calls"); @list = grep { (not $hash->{helper}{DATA}{$_}{running_call}) and ++$count > $limit } sort {$b <=> $a} keys %{$hash->{helper}{DATA}} if($listtype eq "completed"); @@ -513,7 +503,6 @@ sub FB_CALLLIST_returnIcon($$$) my $result = FW_makeImage($icon_name); - return $result if($result ne $icon_name); return $text; } @@ -562,7 +551,7 @@ sub FB_CALLLIST_returnCallState($$;$) $state = FB_CALLLIST_returnIcon($hash, "incoming.done", $state) if($icons and not $data->{missed_call}); $state = FB_CALLLIST_returnIcon($hash, "incoming.missed", $state) if($icons and $data->{missed_call}); } - elsif($data->{direction} eq "incoming" and exists($data->{internal_connection}) and $data->{internal_connection} =~ /Answering_Machine/) + elsif($data->{direction} eq "incoming" and exists($data->{internal_connection}) and $data->{internal_connection} =~ /^Answering_Machine/) { $state = "=> O_O"; $state = FB_CALLLIST_returnIcon($hash,"incoming.tam", $state) if($icons); @@ -600,7 +589,7 @@ sub FB_CALLLIST_list2html($;$) my $name = $hash->{NAME}; my $alias = AttrVal($hash->{NAME}, "alias", $hash->{NAME}); - my $create_readings = AttrVal($hash->{NAME}, "create-readings",0); + my $create_readings = AttrVal($hash->{NAME}, "create-readings","0"); my $td_style = 'style="padding-left:6px;padding-right:6px;"'; my @json_output = (); @@ -641,7 +630,6 @@ sub FB_CALLLIST_list2html($;$) @list = grep { !$hash->{helper}{DATA}{$_}{running_call} } @list; } - foreach my $index (@list) { my $data = \%{$hash->{helper}{DATA}{$index}}; @@ -662,7 +650,7 @@ sub FB_CALLLIST_list2html($;$) push @json_output, FB_CALLLIST_returnOrderedJSONOutput($hash, $line); - FB_CALLLIST_updateReadings($hash, $line) if($to_json and $create_readings); + FB_CALLLIST_updateReadings($hash, $line) if($to_json and $create_readings eq "1"); $ret .= FB_CALLLIST_returnOrderedHTMLOutput($hash, $line, 'number="'.$count.'" class="fbcalllist '.($count % 2 == 1 ? "odd" : "even").'"', 'class="fbcalllist" '.$td_style); $count++; } @@ -899,11 +887,8 @@ sub FB_CALLLIST_updateReadings($$) } readingsEndUpdate($hash, 1); - - } - ##################################### # Check, if a given internal number matches the configured internal-number-filter (if set). returns true if number matches sub FB_CALLLIST_checkForInternalNumberFilter($$) @@ -935,6 +920,8 @@ sub FB_CALLLIST_updateFhemWebClients($) { my ($hash) = @_; my $name = $hash->{NAME}; + + return undef unless($init_done); if(exists($hash->{helper}{DATA}) and (scalar keys %{$hash->{helper}{DATA}}) > 0) { @@ -973,7 +960,8 @@ sub FB_CALLLIST_updateFhemWebClients($) } } - +##################################### +# returns the table header in the configured language sub FB_CALLLIST_returnTableHeader($) { my ($hash) = @_; @@ -1099,6 +1087,11 @@ sub FB_CALLLIST_returnTableHeader($) If enabled, for all visible calls in the list, readings and events will be created. It is recommended to set the attribute event-on-change-reading to .* (all readings), to reduce the amount of generated readings for certain call events.

Possible values: 0 => no readings will be created, 1 => readings and events will be created.
Default Value is 0 (no readings will be created)

+
  • answMachine-is-missed-call 0,1
  • + If activated, a incoming call, which is answered by an answering machine, will be treated as a missed call. This is only relevant if list-type is set to "missed-call". +

    + Possible values: 0 => disabled, 1 => enabled (answering machine calls will be treated as "missed call").
    + Default Value is 0 (disabled)

  • number-of-calls 1..20
  • Defines the maximum number of displayed call entries in the list.

    Default Value is 5 calls

    @@ -1296,6 +1289,11 @@ sub FB_CALLLIST_returnTableHeader($) Es wird empfohlen das Attribut event-on-change-reading auf den Wert .* zu stellen um die hohe Anzahl an Events in bestimmten Fällen zu minimieren.

    Mögliche Werte: 0 => keine Readings erstellen, 1 => Readings und Events werden erzeugt.
    Standardwert ist 0 (keine Readings erstellen)

    +
  • answMachine-is-missed-call 0,1
  • + Sofern aktiviert, werden Anrufe, welche durch einen internen Anrufbeantworter beantwortet werden, als "verpasster Anruf" gewertet. Diese Funktionalität ist nur relevant, wenn list-type auf "missed-call" gesetzt ist. +

    + Mögliche Werte: 0 => deaktiviert, 1 => aktiviert (Anrufbeantworter gilt als "verpasster Anruf").
    + Standardwert ist 0 (deaktiviert)

  • number-of-calls 1..20
  • Setzt die maximale Anzahl an Einträgen in der Anrufliste. Sollte die Anrufliste voll sein, wird das älteste Gespräch gelöscht.

    Standardwert sind 5 Einträge