* __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
@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");
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);
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;
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.
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
*/
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;
*/
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;
}
String availabilityTopic = config.availabilityTopic;
if (availabilityTopic != null) {
- addAvailabilityTopic(availabilityTopic, config.payloadAvailable, config.payloadNotAvailable);
+ addAvailabilityTopic(availabilityTopic, config.payloadAvailable, config.payloadNotAvailable,
+ config.transformationPattern, transformationServiceProvider);
} else {
clearAllAvailabilityTopics();
}
* 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;
}
<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>