From c7d1d34c62603bff93b9a3c243c0a6cea99f798d Mon Sep 17 00:00:00 2001
From: rudolfkoenig <>
Date: Wed, 8 Apr 2020 10:15:11 +0000
Subject: [PATCH] 00_MQTT2_SERVER.pm/00_MQTT2_CLIENT.pm: add ignoreRegexp
 (Forum #103737)

git-svn-id: https://svn.fhem.de/fhem/trunk@21625 2b470e98-0d58-463d-a4d8-8e2adae1ed80
---
 fhem/FHEM/00_MQTT2_CLIENT.pm | 46 +++++++++++++++++++++++++-----------
 fhem/FHEM/00_MQTT2_SERVER.pm | 29 ++++++++++++++++++-----
 fhem/www/pgm2/fhemweb.js     |  7 +++++-
 3 files changed, 61 insertions(+), 21 deletions(-)

diff --git a/fhem/FHEM/00_MQTT2_CLIENT.pm b/fhem/FHEM/00_MQTT2_CLIENT.pm
index 867e548c7..8f6ec4ff3 100644
--- a/fhem/FHEM/00_MQTT2_CLIENT.pm
+++ b/fhem/FHEM/00_MQTT2_CLIENT.pm
@@ -40,6 +40,7 @@ MQTT2_CLIENT_Initialize($)
     clientId
     disable:1,0
     disabledForIntervals
+    ignoreRegexp
     lwt
     lwtRetain
     keepaliveTimeout
@@ -207,8 +208,16 @@ MQTT2_CLIENT_Attr(@)
     $hash->{SSL} = $param[0] ? $param[0] : 1;
   }
 
