From 9d7c346d135d88c2aad0075d69a6e0c70974ba3e Mon Sep 17 00:00:00 2001 From: rudolfkoenig <> Date: Wed, 18 Nov 2015 18:53:43 +0000 Subject: [PATCH] fhem.pl: async get capability, if supported by the module (Forum #43771) git-svn-id: https://svn.fhem.de/fhem/trunk@9927 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/01_FHEMWEB.pm | 63 +++++++++++++++++++++++++++++++++++++--- fhem/FHEM/98_telnet.pm | 34 +++++++++++++++------- fhem/fhem.pl | 21 ++++++++++++++ fhem/www/pgm2/fhemweb.js | 37 ++++++++++++++++++----- 4 files changed, 134 insertions(+), 21 deletions(-) diff --git a/fhem/FHEM/01_FHEMWEB.pm b/fhem/FHEM/01_FHEMWEB.pm index 790f641c7..f0a8e3217 100755 --- a/fhem/FHEM/01_FHEMWEB.pm +++ b/fhem/FHEM/01_FHEMWEB.pm @@ -106,6 +106,7 @@ my %FW_types; # device types, for sorting my %FW_hiddengroup;# hash of hidden groups my $FW_inform; my $FW_XHR; # Data only answer, no HTML +my $FW_id; # id of current page my $FW_jsonp; # jasonp answer (sending function calls to the client) my $FW_headercors; # my $FW_chash; # client fhem hash @@ -125,6 +126,7 @@ FHEMWEB_Initialize($) $hash->{DefFn} = "FW_Define"; $hash->{UndefFn} = "FW_Undef"; $hash->{NotifyFn}= ($init_done ? "FW_Notify" : "FW_SecurityCheck"); + $hash->{AsyncOutputFn} = "FW_AsyncOutput"; $hash->{ActivateInformFn} = "FW_ActivateInform"; no warnings 'qw'; my @attrList = qw( @@ -475,6 +477,43 @@ FW_Read($$) } } +sub +FW_AsyncOutput($$) +{ + my ($hash, $ret) = @_; + + if( $ret =~ m/^(.*)<\/html>$/s ) { + $ret = $1; + + } else { + $ret =~ s/&/&/g; + $ret =~ s/'/'/g; + $ret =~ s/</g; + $ret =~ s/>/>/g; + $ret = "
$ret" if($ret =~ m/\n/ ); + $ret =~ s/\n/
';
FW_pO "";
diff --git a/fhem/FHEM/98_telnet.pm b/fhem/FHEM/98_telnet.pm
index 31a29c736..d7a6bb1ae 100644
--- a/fhem/FHEM/98_telnet.pm
+++ b/fhem/FHEM/98_telnet.pm
@@ -17,6 +17,7 @@ telnet_Initialize($)
$hash->{DefFn} = "telnet_Define";
$hash->{ReadFn} = "telnet_Read";
+ $hash->{AsyncOutputFn} = "telnet_Output";
$hash->{UndefFn} = "telnet_Undef";
$hash->{AttrFn} = "telnet_Attr";
$hash->{NotifyFn}= "telnet_SecurityCheck";
@@ -187,6 +188,7 @@ telnet_Read($)
if($hash->{SERVERSOCKET}) { # Accept and create a child
my $chash = TcpServer_Accept($hash, "telnet");
return if(!$chash);
+ $chash->{canAsyncOutput} = 1;
$chash->{encoding} = AttrVal($name, "encoding", "utf8");
$chash->{prompt} = AttrVal($name, "prompt", "fhem>");
syswrite($chash->{CD}, sprintf("%c%c%c", 255, 253, 0) )
@@ -203,6 +205,7 @@ telnet_Read($)
if($hash->{isClient}) {
telnet_ClientDisconnect($hash, 0);
} else {
+ delete $hash->{canAsyncOutput};
CommandDelete(undef, $name);
}
return;
@@ -284,17 +287,10 @@ telnet_Read($)
$ret .= (join("\n", @ret) . "\n") if(@ret);
$ret .= ($hash->{prevlines} ? "> " : $hash->{prompt}." ")
if($gotCmd && $hash->{showPrompt} && !$hash->{rcvdQuit});
- if($ret) {
- $ret = utf8ToLatin1($ret) if( $hash->{encoding} eq "latin1" );
- $ret =~ s/\n/\r\n/g if($pw); # only for DOS telnet
- for(;;) {
- my $l = syswrite($hash->{CD}, $ret);
- last if(!$l || $l == length($ret));
- $ret = substr($ret, $l);
- }
- $hash->{CD}->flush();
- }
+ $ret =~ s/\n/\r\n/g if($pw); # only for DOS telnet
+ telnet_Output($hash,$ret);
+
if($hash->{rcvdQuit}) {
if($hash->{isClient}) {
delete($hash->{rcvdQuit});
@@ -304,6 +300,24 @@ telnet_Read($)
}
}
}
+sub
+telnet_Output($$)
+{
+ my ($hash,$ret) = @_;
+
+ if($ret) {
+ $ret = utf8ToLatin1($ret) if( $hash->{encoding} eq "latin1" );
+ for(;;) {
+ my $l = syswrite($hash->{CD}, $ret);
+ last if(!$l || $l == length($ret));
+ $ret = substr($ret, $l);
+ }
+ $hash->{CD}->flush();
+
+ }
+
+ return undef;
+}
##########################
sub
diff --git a/fhem/fhem.pl b/fhem/fhem.pl
index 56d6341b0..a0e49d7a4 100755
--- a/fhem/fhem.pl
+++ b/fhem/fhem.pl
@@ -1601,12 +1601,33 @@ CommandGet($$)
}
$a[0] = $sdev;
+ $defs{$sdev}->{CL} = $cl;
my $ret = CallFn($sdev, "GetFn", $defs{$sdev}, @a);
+ delete $defs{$sdev}->{CL};
push @rets, $ret if(defined($ret) && $ret ne "");
}
return join("\n", @rets);
}
+sub
+asyncOutput($$)
+{
+ my ($cl,$ret) = @_;
+
+ return undef if( !$cl );
+
+ if( !$defs{$cl->{NAME}}
+ || $defs{$cl->{NAME}}->{NR} != $cl->{NR}
+ || $defs{$cl->{NAME}}->{NAME} ne $cl->{NAME} ) {
+ Log3 $cl->{NAME},3,"$cl->{NAME} asyncOutput: device gone, output was: $ret";
+ return undef;
+ }
+
+ $ret = CallFn($cl->{NAME}, "AsyncOutputFn", $defs{$cl->{NAME}}, $ret);
+
+ return $ret;
+}
+
#####################################
sub
LoadModule($;$)
diff --git a/fhem/www/pgm2/fhemweb.js b/fhem/www/pgm2/fhemweb.js
index ea30d188c..ce3871bd9 100644
--- a/fhem/www/pgm2/fhemweb.js
+++ b/fhem/www/pgm2/fhemweb.js
@@ -52,8 +52,8 @@ function
FW_jqueryReadyFn()
{
FW_docReady = true;
- FW_serverGenerated = document.body.getAttribute("generated");
- if(document.body.getAttribute("longpoll"))
+ FW_serverGenerated = $("body").attr("generated");
+ if($("body").attr("longpoll"))
setTimeout("FW_longpoll()", 100);
$("a").each(function() { FW_replaceLink(this); })
@@ -128,6 +128,7 @@ FW_jqueryReadyFn()
});
FW_cmd(FW_root+"?"+cmd+"&XHR=1&addLinks=1", function(data) {
if(!data.match(/^[\r\n]*$/)) // ignore empty answers
+ data = data.replace( '<', '<' );
FW_okDialog(''+data+'', el); }); }); @@ -146,12 +147,32 @@ FW_jqueryReadyFn() var input = $(this).find("input.maininput"); if(!input.length) return; - $(this).on("submit", function() { - if($(input).val().match(/^\s*shutdown/)) { - FW_cmd(FW_root+"?XHR=1&cmd="+$(input).val()); + $(this).on("submit", function(e) { + var val = $(input).val(); + if(val.match(/^\s*shutdown/)) { + FW_cmd(FW_root+"?XHR=1&cmd="+val); + $(input).val(""); + return false; + + } else if(val.match(/^\s*get\s+/)) { + // make get use xhr instead of reload + //return true; + FW_cmd(FW_root+"?cmd="+val+"&XHR=1", function(data) { + if( !data.match( /^.*<\/html>/ ) ) { + data = data.replace( '<', '<' ); + data = ' '+data+''; + } + if( location.href.indexOf('?') === -1 ) + $('#content').html(data); + else + FW_okDialog(data); + }); + + e.preventDefault(); $(input).val(""); return false; } + return true; }); }); @@ -215,7 +236,7 @@ log(txt) function addcsrf(arg) { - var csrf = document.body.getAttribute('fwcsrf'); + var csrf = $("body").attr('fwcsrf'); if(csrf && arg.indexOf('fwcsrf') < 0) arg += '&fwcsrf='+csrf; return arg; @@ -226,6 +247,7 @@ FW_cmd(arg, callback) { log("FW_cmd:"+arg); arg = addcsrf(arg); + arg += '&fw_id='+$("body").attr('fw_id'); var req = new XMLHttpRequest(); req.open("POST", arg, true); req.send(null); @@ -509,7 +531,7 @@ FW_longpoll() filter="room="+room; } } - var iP = document.body.getAttribute("iconPath"); + var iP = $("body").attr("iconPath"); if(iP != null) filter = filter +";iconPath="+iP; @@ -519,6 +541,7 @@ FW_longpoll() var query = location.pathname+"?XHR=1"+ "&inform=type=status;filter="+filter+";since="+since+";fmt=JSON"+ + '&fw_id='+$("body").attr('fw_id')+ "×tamp="+new Date().getTime(); query = addcsrf(query); FW_pollConn.open("GET", query, true); |