]> git.basschouten.com Git - openhab-addons.git/commitdiff
[mqtt] Dynamically change accepted item-type for Number channels (#15114)
authorJ-N-K <github@klug.nrw>
Fri, 21 Jul 2023 09:47:51 +0000 (11:47 +0200)
committerGitHub <noreply@github.com>
Fri, 21 Jul 2023 09:47:51 +0000 (11:47 +0200)
Signed-off-by: Jan N. Klug <github@klug.nrw>
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/test/java/org/openhab/binding/mqtt/generic/internal/handler/ThingChannelConstants.java

index 32a006add1468e5690f077af7e8039f11b5fa4d5..9a88492eecccd1bfeb369a944f0474c8f1da8cfd 100644 (file)
@@ -20,6 +20,8 @@ import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.stream.Collectors;
 
+import javax.measure.Unit;
+
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.mqtt.generic.AbstractMQTTThingHandler;
@@ -28,6 +30,7 @@ import org.openhab.binding.mqtt.generic.ChannelState;
 import org.openhab.binding.mqtt.generic.ChannelStateUpdateListener;
 import org.openhab.binding.mqtt.generic.MqttChannelStateDescriptionProvider;
 import org.openhab.binding.mqtt.generic.TransformationServiceProvider;
+import org.openhab.binding.mqtt.generic.internal.MqttBindingConstants;
 import org.openhab.binding.mqtt.generic.utils.FutureCollector;
 import org.openhab.binding.mqtt.generic.values.Value;
 import org.openhab.binding.mqtt.generic.values.ValueFactory;
@@ -37,8 +40,12 @@ import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingStatus;
 import org.openhab.core.thing.ThingStatusDetail;
+import org.openhab.core.thing.binding.ThingHandlerCallback;
+import org.openhab.core.thing.binding.builder.ChannelBuilder;
+import org.openhab.core.thing.binding.builder.ThingBuilder;
 import org.openhab.core.thing.type.ChannelTypeUID;
 import org.openhab.core.types.StateDescription;
+import org.openhab.core.types.util.UnitUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -136,6 +143,15 @@ public class GenericMQTTThingHandler extends AbstractMQTTThingHandler implements
     public void initialize() {
         initializeAvailabilityTopicsFromConfig();
 
+        ThingHandlerCallback callback = getCallback();
+        if (callback == null) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE, "Framework failure: callback must not be null");
+            return;
+        }
+
+        ThingBuilder thingBuilder = editThing();
+        boolean modified = false;
+
         List<ChannelUID> configErrors = new ArrayList<>();
         for (Channel channel : thing.getChannels()) {
             final ChannelTypeUID channelTypeUID = channel.getChannelTypeUID();
@@ -144,6 +160,31 @@ public class GenericMQTTThingHandler extends AbstractMQTTThingHandler implements
                 continue;
             }
             final ChannelConfig channelConfig = channel.getConfiguration().as(ChannelConfig.class);
+
+            if (channelTypeUID
+                    .equals(new ChannelTypeUID(MqttBindingConstants.BINDING_ID, MqttBindingConstants.NUMBER))) {
+                Unit<?> unit = UnitUtils.parseUnit(channelConfig.unit);
+                String dimension = unit == null ? null : UnitUtils.getDimensionName(unit);
+                String expectedItemType = dimension == null ? "Number" : "Number:" + dimension; // unknown dimension ->
+                // Number
+                String actualItemType = channel.getAcceptedItemType();
+                if (!expectedItemType.equals(actualItemType)) {
+                    ChannelBuilder channelBuilder = callback.createChannelBuilder(channel.getUID(), channelTypeUID)
+                            .withAcceptedItemType(expectedItemType).withConfiguration(channel.getConfiguration());
+                    String label = channel.getLabel();
+                    if (label != null) {
+                        channelBuilder.withLabel(label);
+                    }
+                    String description = channel.getDescription();
+                    if (description != null) {
+                        channelBuilder.withDescription(description);
+                    }
+                    thingBuilder.withoutChannel(channel.getUID());
+                    thingBuilder.withChannel(channelBuilder.build());
+                    modified = true;
+                }
+            }
+
             try {
                 Value value = ValueFactory.createValueState(channelConfig, channelTypeUID.getId());
                 ChannelState channelState = createChannelState(channelConfig, channel.getUID(), value);
@@ -159,6 +200,10 @@ public class GenericMQTTThingHandler extends AbstractMQTTThingHandler implements
             }
         }
 
+        if (modified) {
+            updateThing(thingBuilder.build());
+        }
+
         // If some channels could not start up, put the entire thing offline and display the channels
         // in question to the user.
         if (!configErrors.isEmpty()) {
index 57c672893d217d576739a9bb2ddfc503e2e7b43d..c5a8a6e566e09ce8627527a3e0fdc942d3cc64fc 100644 (file)
@@ -70,16 +70,16 @@ public class ThingChannelConstants {
     }
 
     static {
-        THING_CHANNEL_LIST.add(cb("mytext", "TextItemType", textConfiguration(), TEXT_CHANNEL));
-        THING_CHANNEL_LIST.add(cb("onoff", "OnOffType", onoffConfiguration(), ON_OFF_CHANNEL));
-        THING_CHANNEL_LIST.add(cb("num", "NumberType", numberConfiguration(), NUMBER_CHANNEL));
-        THING_CHANNEL_LIST.add(cb("percent", "NumberType", percentageConfiguration(), PERCENTAGE_CHANNEL));
-
+        THING_CHANNEL_LIST.add(cb("mytext", "String", textConfiguration(), TEXT_CHANNEL));
+        THING_CHANNEL_LIST.add(cb("onoff", "Switch", onoffConfiguration(), ON_OFF_CHANNEL));
+        THING_CHANNEL_LIST.add(cb("num", "Number", numberConfiguration(), NUMBER_CHANNEL));
+        THING_CHANNEL_LIST.add(cb("percent", "Number:Dimensionless", percentageConfiguration(), PERCENTAGE_CHANNEL));
+
+        THING_CHANNEL_LIST_WITH_JSON.add(cb("mytext", "String", textConfigurationWithJson(), TEXT_WITH_JSON_CHANNEL));
+        THING_CHANNEL_LIST_WITH_JSON.add(cb("onoff", "Switch", onoffConfiguration(), ON_OFF_CHANNEL));
+        THING_CHANNEL_LIST_WITH_JSON.add(cb("num", "Number", numberConfiguration(), NUMBER_CHANNEL));
         THING_CHANNEL_LIST_WITH_JSON
-                .add(cb("mytext", "TextItemType", textConfigurationWithJson(), TEXT_WITH_JSON_CHANNEL));
-        THING_CHANNEL_LIST_WITH_JSON.add(cb("onoff", "OnOffType", onoffConfiguration(), ON_OFF_CHANNEL));
-        THING_CHANNEL_LIST_WITH_JSON.add(cb("num", "NumberType", numberConfiguration(), NUMBER_CHANNEL));
-        THING_CHANNEL_LIST_WITH_JSON.add(cb("percent", "NumberType", percentageConfiguration(), PERCENTAGE_CHANNEL));
+                .add(cb("percent", "Number:Dimensionless", percentageConfiguration(), PERCENTAGE_CHANNEL));
     }
 
     static Configuration textConfiguration() {