+  if($type eq "set" && $attrName eq "ignoreRegexp") {
+    my $re = join(" ",@param);
+    return "bad $devName ignoreRegexp: $re" if($re eq "1" || $re =~ m/^\*/);
+    eval { "Hallo" =~ m/$re/ };
+    return "bad $devName ignoreRegexp: $re: $@" if($@);
+  }
+
   if($attrName eq "clientId") {
-    $hash->{clientId} = $param[0];
+    delete($hash->{clientId});
+    $hash->{clientId} = $param[0] if($type eq "set");
   }
 
   if($attrName eq "sslargs") {
@@ -362,6 +371,10 @@ MQTT2_CLIENT_Read($@)
 
     if(!IsDisabled($name)) {
       $val = "" if(!defined($val));
+
+      my $ir = AttrVal($name, "ignoreRegexp", undef);
+      next if(defined($ir) && "$tp:$val" =~ m/$ir/);
+
       my $ac = AttrVal($name, "autocreate", "no");
       $ac = $ac eq "1" ? "simple" : ($ac eq "0" ? "no" : $ac); # backward comp.
 
@@ -537,7 +550,7 @@ MQTT2_CLIENT_getStr($$)
   <b>Attributes</b>
   <ul>
 
-    <a name="autocreate"></a>
+    <a name="MQTT_CLIENTautocreate"></a>
     <li>autocreate [no|simple|complex]<br>
       if set to simple/complex, at least one MQTT2_DEVICE will be created, and
       its readingsList will be expanded upon reception of published messages.
@@ -555,7 +568,7 @@ MQTT2_CLIENT_getStr($$)
       attribute it is not really useful.
       </li></br>
 
-    <a name="clientId"></a>
+    <a name="MQTT_CLIENTclientId"></a>
     <li>clientId &lt;name&gt;<br>
       set the MQTT clientId. If not set, the name of the MQTT2_CLIENT instance
       is used, after deleting everything outside 0-9a-zA-Z
@@ -566,65 +579,70 @@ MQTT2_CLIENT_getStr($$)
       disable dispatching of messages.
       </li><br>
 
-    <a name="lwt"></a>
+    <a name="MQTT2_CLIENTignoreRegexp"></a>
+    <li>ignoreRegexp<br>
+      if $topic:$message matches ignoreRegexp, then it will be silently ignored.
+      </li>
+
+    <a name="MQTT_CLIENTlwt"></a>
     <li>lwt &lt;topic&gt; &lt;message&gt; <br>
       set the LWT (last will and testament) topic and message, default is empty.
       </li></br>
 
-    <a name="keepaliveTimeout"></a>
+    <a name="MQTT_CLIENTkeepaliveTimeout"></a>
     <li>keepaliveTimeout &lt;seconds;&gt;<br>
       number of seconds for sending keepalive messages, 0 disables it.
       The broker will disconnect, if there were no messages for
       1.5 * keepaliveTimeout seconds.
       </li></br>
 
-    <a name="lwtRetain"></a>
+    <a name="MQTT_CLIENTlwtRetain"></a>
     <li>lwtRetain<br>
       if set, the lwt retain flag is set
       </li></br>
 
-    <a name="mqttVersion"></a>
+    <a name="MQTT_CLIENTmqttVersion"></a>
     <li>mqttVersion 3.1,3.1.1<br>
       set the MQTT protocol version in the CONNECT header, default is 3.1
       </li></br>
 
-    <a name="msgAfterConnect"></a>
+    <a name="MQTT_CLIENTmsgAfterConnect"></a>
     <li>msgAfterConnect [-r] topic message<br>
       publish the topic after each connect or reconnect.<br>
       If the optional -r is specified, then the publish sets the retain flag.
       </li></br>
 
-    <a name="msgBeforeDisconnect"></a>
+    <a name="MQTT_CLIENTmsgBeforeDisconnect"></a>
     <li>msgBeforeDisconnect [-r] topic message<br>
       publish the topic bofore each disconnect.<br>
       If the optional -r is specified, then the publish sets the retain flag.
       </li></br>
 
-    <a name="rawEvents"></a>
+    <a name="MQTT_CLIENTrawEvents"></a>
     <li>rawEvents &lt;topic-regexp&gt;<br>
       send all messages as events attributed to this MQTT2_CLIENT instance.
       Should only be used, if there is no MQTT2_DEVICE to process the topic.
       </li><br>
 
-    <a name="subscriptions"></a>
+    <a name="MQTT_CLIENTsubscriptions"></a>
     <li>subscriptions &lt;subscriptions&gt;<br>
       space separated list of MQTT subscriptions, default is #<br>
       Note: if the value is the literal setByTheProgram, then the value sent by
       the client (e.g. MQTT_GENERIC_BRIDGE) is used.
       </li><br>
 
-    <a name="SSL"></a>
+    <a name="MQTT_CLIENTSSL"></a>
     <li>SSL<br>
       Enable SSL (i.e. TLS)
       </li><br>
 
-    <a name="sslargs"></a>
+    <a name="MQTT_CLIENTsslargs"></a>
     <li>sslargs<br>
       a list of space separated tuples of key:value, where key is one of the
       possible options documented in perldoc IO::Socket::SSL
       </li><br>
 
-    <a name="username"></a>
+    <a name="MQTT_CLIENTusername"></a>
     <li>username &lt;username&gt;<br>
       set the username. The password is set via the set command, and is stored
       separately, see above.
diff --git a/fhem/FHEM/00_MQTT2_SERVER.pm b/fhem/FHEM/00_MQTT2_SERVER.pm
index 2149230a7..bf24bf83f 100644
--- a/fhem/FHEM/00_MQTT2_SERVER.pm
+++ b/fhem/FHEM/00_MQTT2_SERVER.pm
@@ -42,6 +42,7 @@ MQTT2_SERVER_Initialize($)
     clientId
     disable:1,0
     disabledForIntervals
+    ignoreRegexp
     keepaliveFactor
     rePublish:1,0
     rawEvents
@@ -137,6 +138,14 @@ MQTT2_SERVER_Attr(@)
   if($type eq "set" && $attrName eq "SSL") {
     InternalTimer(1, "TcpServer_SetSSL", $hash, 0); # Wait for sslCertPrefix
   }
+
+  if($type eq "set" && $attrName eq "ignoreRegexp") {
+    my $re = join(" ",@param);
+    return "bad $devName ignoreRegexp: $re" if($re eq "1" || $re =~ m/^\*/);
+    eval { "Hallo" =~ m/$re/ };
+    return "bad $devName ignoreRegexp: $re: $@" if($@);
+  }
+
   return undef;
 } 
 
@@ -443,6 +452,9 @@ MQTT2_SERVER_doPublish($$$$;$)
   }
 
   my $serverName = $server->{NAME};
