diff --git a/fhem/CHANGED b/fhem/CHANGED index 59f7e4af3..8782de870 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,8 @@ # 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 "expire-calls-after" to automatically + delete call entries after a certain time frame. See commandref + for details and syntax. - feature: FB_CALLLIST: new reading "numberOfCalls" which shows the number of shown call entries. - bugfix: 00_SIGNALduino: updated firmware to 3.2.0-hf1 diff --git a/fhem/FHEM/72_FB_CALLLIST.pm b/fhem/FHEM/72_FB_CALLLIST.pm index 79ab85932..4ca3caf66 100755 --- a/fhem/FHEM/72_FB_CALLLIST.pm +++ b/fhem/FHEM/72_FB_CALLLIST.pm @@ -44,6 +44,7 @@ FB_CALLLIST_Initialize($) $hash->{RenameFn} = "FB_CALLLIST_Rename"; $hash->{DeleteFn} = "FB_CALLLIST_Delete"; $hash->{AttrFn} = "FB_CALLLIST_Attr"; + $hash->{UndefFn} = "FB_CALLLIST_Undef"; $hash->{AttrList} = "number-of-calls:1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 ". "internal-number-filter ". "icon-mapping ". @@ -61,6 +62,7 @@ FB_CALLLIST_Initialize($) "number-cmd ". "disabledForIntervals ". "do_not_notify:0,1 ". + "expire-calls-after ". "no-heading:0,1 ". "no-table-header:0,1 ". $readingFnAttributes; @@ -201,7 +203,14 @@ sub FB_CALLLIST_Attr($@) { return "invalid external mapping table: $value"; } - } + } + elsif($attrib eq "expire-calls-after") + { + if($value !~ /^\s*\d+(?:\.\d+)?(?:\s+(?:minute|hour|day|month|year)s?)?\s*$/i) + { + return "not a valid time frame value. See commandref for the correct syntax."; + } + } } elsif($cmd eq "del") { @@ -275,6 +284,15 @@ sub FB_CALLLIST_Rename($$) return undef; } +##################################### +# If device is deleted or rereadcfg is executed +sub FB_CALLLIST_Undef($$) +{ + my ($hash, $name) = @_; + + RemoveInternalTimer($name, "FB_CALLLIST_deleteExpiredCalls"); +} + ##################################### # NotifyFn is trigger upon changes on FB_CALLMONITOR device. Imports the call data into call list sub FB_CALLLIST_Notify($$) @@ -390,6 +408,7 @@ sub FB_CALLLIST_Notify($$) if($event eq "disconnect" ) { $data->{call_duration} = ReadingsVal($fb, "call_duration", undef); + $data->{finished} = gettimeofday(); if($data->{last_event} =~ /^call|ring$/) { @@ -439,8 +458,8 @@ sub FB_CALLLIST_cleanupList($) my ($hash) = @_; my $name = $hash->{NAME}; - my $limit = int(AttrVal($hash->{NAME}, "number-of-calls", 5)); - my $listtype = AttrVal($hash->{NAME}, "list-type", "all"); + my $limit = int(AttrVal($name, "number-of-calls", 5)); + my $listtype = AttrVal($name, "list-type", "all"); my $count = 0; my $index; @@ -479,7 +498,9 @@ sub FB_CALLLIST_cleanupList($) { Log3 $name, 5, "FB_CALLLIST ($name) - deleting old call $index"; delete($hash->{helper}{DATA}{$index}) if(exists($hash->{helper}{DATA}{$index})); - } + } + + FB_CALLLIST_deleteExpiredCalls($hash); } else { @@ -487,6 +508,93 @@ sub FB_CALLLIST_cleanupList($) } } +##################################### +# check if calls are expired and delete them +sub FB_CALLLIST_deleteExpiredCalls($;$) +{ + my ($hash, $inform) = @_; + + if(ref($hash) ne "HASH") + { + ($hash, $inform) = ($defs{$hash}, 1); + } + + my $name = $hash->{NAME}; + my $expireCallSeconds = AttrVal($name, "expire-calls-after", 0); + + RemoveInternalTimer($name, "FB_CALLLIST_deleteExpiredCalls"); + + if($expireCallSeconds !~ /^\d+(?:\.\d+)?$/) + { + if($expireCallSeconds =~ /^\s*(\d+(?:\.\d+)?)\s+minutes?\s*$/i) + { + $expireCallSeconds = $1 * 60; + } + elsif($expireCallSeconds =~ /^\s*(\d+(?:\.\d+)?)\s+hours?\s*$/i) + { + $expireCallSeconds = $1 * 3600; + } + elsif($expireCallSeconds =~ /^\s*(\d+(?:\.\d+)?)\s+days?\s*$/i) + { + $expireCallSeconds = $1 * 86400; + } + elsif($expireCallSeconds =~ /^\s*(\d+(?:\.\d+)?)\s+weeks?\s*$/i) + { + $expireCallSeconds = $1 * 86400 * 7; + } + elsif($expireCallSeconds =~ /^\s*(\d+(?:\.\d+)?)\s+months?\s*$/i) + { + $expireCallSeconds = $1 * 86400 * 30; + } + elsif($expireCallSeconds =~ /^\s*(\d+(?:\.\d+)?)\s+year?\s*$/i) + { + $expireCallSeconds = $1 * 86400 * 356; + } + else + { + $expireCallSeconds = 0; + } + } + + # delete expired calls if activated + if($expireCallSeconds =~ /^\d+(?:\.\d+)?$/ and $expireCallSeconds > 0) + { + my @list = grep { !($hash->{helper}{DATA}{$_}{running_call}) and ((exists($hash->{helper}{DATA}{$_}{finished}) ? $hash->{helper}{DATA}{$_}{finished} : $_) < (gettimeofday - $expireCallSeconds)) } keys %{$hash->{helper}{DATA}}; + + if(@list) + { + # delete the collected list of expired calls + foreach my $index (@list) + { + Log3 $name, 5, "FB_CALLLIST ($name) - deleting expired call $index"; + delete($hash->{helper}{DATA}{$index}) if(exists($hash->{helper}{DATA}{$index})); + } + } + + my ($oldest) = sort {$b <=> $a} map {(exists($hash->{helper}{DATA}{$_}{finished}) ? $hash->{helper}{DATA}{$_}{finished} : $_) } grep { !$hash->{helper}{DATA}{$_}{running_call} } keys %{$hash->{helper}{DATA}}; + + if(defined($oldest)) + { + my $diff = $expireCallSeconds - (gettimeofday() - $oldest); + + if($diff > 0) + { + Log3 $name, 4, "FB_CALLLIST ($name) - oldest call $oldest expires in $diff seconds, scheduling timer..."; + InternalTimer(gettimeofday()+$diff+1, "FB_CALLLIST_deleteExpiredCalls", $name); + } + } + + if($inform) + { + # Inform all FHEMWEB clients + FB_CALLLIST_updateFhemWebClients($hash); + + # save current list state to file/configDB + FB_CALLLIST_saveList($hash); + } + } +} + ##################################### # returns the icon depending on icon mapping sub FB_CALLLIST_returnIcon($$$) @@ -1095,12 +1203,38 @@ sub FB_CALLLIST_returnTableHeader($) Attributes


