From 8e3a6b1b482107651b9a9241f9a84a0739214908 Mon Sep 17 00:00:00 2001 From: rudolfkoenig <> Date: Sun, 24 Jan 2021 18:51:58 +0000 Subject: [PATCH] fhem.pl: add ClientsKeepOrder feature (Forum #117737) git-svn-id: https://svn.fhem.de/fhem/trunk@23609 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/00_MQTT2_CLIENT.pm | 11 ++++++----- fhem/FHEM/00_MQTT2_SERVER.pm | 11 ++++++----- fhem/fhem.pl | 34 +++++++++++++++++++++++++--------- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/fhem/FHEM/00_MQTT2_CLIENT.pm b/fhem/FHEM/00_MQTT2_CLIENT.pm index cb08b562a..3580941e8 100644 --- a/fhem/FHEM/00_MQTT2_CLIENT.pm +++ b/fhem/FHEM/00_MQTT2_CLIENT.pm @@ -20,7 +20,6 @@ MQTT2_CLIENT_Initialize($) { my ($hash) = @_; - MQTT2_CLIENT_resetClients($hash); $hash->{ReadFn} = "MQTT2_CLIENT_Read"; $hash->{DefFn} = "MQTT2_CLIENT_Define"; $hash->{AttrFn} = "MQTT2_CLIENT_Attr"; @@ -63,6 +62,7 @@ MQTT2_CLIENT_resetClients($) { my ($hash) = @_; + $hash->{ClientsKeepOrder} = 1; $hash->{Clients} = ":MQTT2_DEVICE:MQTT_GENERIC_BRIDGE:"; $hash->{MatchList}= { "1:MQTT2_DEVICE" => "^.", @@ -80,6 +80,7 @@ MQTT2_CLIENT_Define($$) return "Usage: define MQTT2_CLIENT :" if(!$host); + MQTT2_CLIENT_resetClients($hash); MQTT2_CLIENT_Undef($hash, undef) if($hash->{OLDDEF}); # modify $hash->{DeviceName} = $host; @@ -332,13 +333,13 @@ MQTT2_CLIENT_Attr(@) if($attrName eq "clientOrder") { if($type eq "set") { my @p = split(" ", $param[0]); - $modules{MQTT2_CLIENT}{Clients} = ":".join(":",@p).":"; + $hash->{Clients} = ":".join(":",@p).":"; my $cnt = 1; my %h = map { ($cnt++.":$_", "^.") } @p; - $modules{MQTT2_CLIENT}{MatchList} = \%h; - delete($modules{MQTT2_CLIENT}{".clientArray"}); # Force a recompute + $hash->{MatchList} = \%h; + delete($hash->{".clientArray"}); # Force a recompute } else { - MQTT2_CLIENT_resetClients($modules{MQTT2_CLIENT}); + MQTT2_CLIENT_resetClients($hash}); } } diff --git a/fhem/FHEM/00_MQTT2_SERVER.pm b/fhem/FHEM/00_MQTT2_SERVER.pm index 392ebf400..0716b57c0 100644 --- a/fhem/FHEM/00_MQTT2_SERVER.pm +++ b/fhem/FHEM/00_MQTT2_SERVER.pm @@ -21,7 +21,6 @@ MQTT2_SERVER_Initialize($) { my ($hash) = @_; - MQTT2_SERVER_resetClients($hash); $hash->{ReadFn} = "MQTT2_SERVER_Read"; $hash->{DefFn} = "MQTT2_SERVER_Define"; $hash->{AttrFn} = "MQTT2_SERVER_Attr"; @@ -55,6 +54,7 @@ MQTT2_SERVER_resetClients($) { my ($hash) = @_; + $hash->{ClientsKeepOrder} = 1; $hash->{Clients} = ":MQTT2_DEVICE:MQTT_GENERIC_BRIDGE:"; $hash->{MatchList}= { "1:MQTT2_DEVICE" => "^.", @@ -72,6 +72,7 @@ MQTT2_SERVER_Define($$) return "Usage: define MQTT2_SERVER [IPV6:] [global]" if($port !~ m/^(IPV6:)?\d+$/); + MQTT2_SERVER_resetClients($hash); MQTT2_SERVER_Undef($hash, undef) if($hash->{OLDDEF}); # modify my $ret = TcpServer_Open($hash, $port, $global); @@ -161,13 +162,13 @@ MQTT2_SERVER_Attr(@) if($attrName eq "clientOrder") { if($type eq "set") { my @p = split(" ", $param[0]); - $modules{MQTT2_SERVER}{Clients} = ":".join(":",@p).":"; + $hash->{Clients} = ":".join(":",@p).":"; my $cnt = 1; my %h = map { ($cnt++.":$_", "^.") } @p; - $modules{MQTT2_SERVER}{MatchList} = \%h; - delete($modules{MQTT2_SERVER}{".clientArray"}); # Force a recompute + $hash->{MatchList} = \%h; + delete($hash->{".clientArray"}); # Force a recompute } else { - MQTT2_SERVER_resetClients($modules{MQTT2_SERVER}); + MQTT2_SERVER_resetClients($hash); } } diff --git a/fhem/fhem.pl b/fhem/fhem.pl index 688f80e97..551dac502 100755 --- a/fhem/fhem.pl +++ b/fhem/fhem.pl @@ -4003,7 +4003,7 @@ Dispatch($$;$$) foreach my $m (@{$clientArray}) { # Module is not loaded or the message is not for this module - next if(!$modules{$m} || $dmsg !~ m/$modules{$m}{Match}/s); + next if(!$dmsg !~ m/$modules{$m}{Match}/s); if( my $ffn = $modules{$m}{FingerprintFn} ) { ($isdup, $idx) = CheckDuplicate($name, $dmsg, $ffn); @@ -4038,10 +4038,20 @@ Dispatch($$;$$) $mname = $newm if($newm ne "UNDEFINED"); if($modules{$mname} && $modules{$mname}{ParseFn}) { no strict "refs"; $readingsUpdateDelayTrigger = 1; - @found = &{$modules{$mname}{ParseFn}}($hash,$dmsg); + my @tfound = &{$modules{$mname}{ParseFn}}($hash,$dmsg); use strict "refs"; $readingsUpdateDelayTrigger = 0; $parserMod = $mname; - last if(defined($found[0])); + + if(int(@tfound) && defined($tfound[0])) { + if($tfound[0] && $tfound[0] eq "[NEXT]") { + shift(@tfound); + push @found, @tfound; + } else { + push @found, @tfound; + last; + } + } + } else { Log 0, "ERROR: Cannot autoload $mname"; } @@ -5066,14 +5076,20 @@ computeClientArray($$) { my ($hash, $module) = @_; my @a = (); + my @mRe = split(":", $hash->{Clients} ? $hash->{Clients}:$module->{Clients}); - foreach my $m (sort { $modules{$a}{ORDER}.$a cmp $modules{$b}{ORDER}.$b } - grep { defined($modules{$_}{ORDER}) } keys %modules) { - foreach my $re (@mRe) { - if($m =~ m/^$re$/) { - push @a, $m if($modules{$m}{Match}); - last; + if($hash->{ClientsKeepOrder}) { + @a = grep { $modules{$_} && $modules{$_}{Match} } @mRe; + + } else { + foreach my $m (sort { $modules{$a}{ORDER}.$a cmp $modules{$b}{ORDER}.$b } + grep { defined($modules{$_}{ORDER}) } keys %modules) { + foreach my $re (@mRe) { + if($m =~ m/^$re$/) { + push @a, $m if($modules{$m}{Match}); + last; + } } } }