]> git.basschouten.com Git - openhab-addons.git/commitdiff
[mqtt.generic] Support transformationPattern for thing's availabilityTopic (#12167)
authorjimtng <2554958+jimtng@users.noreply.github.com>
Sun, 6 Feb 2022 09:30:06 +0000 (19:30 +1000)
committerGitHub <noreply@github.com>
Sun, 6 Feb 2022 09:30:06 +0000 (10:30 +0100)
* [mqtt.generic] Support transformationPattern for thing's availability payload
* [mqtt] Remove org.apache.commons.lang3.StringUtils dependency

Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
bundles/org.openhab.binding.mqtt.generic/README.md
bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/AbstractMQTTThingHandler.java
bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/ChannelState.java
bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/internal/handler/GenericMQTTThingHandler.java
bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/internal/handler/GenericThingConfiguration.java
bundles/org.openhab.binding.mqtt.generic/src/main/resources/OH-INF/thing/generic-thing.xml

index eb679a04badf9d09f542d812c44f4a4299fd4eb1..359f934a97a1c5f1efbd664ccb4ac6a5382d5b6b 100644 (file)
@@ -58,6 +58,7 @@ The following optional parameters can be set for the Thing:
 * __availabilityTopic__: The MQTT topic that represents the availability of the thing. This can be the thing's LWT topic.
 * __payloadAvailable__: Payload of the `Availability Topic`, when the device is available. Default: `ON`.
 * __payloadNotAvailable__: Payload of the `Availability Topic`, when the device is *not* available. Default: `OFF`.
