From c44ec53ad7052f3796c7ac9c9fb11ee2ced68baa Mon Sep 17 00:00:00 2001 From: rudolfkoenig <> Date: Thu, 9 Sep 2021 17:10:37 +0000 Subject: [PATCH] 93_FHEM2FHEM.pm: add "set cmd" and "attr keepaliveInterval" (Forum #122805) git-svn-id: https://svn.fhem.de/fhem/trunk@24939 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/93_FHEM2FHEM.pm | 92 ++++++++++++++++++++++++++++++++++----- fhem/www/pgm2/fhemweb.js | 2 + 2 files changed, 83 insertions(+), 11 deletions(-) diff --git a/fhem/FHEM/93_FHEM2FHEM.pm b/fhem/FHEM/93_FHEM2FHEM.pm index fa711d700..e40821e23 100644 --- a/fhem/FHEM/93_FHEM2FHEM.pm +++ b/fhem/FHEM/93_FHEM2FHEM.pm @@ -35,14 +35,15 @@ FHEM2FHEM_Initialize($) no warnings 'qw'; my @attrList = qw( addStateEvent:1,0 - dummy:1,0 disable:0,1 disabledForIntervals + dummy:1,0 eventOnly:1,0 excludeEvents loopThreshold - setState + keepaliveInterval reportConnected:1,0 + setState ); use warnings 'qw'; $hash->{AttrList} = join(" ", @attrList); @@ -160,6 +161,24 @@ FHEM2FHEM_Read($) #Log3 $hash, 5, "FHEM2FHEM/RAW: $data/$buf"; $data .= $buf; + if($data =~ m/\0/) { + if($data !~ m/^(.*)\0(.*)\0(.*)$/s) { + $hash->{PARTIAL} = $data; + return; + } + + my $resp = $2; + if($hash->{".lcmd"}) { + Log3 $name, 4, "Remote command response:$resp"; + asyncOutput($hash->{".lcmd"}, $resp); + delete($hash->{".lcmd"}); + } else { + Log3 $name, 3, "Remote command response:$resp"; + } + + $data = $1.$3; # Continue with the rest + } + while($data =~ m/\n/) { my $rmsg; ($rmsg,$data) = split("\n", $data, 2); @@ -297,6 +316,9 @@ FHEM2FHEM_OpenDev($$) syswrite($hash->{TCPDev}, $msg . "\n"); syswrite($hash->{TCPDev}, "trigger global CONNECTED $name\n") if(AttrVal($name, "reportConnected", 0)); + + my $ki = AttrVal($hash->{NAME}, "keepaliveInterval", 0); + InternalTimer(gettimeofday()+$ki, "FHEM2FHEM_keepalive", $hash) if($ki); }; return HttpUtils_Connect({ # Nonblocking @@ -346,14 +368,25 @@ sub FHEM2FHEM_Set($@) { my ($hash, @a) = @_; + my %sets = ( reopen=>"noArg", cmd=>"textField" ); return "set needs at least one parameter" if(@a < 2); - return "Unknown argument $a[1], choose one of reopen:noArg" - if($a[1] ne "reopen"); - + return "Unknown argument $a[1], choose one of ". + join(" ", map {"$_:$sets{$_}"} sort keys %sets) if(!$sets{$a[1]}); + return "$a[1] needs at least one parameter" + if(@a < 3 && $sets{$a[1]} ne "noArg"); - FHEM2FHEM_CloseDev($hash); - FHEM2FHEM_OpenDev($hash, 0); + if($a[1] eq "reopen") { + FHEM2FHEM_CloseDev($hash); + FHEM2FHEM_OpenDev($hash, 0); + } + if($a[1] eq "cmd") { + return "Not connected" if($hash->{STATE} ne "connected"); + my $cmd = join(" ",@a[2..$#a]); + $cmd = '{my $r=fhem("'.$cmd.'");; defined($r) ? "\\0$r\\0" : $r}'."\n"; + syswrite($hash->{TCPDev}, $cmd); + $hash->{".lcmd"} = $hash->{CL}; + } return undef; } @@ -363,13 +396,31 @@ FHEM2FHEM_Attr(@) my ($type, $devName, $attrName, @param) = @_; my $hash = $defs{$devName}; - return undef if($attrName && $attrName ne "addStateEvent"); - $attr{$devName}{$attrName} = 1; - FHEM2FHEM_CloseDev($hash); - FHEM2FHEM_OpenDev($hash, 1); + if($attrName eq "addStateEvent") { + $attr{$devName}{$attrName} = 1; + FHEM2FHEM_CloseDev($hash); + FHEM2FHEM_OpenDev($hash, 1); + } + + if($attrName eq "keepaliveInterval") { + return "Numeric argument expected" if($param[0] !~ m/^\d+$/); + InternalTimer(gettimeofday()+$param[0], "FHEM2FHEM_keepalive", $hash) + if($param[0] && $hash->{TCPDev}); + } + return undef; } +sub +FHEM2FHEM_keepalive($) +{ + my ($hash) = @_; + my $ki = AttrVal($hash->{NAME}, "keepaliveInterval", 0); + return if(!$ki || !$hash->{TCPDev}); + syswrite($hash->{TCPDev}, "{undef}\n"); + InternalTimer(gettimeofday()+$ki, "FHEM2FHEM_keepalive", $hash); +} + 1; =pod @@ -464,6 +515,12 @@ FHEM2FHEM_Attr(@)