+
  • icon-mapping <hash>
  • Defines a custom mapping of call states to custom icons. The mapping is performed in a hash table.

    e.g.
    @@ -1172,18 +1289,74 @@ sub FB_CALLLIST_returnTableHeader($)
  • incoming.tam => phone_answering@blue


  • - Default Value: empty (no mapping is performed) -

    -
  • connection-mapping <hash>
  • - Defines a custom mapping of connection names to custom values. The mapping is performed in a hash table.

    + Default Value: empty (no mapping is performed)

    + +
  • internal-number-filter <hash>
  • + This attribute accepts a list of comma seperated internal numbers for + filtering incoming or outgoing calls by a specific list of internal numbers + or a hash for filtering and mapping numbers to text.
    +
    e.g.

    - The mapped name will be displayed in the table instead of the original value from FB_CALLMONITOR. + attr <name> internal-number-filter 304050,304060

    + attr <name> internal-number-filter {'304050' => 'business', '304060' => 'private'}
    + +
    Important: Depending on your provider, the internal number can contain a location area code. + The internal-number-filter must contain the same number as it is displayed in the call list. + This can be with or without location area code depending on your provider.

    - Default Value: empty (no mapping is performed) + If this attribute is set, only the configured internal numbers will be shown in the list. All calls which are not taken via the configured internal numbers, were not be shown in the call list.

    + Default Value: empty (all internal numbers should be used, no exclusions and no mapping is performed) +

    + +
  • language en,de
  • + Defines the language of the table header, some keywords and the timestamp format. You need to have the selected locale installed and available in your operating system.

    + Possible values: en => English , de => German
    + Default Value is en (English)

    + +
  • list-type all,incoming,outgoing,missed-calls,completed,active
  • + Defines what type of calls should be displayed in the list.

    + Default Value is "all"

    + +
  • list-order descending,ascending
  • + Defines whether the newest call should be on top of the list (descending) or on the bottom of the list (ascending).

    + Default Value is descending (first call at top of the list)

    + +
  • no-heading 0,1
  • + If activated the headline with a link to the detail page of the current definition will be hidden.

    + Possible values: 0 => the heading line will be shown , 1 => the heading line will not be shown
    + Default Value is 0 (the heading line will be shown)

    + +
  • no-table-header 0,1
  • + If activated the table header containing the name of each column for the current definition will be hidden.

    + Possible values: 0 => the table header will be shown , 1 => the table header will not be shown
    + Default Value is 0 (the table header will be shown)

    + +
  • number-cmd <command>
  • + Can be set, to execute a specific FHEM command, when clicking on a number in the list. The value can be any valid FHEM command or Perl code (in curly brackets: { ... } ). + The placeholder $NUMBER will be replaced with the current external number of each row. +

    + This can be used for example to initiate a call to this number. + e.g.:

    + +
    + If not set, no link will be shown in the list.

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

    + Default Value is 5 calls

    + +
  • show-icons 0,1
  • + Normally the call state is shown with icons (used from the openautomation icon set). + You need to have openautomation in your iconpath attribute of your appropriate FHEMWEB definition to use this icons. + If you don't want to use icons you can deactivate them with this attribute.

    + Possible values: 0 => no icons , 1 => use icons
    + Default Value is 1 (use icons)

    +
  • time-format-string <string>
  • Defines a format string which should be used to format the timestamp values. It contains several placeholders for different elements of a date/time. @@ -1202,28 +1375,7 @@ sub FB_CALLLIST_returnTableHeader($) Please consult the manpage of strftime() or the documentation of your perl interpreter to find out more.

    Default value is "%a, %d %b %Y %H:%M:%S" ( = "Sun, 07 Jun 2015 12:50:09")

    -
  • language en,de
  • - Defines the language of the table header, some keywords and the timestamp format. You need to have the selected locale installed and available in your operating system.

    - Possible values: en => English , de => German
    - Default Value is en (English)

    -
  • number-cmd <command>
  • - Can be set, to execute a specific FHEM command, when clicking on a number in the list. The value can be any valid FHEM command or Perl code (in curly brackets: { ... } ). - The placeholder $NUMBER will be replaced with the current external number of each row. -

    - This can be used for example to initiate a call to this number. - e.g.:

    - -
    - If not set, no link will be shown in the list.

    -
  • show-icons 0,1
  • - Normally the call state is shown with icons (used from the openautomation icon set). - You need to have openautomation in your iconpath attribute of your appropriate FHEMWEB definition to use this icons. - If you don't want to use icons you can deactivate them with this attribute.

    - Possible values: 0 => no icons , 1 => use icons
    - Default Value is 1 (use icons)

    +
  • visible-columns row,state,timestamp,name,number,internal,external,connection,duration
  • Defines the visible columns, as well as the order in which these columns are displayed in the call list (from left to right). Not all columns must be displayed, you can select only a subset of columns which will be displayed. @@ -1233,15 +1385,7 @@ sub FB_CALLLIST_returnTableHeader($)

    Possible values: a combination of row,state,timestamp,name,number,internal,external,connection,duration
    Default Value is "row,state,timestamp,name,number,internal,external,connection,duration" (show all columns)

    -
  • no-heading 0,1
  • - If activated the headline with a link to the detail page of the current definition will be hidden.

    - Possible values: 0 => the heading line will be shown , 1 => the heading line will not be shown
    - Default Value is 0 (the heading line will be shown)

    -
  • no-table-header 0,1
  • - If activated the table header containing the name of each column for the current definition will be hidden.

    - Possible values: 0 => the table header will be shown , 1 => the table header will not be shown
    - Default Value is 0 (the table header will be shown)

    - +
    Generated Events:

    @@ -1311,74 +1455,22 @@ sub FB_CALLLIST_returnTableHeader($) Attributes


    Generierte Events: