diff --git a/fhem/docs/commandref.html b/fhem/docs/commandref.html
index e039bf531..6364b5602 100644
--- a/fhem/docs/commandref.html
+++ b/fhem/docs/commandref.html
@@ -6375,7 +6375,12 @@ href="http://www.elv.de/output/controller.aspx?cid=74&detail=10&detail2=29870">U
-
+
+
longpoll
+ Affects devices states in the room overview only.
+ In this mode status update is refreshed more or less instantaneously,
+ and state change (on/off only) is done without requesting a complete
+ refresh from the server.
diff --git a/fhem/docs/fhem.html b/fhem/docs/fhem.html
index ed5bc2706..4b9d27243 100644
--- a/fhem/docs/fhem.html
+++ b/fhem/docs/fhem.html
@@ -120,8 +120,6 @@
iPhone frontends:
Fhemobile (native app),
-
- fhemgw,
dhs-computertechnik or
phyfhem
diff --git a/fhem/webfrontend/pgm2/01_FHEMWEB.pm b/fhem/webfrontend/pgm2/01_FHEMWEB.pm
index fe185e4d7..b4ecaecf7 100755
--- a/fhem/webfrontend/pgm2/01_FHEMWEB.pm
+++ b/fhem/webfrontend/pgm2/01_FHEMWEB.pm
@@ -62,10 +62,14 @@ my $FW_RETTYPE; # image/png or the like
my $FW_room; # currently selected room
my %FW_rooms; # hash of all rooms
my %FW_types; # device types, for sorting
-my $FW_wname; # Web instance name
+my $FW_wname; # Web instance
+my $FW_cname; # Current connection
my @FW_zoom; # "qday", "day","week","month","year"
my %FW_zoom; # the same as @FW_zoom
my %FW_hiddenroom; # hash of hidden rooms
+my $FW_longpoll;
+my $FW_inform;
+my $FW_XHR;
#####################################
@@ -78,10 +82,11 @@ FHEMWEB_Initialize($)
$hash->{AttrFn} = "FW_Attr";
$hash->{DefFn} = "FW_Define";
$hash->{UndefFn} = "FW_Undef";
+ $hash->{NotifyFn}= "FW_Notify";
$hash->{AttrList}= "loglevel:0,1,2,3,4,5,6 webname fwmodpath fwcompress " .
"plotmode:gnuplot,gnuplot-scroll,SVG plotsize refresh " .
"touchpad smallscreen plotfork basicAuth basicAuthMsg ".
- "stylesheet hiddenroom HTTPS";
+ "stylesheet hiddenroom HTTPS longpoll";
###############
# Initialize internal structures
@@ -207,9 +212,9 @@ FW_Read($)
}
$FW_wname = $hash->{SNAME};
+ $FW_cname = $name;
my $ll = GetLogLevel($FW_wname,4);
my $c = $hash->{CD};
-
if(!$zlib_loaded && $try_zlib && AttrVal($FW_wname, "fwcompress", 1)) {
$zlib_loaded = 1;
eval { require Compress::Zlib; };
@@ -229,10 +234,10 @@ FW_Read($)
# Data from HTTP Client
my $buf;
- my $ret = sysread($hash->{CD}, $buf, 1024);
+ my $ret = sysread($c, $buf, 1024);
if(!defined($ret) || $ret <= 0) {
- my $r = CommandDelete(undef, $name);
+ CommandDelete(undef, $name);
Log($ll, "Connection closed for $name");
return;
}
@@ -271,8 +276,9 @@ FW_Read($)
$hash->{INUSE} = 1;
my $cacheable = FW_AnswerCall($arg);
-
delete($hash->{INUSE});
+ return if($cacheable == -1); # Longpoll / inform request;
+
if(!$selectlist{$name}) { # removed by rereadcfg, reinsert
$selectlist{$name} = $hash;
$defs{$name} = $hash;
@@ -390,12 +396,31 @@ FW_AnswerCall($)
$FW_reldoc = "$FW_ME/commandref.html";
$FW_cmdret = $docmd ? fC($cmd) : "";
+
+ if($FW_inform) { # Longpoll header
+ $defs{$FW_cname}{inform} = $FW_room;
+ my $c = $defs{$FW_cname}{CD};
+ print $c "HTTP/1.1 200 OK\r\n",
+ "Content-Type: text/plain; charset=ISO-8859-1\r\n\r\n";
+ return -1;
+ }
+
+ if($FW_XHR) {
+ $FW_RETTYPE = "text/plain; charset=ISO-8859-1";
+ pO $FW_cmdret;
+ return 0;
+ }
+
FW_updateHashes();
if($cmd =~ m/^showlog /) {
FW_showLog($cmd);
return 0;
}
+ $FW_longpoll = (AttrVal($FW_wname, "longpoll", undef) &&
+ $FW_room &&
+ !$FW_detail);
+
if($cmd =~ m/^toweblink (.*)$/) {
my @aa = split(":", $1);
my $max = 0;
@@ -433,10 +458,12 @@ FW_AnswerCall($)
pO "" if($rf);
my $stylecss = ($FW_ss ? "style_smallscreen.css" :
$FW_tp ? "style_touchpad.css" : "style.css");
- $stylecss = AttrVal($FW_wname, "stylecss", $stylecss);
+ $stylecss = AttrVal($FW_wname, "stylesheet", $stylecss);
pO "";
pO ""
if($FW_plotmode eq "SVG");
+ pO ""
+ if($FW_longpoll);
pO "\n";
if($FW_cmdret) {
@@ -473,9 +500,11 @@ FW_digestCgi($)
my (%arg, %val, %dev);
my ($cmd, $c) = ("","","");
- $FW_detail = "";
%FW_pos = ();
$FW_room = "";
+ $FW_detail = "";
+ $FW_XHR = undef;
+ $FW_inform = undef;
$arg =~ s,^[?/],,;
foreach my $pv (split("&", $arg)) {
@@ -495,6 +524,8 @@ FW_digestCgi($)
if($p =~ m/^cmd\.(.*)$/) { $cmd = $v; $c= $1; }
if($p eq "pos") { %FW_pos = split(/[=;]/, $v); }
if($p eq "data") { $FW_data = $v; }
+ if($p eq "XHR") { $FW_XHR = 1; }
+ if($p eq "inform") { $FW_inform = $v; }
}
$cmd.=" $dev{$c}" if(defined($dev{$c}));
@@ -537,13 +568,13 @@ FW_makeTable($$@)
my($name, $hash, $cmd) = (@_);
return if(!$hash || !int(keys %{$hash}));
- pO " ";
+ pO "";
my $row = 1;
foreach my $n (sort keys %{$hash}) {
my $r = ref($hash->{$n});
next if($r && ($r ne "HASH" || !defined($hash->{$n}{VAL})));
- pF " ", ($row&1)?"odd":"even";
+ pF "
", ($row&1)?"odd":"even";
$row++;
my $val = $hash->{$n};
@@ -578,7 +609,7 @@ FW_makeTable($$@)
pO "
";
}
- pO "
";
+ pO "
";
pO "
";
}
@@ -622,9 +653,9 @@ FW_doDetail($)
FW_makeTable($d, $attr{$d}, "deleteattr");
if($t eq "FileLog" ) {
- pO " ";
+ pO "";
FW_dumpFileLog($d, 0, 1);
- pO "
";
+ pO "
";
}
pO "";
@@ -728,25 +759,25 @@ FW_roomOverview($)
pO "