FB_CALLIST: update only the changed items via inform mechanism. don't update all items allways. (Forum: #80376)
git-svn-id: https://svn.fhem.de/fhem/trunk@15880 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
@@ -334,7 +334,7 @@ sub FB_CALLLIST_Notify($$)
|
||||
if(grep(m/^(?:ATTR $name icon-mapping .*|INITIALIZED|REREADCFG)$/, @{$events}))
|
||||
{
|
||||
my $value = AttrVal($name,"icon-mapping","");
|
||||
|
||||
|
||||
$value =~ s/"([^"]+?)"/'$1'/g; # workaround for array variable interpretation
|
||||
|
||||
my $table = eval($value);
|
||||
@@ -434,7 +434,7 @@ sub FB_CALLLIST_Notify($$)
|
||||
$hash->{helper}{DATA}{$timestamp} = undef;
|
||||
|
||||
$data = \%{$hash->{helper}{DATA}{$timestamp}};
|
||||
|
||||
$data->{internal_index} = $timestamp;
|
||||
$data->{external_number} = ReadingsVal($fb, "external_number", undef);
|
||||
$data->{external_name} = ReadingsVal($fb, "external_name", undef);
|
||||
$data->{external_connection} = ReadingsVal($fb, "external_connection", undef);
|
||||
@@ -489,8 +489,8 @@ sub FB_CALLLIST_Notify($$)
|
||||
# clean up the list
|
||||
FB_CALLLIST_cleanupList($hash);
|
||||
|
||||
# Inform all FHEMWEB clients
|
||||
FB_CALLLIST_updateFhemWebClients($hash);
|
||||
# inform about changes of current call index
|
||||
FB_CALLLIST_updateOneItemInFHEMWEB($hash,$data->{internal_index});
|
||||
|
||||
# save current list state to file/configDB
|
||||
FB_CALLLIST_saveList($hash);
|
||||
@@ -561,6 +561,7 @@ sub FB_CALLLIST_cleanupList($)
|
||||
foreach $index (@list)
|
||||
{
|
||||
Log3 $name, 5, "FB_CALLLIST ($name) - deleting old call $index";
|
||||
FW_directNotify($name, "{\"action\":\"delete\",\"index\":\"$index\"}", 1) if(defined($FW_ME));
|
||||
delete($hash->{helper}{DATA}{$index});
|
||||
}
|
||||
|
||||
@@ -576,11 +577,11 @@ sub FB_CALLLIST_cleanupList($)
|
||||
# check if calls are expired and delete them
|
||||
sub FB_CALLLIST_deleteExpiredCalls($;$)
|
||||
{
|
||||
my ($hash, $inform) = @_;
|
||||
my ($hash, $save) = @_;
|
||||
|
||||
if(ref($hash) ne "HASH")
|
||||
{
|
||||
($hash, $inform) = ($defs{$hash}, 1);
|
||||
($hash, $save) = ($defs{$hash}, 1);
|
||||
}
|
||||
|
||||
my $name = $hash->{NAME};
|
||||
@@ -631,6 +632,10 @@ sub FB_CALLLIST_deleteExpiredCalls($;$)
|
||||
foreach my $index (@list)
|
||||
{
|
||||
Log3 $name, 5, "FB_CALLLIST ($name) - deleting expired call $index";
|
||||
|
||||
# Inform Web Client
|
||||
FW_directNotify($name, "{\"action\":\"delete\",\"index\":\"$index\"}", 1) if(defined($FW_ME));
|
||||
|
||||
delete($hash->{helper}{DATA}{$index});
|
||||
}
|
||||
}
|
||||
@@ -648,14 +653,8 @@ sub FB_CALLLIST_deleteExpiredCalls($;$)
|
||||
}
|
||||
}
|
||||
|
||||
if($inform)
|
||||
{
|
||||
# Inform all FHEMWEB clients
|
||||
FB_CALLLIST_updateFhemWebClients($hash);
|
||||
|
||||
# save current list state to file/configDB
|
||||
FB_CALLLIST_saveList($hash);
|
||||
}
|
||||
# save current list state to file/configDB
|
||||
FB_CALLLIST_saveList($hash) if($save);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -771,50 +770,101 @@ sub FB_CALLLIST_getListItems($)
|
||||
my ($hash) = @_;
|
||||
|
||||
my $name = $hash->{NAME};
|
||||
my @list = FB_CALLLIST_createOrderedIndexList($hash);
|
||||
my @result;
|
||||
|
||||
if(exists($hash->{helper}{DATA}) and (scalar keys %{$hash->{helper}{DATA}}) > 0)
|
||||
if(@list)
|
||||
{
|
||||
my $count = 0;
|
||||
|
||||
my @list = sort { (AttrVal($name, "list-order","descending") eq "descending") ? $b <=> $a : $a <=> $b } keys %{$hash->{helper}{DATA}};
|
||||
|
||||
if(AttrVal($hash->{NAME}, "list-type", "all") eq "missed-calls")
|
||||
{
|
||||
@list = grep { !$hash->{helper}{DATA}{$_}{running_call} } @list;
|
||||
}
|
||||
|
||||
if(AttrVal($hash->{NAME}, "list-type", "all") eq "completed")
|
||||
{
|
||||
@list = grep { !$hash->{helper}{DATA}{$_}{running_call} } @list;
|
||||
}
|
||||
|
||||
foreach my $index (@list)
|
||||
{
|
||||
$count++;
|
||||
my $data = \%{$hash->{helper}{DATA}{$index}};
|
||||
push @result, FB_CALLLIST_index2line($hash, $index);
|
||||
}
|
||||
}
|
||||
|
||||
my $number = $data->{external_number};
|
||||
return @result;
|
||||
}
|
||||
|
||||
my $line = {
|
||||
#####################################
|
||||
# creates a line hash from index
|
||||
sub FB_CALLLIST_index2line($$)
|
||||
{
|
||||
my ($hash, $index) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
if(exists($hash->{helper}{DATA}{$index}))
|
||||
{
|
||||
my $data = \%{$hash->{helper}{DATA}{$index}};
|
||||
my $count = FB_CALLLIST_getItemLineNumberFromIndex($hash,$index);
|
||||
my $line = {
|
||||
index => $index,
|
||||
line => $count, # internal line identifier for JavaScript, must be present
|
||||
row => $count, # column "row" to display or not
|
||||
state => FB_CALLLIST_returnCallState($hash, $index),
|
||||
timestamp => strftime(AttrVal($name, "time-format-string", "%a, %d %b %Y %H:%M:%S"), localtime($index)),
|
||||
name => ($data->{external_name} eq "unknown" ? "-" : $data->{external_name}),
|
||||
number => $number,
|
||||
number => $data->{external_number},
|
||||
external => ($data->{external_connection} ? ((exists($hash->{helper}{EXTERNAL_MAP}) and exists($hash->{helper}{EXTERNAL_MAP}{$data->{external_connection}})) ? $hash->{helper}{EXTERNAL_MAP}{$data->{external_connection}} : $data->{external_connection} ) : "-"),
|
||||
internal => ((exists($hash->{helper}{INTERNAL_FILTER}) and exists($hash->{helper}{INTERNAL_FILTER}{$data->{internal_number}})) ? $hash->{helper}{INTERNAL_FILTER}{$data->{internal_number}} : $data->{internal_number} ),
|
||||
connection => ($data->{internal_connection} ? ((exists($hash->{helper}{CONNECTION_MAP}) and exists($hash->{helper}{CONNECTION_MAP}{$data->{internal_connection}})) ? $hash->{helper}{CONNECTION_MAP}{$data->{internal_connection}} : $data->{internal_connection} ) : "-"),
|
||||
duration => FB_CALLLIST_formatDuration($hash, $index)
|
||||
};
|
||||
};
|
||||
return $line;
|
||||
}
|
||||
|
||||
push @result, $line;
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
# creates an array of data indices in order to display
|
||||
sub FB_CALLLIST_createOrderedIndexList($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
my $name = $hash->{NAME};
|
||||
my @list;
|
||||
|
||||
if(exists($hash->{helper}{DATA}) and (scalar keys %{$hash->{helper}{DATA}}) > 0)
|
||||
{
|
||||
my $count = 0;
|
||||
|
||||
@list = sort { (AttrVal($name, "list-order","descending") eq "descending") ? $b <=> $a : $a <=> $b } keys %{$hash->{helper}{DATA}};
|
||||
|
||||
if(AttrVal($name, "list-type", "all") eq "missed-calls")
|
||||
{
|
||||
@list = grep { !$hash->{helper}{DATA}{$_}{running_call} } @list;
|
||||
}
|
||||
|
||||
if(AttrVal($name, "list-type", "all") eq "completed")
|
||||
{
|
||||
@list = grep { !$hash->{helper}{DATA}{$_}{running_call} } @list;
|
||||
}
|
||||
}
|
||||
|
||||
return @result;
|
||||
return @list;
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
# get formated list items to display
|
||||
sub FB_CALLLIST_getItemLineNumberFromIndex($$)
|
||||
{
|
||||
my ($hash,$index) = @_;
|
||||
|
||||
my $name = $hash->{NAME};
|
||||
my @list = FB_CALLLIST_createOrderedIndexList($hash);
|
||||
|
||||
if(@list)
|
||||
{
|
||||
my $count = 0;
|
||||
|
||||
foreach my $tmp (@list)
|
||||
{
|
||||
$count++;
|
||||
return $count if($tmp eq $index);
|
||||
}
|
||||
}
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
#####################################
|
||||
@@ -863,14 +913,7 @@ sub FB_CALLLIST_list2html($)
|
||||
{
|
||||
foreach $line (@item_list)
|
||||
{
|
||||
if(defined(my $cmd = AttrVal($name, "number-cmd", undef)))
|
||||
{
|
||||
$cmd =~ s/\$NUMBER/$line->{number}/g;
|
||||
|
||||
$line->{number} = '<a href=\'#\' onclick="FW_cmd(FW_root+\'?XHR=1&cmd='.urlEncode($cmd).'\');return false;">'.$line->{number}."</a>";
|
||||
}
|
||||
|
||||
$ret .= FB_CALLLIST_returnOrderedHTMLOutput($hash, $line, 'number="'.$line->{line}.'" class="fbcalllist '.($line->{line} % 2 == 1 ? "odd" : "even").'"', 'class="fbcalllist" '.$td_style);
|
||||
$ret .= FB_CALLLIST_returnOrderedHTMLOutput($hash, $line, 'number="'.$line->{line}.'" index="'.$line->{index}.'" class="fbcalllist item '.($line->{line} % 2 == 1 ? "odd" : "even").'"', 'class="fbcalllist cell" '.$td_style);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -897,7 +940,6 @@ sub FB_CALLLIST_list2html($)
|
||||
|
||||
setlocale(LC_ALL, $old_locale);
|
||||
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
@@ -935,13 +977,6 @@ sub FB_CALLLIST_list2json($)
|
||||
{
|
||||
FB_CALLLIST_updateReadings($hash, $line) if($create_readings eq "1");
|
||||
|
||||
if(defined(my $cmd = AttrVal($name, "number-cmd", undef)))
|
||||
{
|
||||
$cmd =~ s/\$NUMBER/$line->{number}/g;
|
||||
|
||||
$line->{number} = '<a href=\'#\' onclick="FW_cmd(FW_root+\'?XHR=1&cmd='.urlEncode($cmd).'\');return false;">'.$line->{number}."</a>";
|
||||
}
|
||||
|
||||
push @json_output, FB_CALLLIST_returnOrderedJSONOutput($hash, $line);
|
||||
}
|
||||
}
|
||||
@@ -969,7 +1004,6 @@ sub FB_CALLLIST_list2json($)
|
||||
return @json_output;
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
# format duration in seconds into hh:mm:ss
|
||||
sub FB_CALLLIST_formatDuration($$)
|
||||
@@ -1106,7 +1140,7 @@ sub FB_CALLLIST_loadList($)
|
||||
sub FB_CALLLIST_returnOrderedHTMLOutput($$$$)
|
||||
{
|
||||
|
||||
my ($hash,$line, $tr_additions, $td_additions) = @_;
|
||||
my ($hash, $line, $tr_additions, $td_additions) = @_;
|
||||
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
@@ -1114,6 +1148,13 @@ sub FB_CALLLIST_returnOrderedHTMLOutput($$$$)
|
||||
|
||||
my @ret = ();
|
||||
|
||||
if(defined(my $cmd = AttrVal($name, "number-cmd", undef)) and $line->{number} =~/\d$/)
|
||||
{
|
||||
$cmd =~ s/\$NUMBER/$line->{number}/g;
|
||||
|
||||
$line->{number} = '<a href=\'#\' onclick="FW_cmd(FW_root+\'?XHR=1&cmd='.urlEncode($cmd).'\');return false;">'.$line->{number}."</a>";
|
||||
}
|
||||
|
||||
push @ret, '<tr align="center" '.$tr_additions.'>';
|
||||
|
||||
foreach my $col (@order)
|
||||
@@ -1136,6 +1177,13 @@ sub FB_CALLLIST_returnOrderedJSONOutput($$)
|
||||
|
||||
my @ret = ();
|
||||
|
||||
if(defined(my $cmd = AttrVal($name, "number-cmd", undef)) and $line->{number} =~/\d$/)
|
||||
{
|
||||
$cmd =~ s/\$NUMBER/$line->{number}/g;
|
||||
|
||||
$line->{number} = '<a href=\'#\' onclick="FW_cmd(FW_root+\'?XHR=1&cmd='.urlEncode($cmd).'\');return false;">'.$line->{number}."</a>";
|
||||
}
|
||||
|
||||
push @ret, '"line":"'.$line->{line}.'"';
|
||||
|
||||
foreach my $col (@order)
|
||||
@@ -1212,14 +1260,12 @@ sub FB_CALLLIST_updateFhemWebClients($)
|
||||
|
||||
# inform all FHEMWEB clients about changes
|
||||
my $count = 0;
|
||||
|
||||
foreach my $line (@list)
|
||||
{
|
||||
FW_directNotify($name, $line, 1);
|
||||
FW_directNotify($name, "{\"action\":\"updateItem\",\"item\":$line}", 1);
|
||||
$count++;
|
||||
}
|
||||
|
||||
# send the current row count to ensure all other rows are deleted via JS
|
||||
FW_directNotify($name,"max-lines,$count", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1239,10 +1285,25 @@ sub FB_CALLLIST_updateFhemWebClients($)
|
||||
$string = "empty";
|
||||
}
|
||||
|
||||
FW_directNotify($name, "clear,$additional_columns,$string", 1);
|
||||
FW_directNotify($name, "{\"action\":\"clear\",\"content\":\"$string\"}", 1);
|
||||
}
|
||||
}
|
||||
|
||||
#####################################
|
||||
# update one particular item of the call list of all connected FHEMWEB clients via inform mechanism
|
||||
sub FB_CALLLIST_updateOneItemInFHEMWEB($$)
|
||||
{
|
||||
my ($hash, $index) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $json = FB_CALLLIST_returnOrderedJSONOutput($hash, FB_CALLLIST_index2line($hash,$index));
|
||||
|
||||
FW_directNotify($name, "{\"action\":\"update\",\"index\":\"$index\",\"order\":\"".AttrVal($name, "list-order","descending")."\",\"item\":$json}", 1);
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
#####################################
|
||||
# returns the table header in the configured language
|
||||
sub FB_CALLLIST_returnTableHeader($)
|
||||
|
||||
@@ -14,69 +14,85 @@ $(function () {
|
||||
function FW_processCallListUpdate(data)
|
||||
{
|
||||
var table = $(this).find("table.fbcalllist").first();
|
||||
|
||||
// clear the list if data starts with "clear"
|
||||
if(/^clear/.test(data))
|
||||
var json_data = jQuery.parseJSON(data)
|
||||
|
||||
// clear the list
|
||||
if(json_data.action == "clear")
|
||||
{
|
||||
// if the table isn't already empty
|
||||
if(!table.find("tr[name=empty]").length)
|
||||
{
|
||||
var tmp = data.split(",");
|
||||
|
||||
table.find("tr[number]").remove();
|
||||
table.append("<tr align=\"center\" name=\"empty\"><td style=\"padding:10px;\" colspan=\""+tmp[1]+"\"><i>"+tmp[2]+"</i></td></tr>");
|
||||
table.append("<tr align=\"center\" name=\"empty\"><td style=\"padding:10px;\" colspan=\""+table.find("tr.header td").length+"\"><i>"+json_data.content+"</i></td></tr>");
|
||||
}
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
// clear all lines greater than max-lines (e.g. after activate a filter statement)
|
||||
if(/^max-lines/.test(data))
|
||||
|
||||
// remove deleted item
|
||||
if(json_data.action == "delete")
|
||||
{
|
||||
var tmp = data.split(",");
|
||||
table.find("tr[number]").filter(function(index,obj) {return (parseInt($(obj).attr("number")) > parseInt(tmp[1]));}).remove();
|
||||
return;
|
||||
table.find("tr[index='"+json_data.index+"']").remove();
|
||||
FW_FbCalllistUpdateRowNumbers(table);
|
||||
return;
|
||||
}
|
||||
|
||||
// else it's JSON data with row updates
|
||||
var json_data = jQuery.parseJSON(data)
|
||||
|
||||
if(table.find("tr[number="+json_data.line+"]").length)
|
||||
|
||||
// update a item with new data
|
||||
if(json_data.action == "update")
|
||||
{
|
||||
$.each(json_data, function (key, val) {
|
||||
|
||||
if(key == "line")
|
||||
{ return true; }
|
||||
|
||||
FW_setCallListValue(table,json_data.line,key,val);
|
||||
});
|
||||
}
|
||||
else // add new tr row with the values)
|
||||
{
|
||||
// delete the empty tr row if it may exist
|
||||
table.find("tr[name=empty]").remove();
|
||||
|
||||
var new_tr = '<tr align="center" number="'+json_data.line+'" class="'+((json_data.line % 2) == 1 ? "odd" : "even")+'">';
|
||||
var style = "style=\"padding-left:6px;padding-right:6px;\"";
|
||||
|
||||
|
||||
// create the corresponding <td> tags with the received data
|
||||
$.each(json_data, function (key, val) {
|
||||
if(key == "line")
|
||||
{ return true; }
|
||||
new_tr += '<td name="'+key+'" '+style+'>'+val+'</td>';
|
||||
});
|
||||
|
||||
new_tr += "</tr>";
|
||||
|
||||
// insert new tr into table
|
||||
table.append(new_tr);
|
||||
if(table.find("tr[index='"+json_data.index+"']").length)
|
||||
{
|
||||
$.each(json_data.item, function (key, val) {
|
||||
|
||||
if(key == "index" || key == "line")
|
||||
{ return true; }
|
||||
|
||||
FW_setCallListValue(table,json_data.index,key,val);
|
||||
});
|
||||
}
|
||||
else // add new tr row with the values)
|
||||
{
|
||||
// delete the empty tr row if it may exist
|
||||
table.find("tr[name=empty]").remove();
|
||||
|
||||
var new_tr = '<tr align="center" number="'+json_data.item.line+'" index="'+json_data.index+'" class="fbcalllist item '+((json_data.line % 2) == 1 ? "odd" : "even")+'">';
|
||||
var style = "style=\"padding-left:6px;padding-right:6px;\"";
|
||||
|
||||
// create the corresponding <td> tags with the received data
|
||||
$.each(json_data.item, function (key, val) {
|
||||
if(key == "index" || key == "line")
|
||||
{ return true; }
|
||||
new_tr += '<td name="'+key+'" '+style+'>'+val+'</td>';
|
||||
});
|
||||
|
||||
new_tr += "</tr>";
|
||||
|
||||
// insert new tr into table
|
||||
if(json_data.order == "ascending")
|
||||
{
|
||||
table.append(new_tr);
|
||||
}
|
||||
else
|
||||
{
|
||||
table.find("tr.header").after(new_tr);
|
||||
}
|
||||
FW_FbCalllistUpdateRowNumbers(table);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function FW_setCallListValue(table,line,key,val)
|
||||
function FW_FbCalllistUpdateRowNumbers(table)
|
||||
{
|
||||
table.find("tr[number="+line+"] td[name="+key+"]").each(function(index, obj) {
|
||||
$(obj).html(val);
|
||||
count = 0;
|
||||
table.find("tr.item").each(function(index, obj) {
|
||||
$(obj).attr("number", ++count);
|
||||
$(obj).find("td[name='row']").html(count);
|
||||
});
|
||||
}
|
||||
|
||||
function FW_setCallListValue(table,index,key,val)
|
||||
{
|
||||
table.find("tr[index='"+index+"'] td[name="+key+"]").each(function(index, obj) {
|
||||
$(obj).html(val);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user