+* __transformationPattern__: An optional transformation pattern like [JSONPath](https://goessner.net/articles/JsonPath/index.html#e2) that is applied to the incoming availability payload. Transformations can be chained by separating them with the mathematical intersection character "∩". The result of the transformations is then checked against `payloadAvailable` and `payloadNotAvailable`.
 
 ## Supported Channels
 
index c53a00e0fc4266b5662cab4515fdb2eb02aa00fc..e7ff415f4ff9102dccc067a8a4093d0e4beba007 100644 (file)
@@ -289,6 +289,12 @@ public abstract class AbstractMQTTThingHandler extends BaseThingHandler
     @Override
     public void addAvailabilityTopic(String availability_topic, String payload_available,
             String payload_not_available) {
+        addAvailabilityTopic(availability_topic, payload_available, payload_not_available, null, null);
+    }
+
+    public void addAvailabilityTopic(String availability_topic, String payload_available, String payload_not_available,
+            @Nullable String transformation_pattern,
+            @Nullable TransformationServiceProvider transformationServiceProvider) {
         availabilityStates.computeIfAbsent(availability_topic, topic -> {
             Value value = new OnOffValue(payload_available, payload_not_available);
             ChannelGroupUID groupUID = new ChannelGroupUID(getThing().getUID(), "availablility");
@@ -308,6 +314,9 @@ public abstract class AbstractMQTTThingHandler extends BaseThingHandler
                         public void postChannelCommand(ChannelUID channelUID, Command value) {
                         }
                     });
+            if (transformation_pattern != null && transformationServiceProvider != null) {
+                state.addTransformation(transformation_pattern, transformationServiceProvider);
+            }
             MqttBrokerConnection connection = getConnection();
             if (connection != null) {
                 state.start(connection, scheduler, 0);
index fb2a0213d2b41701012006df472cef1b0a723edf..8b1ea428aea751cbfb62f1cf50274b071cdecdab 100644 (file)
@@ -20,6 +20,7 @@ import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
@@ -94,6 +95,10 @@ public class ChannelState implements MqttMessageSubscriber {
         transformationsIn.add(transformation);
     }
 
+    public void addTransformation(String transformation, TransformationServiceProvider transformationServiceProvider) {
+        parseTransformation(transformation, transformationServiceProvider).forEach(t -> addTransformation(t));
+    }
+
     /**
      * Add a transformation that is applied for each value to be published.
      * The transformations are executed in order.
@@ -104,6 +109,18 @@ public class ChannelState implements MqttMessageSubscriber {
         transformationsOut.add(transformation);
     }
 
+    public void addTransformationOut(String transformation,
+            TransformationServiceProvider transformationServiceProvider) {
+        parseTransformation(transformation, transformationServiceProvider).forEach(t -> addTransformationOut(t));
+    }
+
+    public static Stream<ChannelStateTransformation> parseTransformation(String transformation,
+            TransformationServiceProvider transformationServiceProvider) {
+        String[] transformations = transformation.split("∩");
+        return Stream.of(transformations).filter(t -> !t.isBlank())
+                .map(t -> new ChannelStateTransformation(t, transformationServiceProvider));
+    }
+
     /**
      * Clear transformations
      */
index 0baa72040887986bbf83b66140790bf5fdc83570..23e6c67ee276f5d77b91a1f383ee58c96a10c451 100644 (file)
@@ -19,15 +19,12 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
-import org.apache.commons.lang3.StringUtils;
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.mqtt.generic.AbstractMQTTThingHandler;
 import org.openhab.binding.mqtt.generic.ChannelConfig;
 import org.openhab.binding.mqtt.generic.ChannelState;
-import org.openhab.binding.mqtt.generic.ChannelStateTransformation;
 import org.openhab.binding.mqtt.generic.ChannelStateUpdateListener;
 import org.openhab.binding.mqtt.generic.MqttChannelStateDescriptionProvider;
 import org.openhab.binding.mqtt.generic.TransformationServiceProvider;
@@ -126,19 +123,11 @@ public class GenericMQTTThingHandler extends AbstractMQTTThingHandler implements
      */
     protected ChannelState createChannelState(ChannelConfig channelConfig, ChannelUID channelUID, Value valueState) {
         ChannelState state = new ChannelState(channelConfig, channelUID, valueState, this);
-        String[] transformations;
 
         // Incoming value transformations
-        transformations = channelConfig.transformationPattern.split("∩");
-        Stream.of(transformations).filter(StringUtils::isNotBlank)
-                .map(t -> new ChannelStateTransformation(t, transformationServiceProvider))
-                .forEach(t -> state.addTransformation(t));
-
+        state.addTransformation(channelConfig.transformationPattern, transformationServiceProvider);
         // Outgoing value transformations
-        transformations = channelConfig.transformationPatternOut.split("∩");
-        Stream.of(transformations).filter(StringUtils::isNotBlank)
-                .map(t -> new ChannelStateTransformation(t, transformationServiceProvider))
-                .forEach(t -> state.addTransformationOut(t));
+        state.addTransformationOut(channelConfig.transformationPatternOut, transformationServiceProvider);
 
         return state;
     }
@@ -195,7 +184,8 @@ public class GenericMQTTThingHandler extends AbstractMQTTThingHandler implements
         String availabilityTopic = config.availabilityTopic;
 
         if (availabilityTopic != null) {
-            addAvailabilityTopic(availabilityTopic, config.payloadAvailable, config.payloadNotAvailable);
+            addAvailabilityTopic(availabilityTopic, config.payloadAvailable, config.payloadNotAvailable,
+                    config.transformationPattern, transformationServiceProvider);
         } else {
             clearAllAvailabilityTopics();
         }
index a8b3a67e4f375d08a56d88351dbae80f1e387458..16d06a9569a26db43fef3d89f2510c77c715fb8b 100644 (file)
@@ -38,4 +38,9 @@ public class GenericThingConfiguration {
      * payload for the availability topic when the device is *not* available.
      */
     public String payloadNotAvailable = OnOffType.OFF.toString();
+
+    /**
+     * transformation pattern for the availability payload
+     */
+    public @Nullable String transformationPattern;
 }
index edba180129a62c3d67264ee027fa6d6847367454..3b5c731b506d41deba73029e908ce7a942b3425a 100644 (file)
                                <description>Payload of the 'Availability Topic', when the device is *not* available. Default: 'OFF'</description>
                                <advanced>true</advanced>
                        </parameter>
+                       <parameter name="transformationPattern" type="text">
+                               <label>Availability Payload Transformations</label>
+                               <description>
+                                       <![CDATA[
+                                       Applies transformations to the incoming availability payload.
+                                       A transformation example for a received JSON would be "JSONPATH:$.status" for
+                                       a json {status: "Online"}.
+
+                                       You can chain transformations by separating them with the intersection character ∩.
+                                       ]]>
+                               </description>
+                               <advanced>true</advanced>
+                       </parameter>
                </config-description>
        </thing-type>
 </thing:thing-descriptions>