diff --git a/bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/ChannelState.java b/bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/ChannelState.java
index e1d5da2ef59..2ba8ad2aa1b 100644
--- a/bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/ChannelState.java
+++ b/bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/ChannelState.java
@@ -78,13 +78,35 @@ public class ChannelState implements MqttMessageSubscriber {
*/
public ChannelState(ChannelConfig config, ChannelUID channelUID, Value cachedValue,
@Nullable ChannelStateUpdateListener channelStateUpdateListener) {
+ this(config, channelUID, cachedValue, channelStateUpdateListener,
+ new ChannelTransformation(config.transformationPattern),
+ new ChannelTransformation(config.transformationPatternOut));
+ }
+
+ /**
+ * Creates a new channel state.
+ *
+ * @param config The channel configuration
+ * @param channelUID The channelUID is used for the {@link ChannelStateUpdateListener} to notify about value changes
+ * @param cachedValue MQTT only notifies us once about a value, during the subscribe. The channel state therefore
+ * needs a cache for the current value.
+ * @param channelStateUpdateListener A channel state update listener
+ * @param incomingTransformation A transformation to apply to incoming values
+ * @param outgoingTransformation A transformation to apply to outgoing values
+ */
+ public ChannelState(ChannelConfig config, ChannelUID channelUID, Value cachedValue,
+ @Nullable ChannelStateUpdateListener channelStateUpdateListener,
+ @Nullable ChannelTransformation incomingTransformation,
+ @Nullable ChannelTransformation outgoingTransformation) {
this.config = config;
this.channelStateUpdateListener = channelStateUpdateListener;
this.channelUID = channelUID;
this.cachedValue = cachedValue;
this.readOnly = config.commandTopic.isBlank();
- this.incomingTransformation = new ChannelTransformation(config.transformationPattern);
- this.outgoingTransformation = new ChannelTransformation(config.transformationPatternOut);
+ this.incomingTransformation = incomingTransformation == null ? new ChannelTransformation((String) null)
+ : incomingTransformation;
+ this.outgoingTransformation = outgoingTransformation == null ? new ChannelTransformation((String) null)
+ : outgoingTransformation;
}
public boolean isReadOnly() {
diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/README.md b/bundles/org.openhab.binding.mqtt.homeassistant/README.md
index 93205168af9..f65261c18bf 100644
--- a/bundles/org.openhab.binding.mqtt.homeassistant/README.md
+++ b/bundles/org.openhab.binding.mqtt.homeassistant/README.md
@@ -6,15 +6,6 @@ Devices that use [Home Assistant MQTT Discovery](https://www.home-assistant.io/i
Components that share a common `device.identifiers` will automatically be grouped together as a single Thing.
Each component will be represented as a Channel Group, with the attributes of that component being individual channels.
-## Requirements
-
-The Home Assistant MQTT binding requires two transformations to be installed:
-
-- JINJA-Transformations
-- JSONPath-Transformations
-
-These can be installed under `Settings` → `Addon` → `Transformations`
-
## Discovery
Any device that publishes the component configuration under the `homeassistant` prefix in MQTT will have their components automatically discovered and added to the Inbox.
diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/noEmbedDependencies.profile b/bundles/org.openhab.binding.mqtt.homeassistant/noEmbedDependencies.profile
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/pom.xml b/bundles/org.openhab.binding.mqtt.homeassistant/pom.xml
index 79773a7dc24..854983ad21f 100644
--- a/bundles/org.openhab.binding.mqtt.homeassistant/pom.xml
+++ b/bundles/org.openhab.binding.mqtt.homeassistant/pom.xml
@@ -35,21 +35,22 @@
- org.openhab.addons.bundles
- org.openhab.transform.jinja
- ${project.version}
- test
+ org.openhab.osgiify
+ com.hubspot.jinjava.jinjava
+ 2.7.2_0
+ compile
- com.hubspot.jinjava
- jinjava
- 2.7.2
- test
-
-
- com.google.re2j
- re2j
+ org.openhab.osgiify
+ com.google.re2j.re2j
1.2
+ compile
+
+
+ ch.obermuhlner
+ big-math
+ 2.3.2
+ compile
diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/feature/feature.xml b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/feature/feature.xml
index fd50c3169fc..853e170e1cf 100644
--- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/feature/feature.xml
+++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/feature/feature.xml
@@ -5,6 +5,10 @@
openhab-runtime-base
openhab-transport-mqtt
+ openhab.tp-commons-net
+ mvn:org.openhab.osgiify/com.hubspot.jinjava.jinjava/2.7.2_0
+ mvn:org.openhab.osgiify/com.google.re2j.re2j/1.2
+ mvn:ch.obermuhlner/big-math/2.3.2
mvn:org.openhab.addons.bundles/org.openhab.binding.mqtt/${project.version}
mvn:org.openhab.addons.bundles/org.openhab.binding.mqtt.generic/${project.version}
mvn:org.openhab.addons.bundles/org.openhab.binding.mqtt.homeassistant/${project.version}
diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/generic/internal/MqttThingHandlerFactory.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/generic/internal/MqttThingHandlerFactory.java
index b228b1b0e3b..6c5ebdd8886 100644
--- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/generic/internal/MqttThingHandlerFactory.java
+++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/generic/internal/MqttThingHandlerFactory.java
@@ -31,6 +31,8 @@ import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
+import com.hubspot.jinjava.Jinjava;
+
/**
* The {@link MqttThingHandlerFactory} is responsible for creating things and thing
* handlers.
@@ -43,6 +45,7 @@ public class MqttThingHandlerFactory extends BaseThingHandlerFactory {
private final MqttChannelTypeProvider typeProvider;
private final MqttChannelStateDescriptionProvider stateDescriptionProvider;
private final ChannelTypeRegistry channelTypeRegistry;
+ private final Jinjava jinjava = new Jinjava();
private static final Set SUPPORTED_THING_TYPES_UIDS = Stream
.of(MqttBindingConstants.HOMEASSISTANT_MQTT_THING).collect(Collectors.toSet());
@@ -72,7 +75,7 @@ public class MqttThingHandlerFactory extends BaseThingHandlerFactory {
if (supportsThingType(thingTypeUID)) {
return new HomeAssistantThingHandler(thing, typeProvider, stateDescriptionProvider, channelTypeRegistry,
- 10000, 2000);
+ jinjava, 10000, 2000);
}
return null;
}
diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/ComponentChannel.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/ComponentChannel.java
index c8bb949f42b..df7b926870b 100644
--- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/ComponentChannel.java
+++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/ComponentChannel.java
@@ -12,7 +12,6 @@
*/
package org.openhab.binding.mqtt.homeassistant.internal;
-import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledExecutorService;
@@ -30,6 +29,7 @@ import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
import org.openhab.core.thing.Channel;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.binding.builder.ChannelBuilder;
+import org.openhab.core.thing.binding.generic.ChannelTransformation;
import org.openhab.core.thing.type.AutoUpdatePolicy;
import org.openhab.core.thing.type.ChannelDefinition;
import org.openhab.core.thing.type.ChannelDefinitionBuilder;
@@ -223,21 +223,26 @@ public class ComponentChannel {
ChannelUID channelUID;
ChannelState channelState;
Channel channel;
+ ChannelTransformation incomingTransformation = null, outgoingTransformation = null;
channelUID = component.buildChannelUID(channelID);
ChannelConfigBuilder channelConfigBuilder = ChannelConfigBuilder.create().withRetain(retain).withQos(qos)
.withStateTopic(stateTopic).withCommandTopic(commandTopic).makeTrigger(trigger)
.withFormatter(format);
- if (templateIn != null) {
- channelConfigBuilder.withTransformationPattern(List.of(JINJA + ":" + templateIn));
+ String localTemplateIn = templateIn;
+ if (localTemplateIn != null) {
+ incomingTransformation = new HomeAssistantChannelTransformation(component.getJinjava(), component,
+ localTemplateIn);
}
- if (templateOut != null) {
- channelConfigBuilder.withTransformationPatternOut(List.of(JINJA + ":" + templateOut));
+ String localTemplateOut = templateOut;
+ if (localTemplateOut != null) {
+ outgoingTransformation = new HomeAssistantChannelTransformation(component.getJinjava(), component,
+ localTemplateOut);
}
channelState = new HomeAssistantChannelState(channelConfigBuilder.build(), channelUID, valueState,
- channelStateUpdateListener, commandFilter);
+ channelStateUpdateListener, commandFilter, incomingTransformation, outgoingTransformation);
// disabled by default components should always show up as advanced
if (!component.isEnabledByDefault()) {
diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/DiscoverComponents.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/DiscoverComponents.java
index 7f23a13aed2..810d99d988d 100644
--- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/DiscoverComponents.java
+++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/DiscoverComponents.java
@@ -37,6 +37,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
+import com.hubspot.jinjava.Jinjava;
/**
* Responsible for subscribing to the HomeAssistant MQTT components wildcard topic, either
@@ -55,6 +56,7 @@ public class DiscoverComponents implements MqttMessageSubscriber {
protected final CompletableFuture<@Nullable Void> discoverFinishedFuture = new CompletableFuture<>();
private final Gson gson;
+ private final Jinjava jinjava;
private @Nullable ScheduledFuture> stopDiscoveryFuture;
private WeakReference<@Nullable MqttBrokerConnection> connectionRef = new WeakReference<>(null);
@@ -78,11 +80,12 @@ public class DiscoverComponents implements MqttMessageSubscriber {
*/
public DiscoverComponents(ThingUID thingUID, ScheduledExecutorService scheduler,
ChannelStateUpdateListener channelStateUpdateListener, AvailabilityTracker tracker, Gson gson,
- boolean newStyleChannels) {
+ Jinjava jinjava, boolean newStyleChannels) {
this.thingUID = thingUID;
this.scheduler = scheduler;
this.updateListener = channelStateUpdateListener;
this.gson = gson;
+ this.jinjava = jinjava;
this.tracker = tracker;
this.newStyleChannels = newStyleChannels;
}
@@ -100,7 +103,7 @@ public class DiscoverComponents implements MqttMessageSubscriber {
if (config.length() > 0) {
try {
component = ComponentFactory.createComponent(thingUID, haID, config, updateListener, tracker, scheduler,
- gson, newStyleChannels);
+ gson, jinjava, newStyleChannels);
component.setConfigSeen();
logger.trace("Found HomeAssistant component {}", haID);
diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/HomeAssistantChannelState.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/HomeAssistantChannelState.java
index 16fb5303dac..84afd134883 100644
--- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/HomeAssistantChannelState.java
+++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/HomeAssistantChannelState.java
@@ -22,6 +22,7 @@ import org.openhab.binding.mqtt.generic.ChannelState;
import org.openhab.binding.mqtt.generic.ChannelStateUpdateListener;
import org.openhab.binding.mqtt.generic.values.Value;
import org.openhab.core.thing.ChannelUID;
+import org.openhab.core.thing.binding.generic.ChannelTransformation;
import org.openhab.core.types.Command;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,9 +49,11 @@ public class HomeAssistantChannelState extends ChannelState {
* false
ignored. Can be null
to publish all commands.
*/
public HomeAssistantChannelState(ChannelConfig config, ChannelUID channelUID, Value cachedValue,
- @Nullable ChannelStateUpdateListener channelStateUpdateListener,
- @Nullable Predicate commandFilter) {
- super(config, channelUID, cachedValue, channelStateUpdateListener);
+ @Nullable ChannelStateUpdateListener channelStateUpdateListener, @Nullable Predicate commandFilter,
+ @Nullable ChannelTransformation incomingTransformation,
+ @Nullable ChannelTransformation outgoingTransformation) {
+ super(config, channelUID, cachedValue, channelStateUpdateListener, incomingTransformation,
+ outgoingTransformation);
this.commandFilter = commandFilter;
}
diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/HomeAssistantChannelTransformation.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/HomeAssistantChannelTransformation.java
new file mode 100644
index 00000000000..3a51c77bf2d
--- /dev/null
+++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/HomeAssistantChannelTransformation.java
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.mqtt.homeassistant.internal;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.binding.mqtt.homeassistant.internal.component.AbstractComponent;
+import org.openhab.core.thing.binding.generic.ChannelTransformation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.hubspot.jinjava.Jinjava;
+import com.hubspot.jinjava.interpret.FatalTemplateErrorsException;
+
+/**
+ * Provides a channel transformation for a Home Assistant channel with a
+ * Jinja2 template, providing the additional context and extensions required by Home Assistant
+ * Based in part on the JinjaTransformationService
+ *
+ * @author Cody Cutrer - Initial contribution
+ */
+@NonNullByDefault
+public class HomeAssistantChannelTransformation extends ChannelTransformation {
+ private final Logger logger = LoggerFactory.getLogger(HomeAssistantChannelTransformation.class);
+
+ private final Jinjava jinjava;
+ private final AbstractComponent component;
+ private final String template;
+ private final ObjectMapper objectMapper = new ObjectMapper();
+
+ public HomeAssistantChannelTransformation(Jinjava jinjava, AbstractComponent component, String template) {
+ super((String) null);
+ this.jinjava = jinjava;
+ this.component = component;
+ this.template = template;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return template.isEmpty();
+ }
+
+ @Override
+ public Optional apply(String value) {
+ String transformationResult;
+ Map bindings = new HashMap<>();
+
+ logger.debug("about to transform '{}' by the function '{}'", value, template);
+
+ bindings.put("value", value);
+
+ try {
+ JsonNode tree = objectMapper.readTree(value);
+ bindings.put("value_json", toObject(tree));
+ } catch (IOException e) {
+ // ok, then value_json is null...
+ }
+
+ try {
+ transformationResult = jinjava.render(template, bindings);
+ } catch (FatalTemplateErrorsException e) {
+ logger.warn("Applying template {} for component {} failed: {}", template,
+ component.getHaID().toShortTopic(), e.getMessage());
+ return Optional.empty();
+ }
+
+ logger.debug("transformation resulted in '{}'", transformationResult);
+
+ return Optional.of(transformationResult);
+ }
+
+ private static @Nullable Object toObject(JsonNode node) {
+ switch (node.getNodeType()) {
+ case ARRAY: {
+ List<@Nullable Object> result = new ArrayList<>();
+ for (JsonNode el : node) {
+ result.add(toObject(el));
+ }
+ return result;
+ }
+ case NUMBER:
+ return node.decimalValue();
+ case OBJECT: {
+ Map result = new HashMap<>();
+ Iterator> it = node.fields();
+ while (it.hasNext()) {
+ Entry field = it.next();
+ result.put(field.getKey(), toObject(field.getValue()));
+ }
+ return result;
+ }
+ case STRING:
+ return node.asText();
+ case BOOLEAN:
+ return node.asBoolean();
+ case NULL:
+ default:
+ return null;
+ }
+ }
+}
diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponent.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponent.java
index ccff4d3db0c..131cc81d65c 100644
--- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponent.java
+++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponent.java
@@ -49,6 +49,7 @@ import org.openhab.core.types.CommandDescription;
import org.openhab.core.types.StateDescription;
import com.google.gson.Gson;
+import com.hubspot.jinjava.Jinjava;
/**
* A HomeAssistant component is comparable to a channel group.
@@ -334,6 +335,10 @@ public abstract class AbstractComponent
return componentConfiguration.getGson();
}
+ public Jinjava getJinjava() {
+ return componentConfiguration.getJinjava();
+ }
+
public C getChannelConfiguration() {
return channelConfiguration;
}
diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/ComponentFactory.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/ComponentFactory.java
index 1acc4ac18bd..36e9bbd66bd 100644
--- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/ComponentFactory.java
+++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/ComponentFactory.java
@@ -24,6 +24,7 @@ import org.openhab.binding.mqtt.homeassistant.internal.exception.UnsupportedComp
import org.openhab.core.thing.ThingUID;
import com.google.gson.Gson;
+import com.hubspot.jinjava.Jinjava;
/**
* A factory to create HomeAssistant MQTT components. Those components are specified at:
@@ -46,9 +47,9 @@ public class ComponentFactory {
*/
public static AbstractComponent> createComponent(ThingUID thingUID, HaID haID, String channelConfigurationJSON,
ChannelStateUpdateListener updateListener, AvailabilityTracker tracker, ScheduledExecutorService scheduler,
- Gson gson, boolean newStyleChannels) throws ConfigurationException {
+ Gson gson, Jinjava jinjava, boolean newStyleChannels) throws ConfigurationException {
ComponentConfiguration componentConfiguration = new ComponentConfiguration(thingUID, haID,
- channelConfigurationJSON, gson, updateListener, tracker, scheduler);
+ channelConfigurationJSON, gson, jinjava, updateListener, tracker, scheduler);
switch (haID.component) {
case "alarm_control_panel":
return new AlarmControlPanel(componentConfiguration, newStyleChannels);
@@ -96,6 +97,7 @@ public class ComponentFactory {
private final ChannelStateUpdateListener updateListener;
private final AvailabilityTracker tracker;
private final Gson gson;
+ private final Jinjava jinjava;
private final ScheduledExecutorService scheduler;
/**
@@ -106,13 +108,14 @@ public class ComponentFactory {
* @param configJSON The configuration string
* @param gson A Gson instance
*/
- protected ComponentConfiguration(ThingUID thingUID, HaID haID, String configJSON, Gson gson,
+ protected ComponentConfiguration(ThingUID thingUID, HaID haID, String configJSON, Gson gson, Jinjava jinjava,
ChannelStateUpdateListener updateListener, AvailabilityTracker tracker,
ScheduledExecutorService scheduler) {
this.thingUID = thingUID;
this.haID = haID;
this.configJSON = configJSON;
this.gson = gson;
+ this.jinjava = jinjava;
this.updateListener = updateListener;
this.tracker = tracker;
this.scheduler = scheduler;
@@ -138,6 +141,10 @@ public class ComponentFactory {
return gson;
}
+ public Jinjava getJinjava() {
+ return jinjava;
+ }
+
public AvailabilityTracker getTracker() {
return tracker;
}
diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandler.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandler.java
index fb9e68e862f..8c19ce7efe3 100644
--- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandler.java
+++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandler.java
@@ -59,6 +59,7 @@ import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
+import com.hubspot.jinjava.Jinjava;
/**
* Handles HomeAssistant MQTT object things. Such an HA Object can have multiple HA Components with different instances
@@ -90,6 +91,7 @@ public class HomeAssistantThingHandler extends AbstractMQTTThingHandler
protected final MqttChannelTypeProvider channelTypeProvider;
protected final MqttChannelStateDescriptionProvider stateDescriptionProvider;
protected final ChannelTypeRegistry channelTypeRegistry;
+ protected final Jinjava jinjava;
public final int attributeReceiveTimeout;
protected final DelayedBatchProcessing> delayedProcessing;
protected final DiscoverComponents discoverComponents;
@@ -115,18 +117,20 @@ public class HomeAssistantThingHandler extends AbstractMQTTThingHandler
*/
public HomeAssistantThingHandler(Thing thing, MqttChannelTypeProvider channelTypeProvider,
MqttChannelStateDescriptionProvider stateDescriptionProvider, ChannelTypeRegistry channelTypeRegistry,
- int subscribeTimeout, int attributeReceiveTimeout) {
+ Jinjava jinjava, int subscribeTimeout, int attributeReceiveTimeout) {
super(thing, subscribeTimeout);
this.gson = new GsonBuilder().registerTypeAdapterFactory(new ChannelConfigurationTypeAdapterFactory()).create();
this.channelTypeProvider = channelTypeProvider;
this.stateDescriptionProvider = stateDescriptionProvider;
this.channelTypeRegistry = channelTypeRegistry;
+ this.jinjava = jinjava;
this.attributeReceiveTimeout = attributeReceiveTimeout;
this.delayedProcessing = new DelayedBatchProcessing<>(attributeReceiveTimeout, this, scheduler);
newStyleChannels = "true".equals(thing.getProperties().get("newStyleChannels"));
- this.discoverComponents = new DiscoverComponents(thing.getUID(), scheduler, this, this, gson, newStyleChannels);
+ this.discoverComponents = new DiscoverComponents(thing.getUID(), scheduler, this, this, gson, jinjava,
+ newStyleChannels);
}
@Override
@@ -156,7 +160,7 @@ public class HomeAssistantThingHandler extends AbstractMQTTThingHandler
} else {
try {
component = ComponentFactory.createComponent(thingUID, haID, channelConfigurationJSON, this, this,
- scheduler, gson, newStyleChannels);
+ scheduler, gson, jinjava, newStyleChannels);
if (typeID.equals(MqttBindingConstants.HOMEASSISTANT_MQTT_THING)) {
typeID = calculateThingTypeUID(component);
}
diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/AbstractHomeAssistantTests.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/AbstractHomeAssistantTests.java
index 3e3de4afbff..4ef9d6e2668 100644
--- a/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/AbstractHomeAssistantTests.java
+++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/AbstractHomeAssistantTests.java
@@ -32,7 +32,6 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
-import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
@@ -59,8 +58,6 @@ import org.openhab.core.thing.type.ThingTypeBuilder;
import org.openhab.core.thing.type.ThingTypeRegistry;
import org.openhab.core.transform.TransformationHelper;
import org.openhab.core.transform.TransformationService;
-import org.openhab.transform.jinja.internal.JinjaTransformationService;
-import org.openhab.transform.jinja.internal.profiles.JinjaTransformationProfile;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
@@ -107,14 +104,8 @@ public abstract class AbstractHomeAssistantTests extends JavaTest {
private @NonNullByDefault({}) TransformationHelper transformationHelper;
- private final JinjaTransformationService jinjaTransformationService = new JinjaTransformationService();
-
@BeforeEach
public void beforeEachAbstractHomeAssistantTests() {
- Mockito.when(serviceRefMock.getProperty(any())).thenReturn(JinjaTransformationProfile.PROFILE_TYPE_UID.getId());
-
- Mockito.when(bundleContextMock.getService(serviceRefMock)).thenReturn(jinjaTransformationService);
-
transformationHelper = new TransformationHelper(bundleContextMock);
transformationHelper.setTransformationService(serviceRefMock);
diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponentTests.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponentTests.java
index bc63d783ea1..dc7d2b1ef1d 100644
--- a/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponentTests.java
+++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/AbstractComponentTests.java
@@ -49,6 +49,8 @@ import org.openhab.core.thing.type.ChannelTypeRegistry;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
+import com.hubspot.jinjava.Jinjava;
+
/**
* Abstract class for components tests.
*
@@ -288,8 +290,8 @@ public abstract class AbstractComponentTests extends AbstractHomeAssistantTests
public LatchThingHandler(Thing thing, MqttChannelTypeProvider channelTypeProvider,
MqttChannelStateDescriptionProvider stateDescriptionProvider, ChannelTypeRegistry channelTypeRegistry,
int subscribeTimeout, int attributeReceiveTimeout) {
- super(thing, channelTypeProvider, stateDescriptionProvider, channelTypeRegistry, subscribeTimeout,
- attributeReceiveTimeout);
+ super(thing, channelTypeProvider, stateDescriptionProvider, channelTypeRegistry, new Jinjava(),
+ subscribeTimeout, attributeReceiveTimeout);
}
@Override
diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandlerTests.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandlerTests.java
index acf5990420c..ab469881547 100644
--- a/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandlerTests.java
+++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/handler/HomeAssistantThingHandlerTests.java
@@ -39,6 +39,8 @@ import org.openhab.core.thing.Channel;
import org.openhab.core.thing.binding.ThingHandlerCallback;
import org.openhab.core.types.StateDescription;
+import com.hubspot.jinjava.Jinjava;
+
/**
* Tests for {@link HomeAssistantThingHandler}
*
@@ -75,7 +77,7 @@ public class HomeAssistantThingHandlerTests extends AbstractHomeAssistantTests {
when(callbackMock.getBridge(eq(BRIDGE_UID))).thenReturn(bridgeThing);
thingHandler = new HomeAssistantThingHandler(haThing, channelTypeProvider, stateDescriptionProvider,
- channelTypeRegistry, SUBSCRIBE_TIMEOUT, ATTRIBUTE_RECEIVE_TIMEOUT);
+ channelTypeRegistry, new Jinjava(), SUBSCRIBE_TIMEOUT, ATTRIBUTE_RECEIVE_TIMEOUT);
thingHandler.setConnection(bridgeConnection);
thingHandler.setCallback(callbackMock);
nonSpyThingHandler = thingHandler;
diff --git a/features/openhab-addons/src/main/resources/footer.xml b/features/openhab-addons/src/main/resources/footer.xml
index df421579366..383959548d4 100644
--- a/features/openhab-addons/src/main/resources/footer.xml
+++ b/features/openhab-addons/src/main/resources/footer.xml
@@ -22,6 +22,10 @@
openhab-runtime-base
openhab-transport-mqtt
+ openhab.tp-commons-net
+ mvn:org.openhab.osgiify/com.hubspot.jinjava.jinjava/2.7.2_0
+ mvn:org.openhab.osgiify/com.google.re2j.re2j/1.2
+ mvn:ch.obermuhlner/big-math/2.3.2
mvn:org.openhab.addons.bundles/org.openhab.binding.mqtt/${project.version}
mvn:org.openhab.addons.bundles/org.openhab.binding.mqtt.espmilighthub/${project.version}
mvn:org.openhab.addons.bundles/org.openhab.binding.mqtt.generic/${project.version}
diff --git a/itests/org.openhab.binding.mqtt.homeassistant.tests/itest.bndrun b/itests/org.openhab.binding.mqtt.homeassistant.tests/itest.bndrun
index 226f765ca26..b6d41e1a2e8 100644
--- a/itests/org.openhab.binding.mqtt.homeassistant.tests/itest.bndrun
+++ b/itests/org.openhab.binding.mqtt.homeassistant.tests/itest.bndrun
@@ -116,4 +116,18 @@ Import-Package: \
org.openhab.core.io.transport.mqtt;version='[4.3.0,4.3.1)',\
org.openhab.core.test;version='[4.3.0,4.3.1)',\
org.openhab.core.thing;version='[4.3.0,4.3.1)',\
- org.openhab.core.transform;version='[4.3.0,4.3.1)'
+ org.openhab.core.transform;version='[4.3.0,4.3.1)',\
+ ch.obermuhlner.math.big;version='[2.3.2,2.3.3)',\
+ com.fasterxml.jackson.core.jackson-annotations;version='[2.17.1,2.17.2)',\
+ com.fasterxml.jackson.core.jackson-core;version='[2.17.1,2.17.2)',\
+ com.fasterxml.jackson.core.jackson-databind;version='[2.17.1,2.17.2)',\
+ com.fasterxml.jackson.dataformat.jackson-dataformat-yaml;version='[2.17.1,2.17.2)',\
+ com.google.guava;version='[33.2.0,33.2.1)',\
+ com.google.guava.failureaccess;version='[1.0.2,1.0.3)',\
+ com.google.re2j.re2j;version='[1.2.0,1.2.1)',\
+ com.hubspot.jinjava.jinjava;version='[2.7.2,2.7.3)',\
+ javassist;version='[3.29.2,3.29.3)',\
+ org.apache.commons.commons-net;version='[3.9.0,3.9.1)',\
+ org.apache.commons.lang3;version='[3.14.0,3.14.1)',\
+ org.osgi.service.cm;version='[1.6.0,1.6.1)',\
+ org.yaml.snakeyaml;version='[2.2.0,2.2.1)'
diff --git a/itests/org.openhab.binding.mqtt.homeassistant.tests/src/main/java/org/openhab/binding/mqtt/homeassistant/DiscoverComponentsTest.java b/itests/org.openhab.binding.mqtt.homeassistant.tests/src/main/java/org/openhab/binding/mqtt/homeassistant/DiscoverComponentsTest.java
index 5ab82f8347b..903c94a00d7 100644
--- a/itests/org.openhab.binding.mqtt.homeassistant.tests/src/main/java/org/openhab/binding/mqtt/homeassistant/DiscoverComponentsTest.java
+++ b/itests/org.openhab.binding.mqtt.homeassistant.tests/src/main/java/org/openhab/binding/mqtt/homeassistant/DiscoverComponentsTest.java
@@ -46,6 +46,7 @@ import org.openhab.core.test.java.JavaOSGiTest;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
+import com.hubspot.jinjava.Jinjava;
/**
* Tests the {@link DiscoverComponents} class.
@@ -79,9 +80,10 @@ public class DiscoverComponentsTest extends JavaOSGiTest {
ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(1);
Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ChannelConfigurationTypeAdapterFactory()).create();
+ Jinjava jinjava = new Jinjava();
DiscoverComponents discover = spy(new DiscoverComponents(ThingChannelConstants.TEST_HOME_ASSISTANT_THING,
- scheduler, channelStateUpdateListener, availabilityTracker, gson, true));
+ scheduler, channelStateUpdateListener, availabilityTracker, gson, jinjava, true));
HandlerConfiguration config = new HandlerConfiguration("homeassistant", List.of("switch/object"));
diff --git a/itests/org.openhab.binding.mqtt.homeassistant.tests/src/main/java/org/openhab/binding/mqtt/homeassistant/HomeAssistantMQTTImplementationTest.java b/itests/org.openhab.binding.mqtt.homeassistant.tests/src/main/java/org/openhab/binding/mqtt/homeassistant/HomeAssistantMQTTImplementationTest.java
index 04a732c9296..2f273661d3b 100644
--- a/itests/org.openhab.binding.mqtt.homeassistant.tests/src/main/java/org/openhab/binding/mqtt/homeassistant/HomeAssistantMQTTImplementationTest.java
+++ b/itests/org.openhab.binding.mqtt.homeassistant.tests/src/main/java/org/openhab/binding/mqtt/homeassistant/HomeAssistantMQTTImplementationTest.java
@@ -57,6 +57,7 @@ import org.openhab.core.types.UnDefType;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
+import com.hubspot.jinjava.Jinjava;
/**
* A full implementation test, that starts the embedded MQTT broker and publishes a homeassistant MQTT discovery device
@@ -143,10 +144,11 @@ public class HomeAssistantMQTTImplementationTest extends MqttOSGiTest {
final Map> haComponents = new HashMap<>();
Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ChannelConfigurationTypeAdapterFactory()).create();
+ Jinjava jinjava = new Jinjava();
ScheduledExecutorService scheduler = new ScheduledThreadPoolExecutor(4);
DiscoverComponents discover = spy(new DiscoverComponents(ThingChannelConstants.TEST_HOME_ASSISTANT_THING,
- scheduler, channelStateUpdateListener, availabilityTracker, gson, true));
+ scheduler, channelStateUpdateListener, availabilityTracker, gson, jinjava, true));
// The DiscoverComponents object calls ComponentDiscovered callbacks.
// In the following implementation we add the found component to the `haComponents` map