diff --git a/bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/internal/handler/GenericMQTTThingHandler.java b/bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/internal/handler/GenericMQTTThingHandler.java index 32a006add..9a88492ee 100644 --- a/bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/internal/handler/GenericMQTTThingHandler.java +++ b/bundles/org.openhab.binding.mqtt.generic/src/main/java/org/openhab/binding/mqtt/generic/internal/handler/GenericMQTTThingHandler.java @@ -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 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()) { diff --git a/bundles/org.openhab.binding.mqtt.generic/src/test/java/org/openhab/binding/mqtt/generic/internal/handler/ThingChannelConstants.java b/bundles/org.openhab.binding.mqtt.generic/src/test/java/org/openhab/binding/mqtt/generic/internal/handler/ThingChannelConstants.java index 57c672893..c5a8a6e56 100644 --- a/bundles/org.openhab.binding.mqtt.generic/src/test/java/org/openhab/binding/mqtt/generic/internal/handler/ThingChannelConstants.java +++ b/bundles/org.openhab.binding.mqtt.generic/src/test/java/org/openhab/binding/mqtt/generic/internal/handler/ThingChannelConstants.java @@ -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() {