+  my $ir = AttrVal($serverName, "ignoreRegexp", undef);
+  next if(defined($ir) && "$tp:$val" =~ m/$ir/);
+
   my $cid = $src->{cid};
   $tp =~ s/:/_/g; # 96608
   if(defined($cid) ||                    # "real" MQTT client
@@ -614,7 +626,7 @@ MQTT2_SERVER_ReadDebug($$)
   <b>Attributes</b>
   <ul>
 
-    <a name="clientId"></a>
+    <a name="MQTT2_SERVERclientId"></a>
     <li>clientId &lt;name&gt;<br>
       set the MQTT clientId for all connections, for setups with clients
       creating a different MQTT-ID for each connection. The autocreate
@@ -629,7 +641,12 @@ MQTT2_SERVER_ReadDebug($$)
       messages, but not forward them.
       </li><br>
 
-    <a name="keepaliveFactor"></a>
+    <a name="MQTT2_SERVERignoreRegexp"></a>
+    <li>ignoreRegexp<br>
+      if $topic:$message matches ignoreRegexp, then it will be silently ignored.
+      </li>
+
+    <a name="MQTT2_SERVERkeepaliveFactor"></a>
     <li>keepaliveFactor<br>
       the oasis spec requires a disconnect, if after 1.5 times the client
       supplied keepalive no data or PINGREQ is sent. With this attribute you
@@ -641,13 +658,13 @@ MQTT2_SERVER_ReadDebug($$)
       </ul>
       </li>
     
-    <a name="rawEvents"></a>
+    <a name="MQTT2_SERVERrawEvents"></a>
     <li>rawEvents &lt;topic-regexp&gt;<br>
       Send all messages as events attributed to this MQTT2_SERVER instance.
       Should only be used, if there is no MQTT2_DEVICE to process the topic.
       </li><br>
 
-    <a name="rePublish"></a>
+    <a name="MQTT2_SERVERrePublish"></a>
     <li>rePublish<br>
       if a topic is published from a source inside of FHEM (e.g. MQTT2_DEVICE),
       it is only sent to real MQTT clients, and it will not internally
@@ -655,7 +672,7 @@ MQTT2_SERVER_ReadDebug($$)
       to the FHEM internal clients.
       </li><br>
 
-    <a name="SSL"></a>
+    <a name="MQTT2_SERVERSSL"></a>
     <li>SSL<br>
       Enable SSL (i.e. TLS).
       </li><br>
@@ -669,7 +686,7 @@ MQTT2_SERVER_ReadDebug($$)
        also the SSL attribute.
        </li><br>
 
-    <a name="autocreate"></a>
+    <a name="MQTT2_SERVERautocreate"></a>
     <li>autocreate [no|simple|complex]<br>
       MQTT2_DEVICES will be automatically created upon receiving an
       unknown message. Set this value to no to disable autocreating, the
diff --git a/fhem/www/pgm2/fhemweb.js b/fhem/www/pgm2/fhemweb.js
index dc37b21ca..dbbb84bad 100644
--- a/fhem/www/pgm2/fhemweb.js
+++ b/fhem/www/pgm2/fhemweb.js
@@ -306,7 +306,12 @@ FW_jqueryReadyFn()
       $("#content")
         .append("<div id='workbench' style='display:none'></div>");
       $("#content > #workbench").html(data);
-      var aTag = $("#content > #workbench").find("a[name="+val+"]");
+
+      var mtype = $("#content > #workbench a[name]").attr("name"), aTag;
+      if(mtype)
+        aTag = $("#content > #workbench").find("a[name="+mtype+val+"]");
+      if(!$(aTag).length) // old style syntax without type
+        aTag = $("#content > #workbench").find("a[name="+val+"]");
       if($(aTag).length) {
         var liTag = $(aTag).next("li");
         if(!$(liTag).length)