diff --git a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/handler/DeviceThingHandler.java b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/handler/DeviceThingHandler.java index 040e16a72..2b6402529 100644 --- a/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/handler/DeviceThingHandler.java +++ b/bundles/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/handler/DeviceThingHandler.java @@ -27,6 +27,8 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import javax.measure.Unit; + import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.knx.internal.KNXBindingConstants; @@ -38,6 +40,7 @@ import org.openhab.binding.knx.internal.client.InboundSpec; import org.openhab.binding.knx.internal.client.KNXClient; import org.openhab.binding.knx.internal.client.OutboundSpec; import org.openhab.binding.knx.internal.config.DeviceConfig; +import org.openhab.binding.knx.internal.dpt.DPTUnits; import org.openhab.binding.knx.internal.dpt.DPTUtil; import org.openhab.binding.knx.internal.dpt.ValueDecoder; import org.openhab.binding.knx.internal.i18n.KNXTranslationProvider; @@ -51,11 +54,15 @@ import org.openhab.core.thing.ThingStatus; import org.openhab.core.thing.ThingStatusDetail; import org.openhab.core.thing.ThingStatusInfo; import org.openhab.core.thing.binding.BaseThingHandler; +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.types.Command; import org.openhab.core.types.RefreshType; import org.openhab.core.types.State; import org.openhab.core.types.Type; import org.openhab.core.types.UnDefType; +import org.openhab.core.types.util.UnitUtils; import org.openhab.core.util.HexUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -99,15 +106,56 @@ public class DeviceThingHandler extends BaseThingHandler implements GroupAddress @Override public void initialize() { - attachToClient(); DeviceConfig config = getConfigAs(DeviceConfig.class); readInterval = config.getReadInterval(); + // gather all GAs from channel configurations and create channels - getThing().getChannels().forEach(channel -> { + ThingBuilder thingBuilder = editThing(); + boolean modified = false; + ThingHandlerCallback callback = getCallback(); + if (callback == null) { + updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE, "Framework failure: callback must not be null"); + return; + } + + for (Channel channel : getThing().getChannels()) { KNXChannel knxChannel = KNXChannelFactory.createKnxChannel(channel); knxChannels.put(channel.getUID(), knxChannel); groupAddresses.addAll(knxChannel.getAllGroupAddresses()); - }); + + if (knxChannel.getChannelType().startsWith("number")) { + // check if we need to update the accepted item-type + List inboundSpecs = knxChannel.getAllGroupAddresses().stream() + .map(knxChannel::getListenSpec).filter(Objects::nonNull).map(Objects::requireNonNull).toList(); + + String dpt = inboundSpecs.get(0).getDPT(); // there can be only one DPT on number channels + Unit unit = UnitUtils.parseUnit(DPTUnits.getUnitForDpt(dpt)); + 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(), Objects.requireNonNull(channel.getChannelTypeUID())) + .withAcceptedItemType(expectedItemType).withConfiguration(channel.getConfiguration()); + if (channel.getLabel() != null) { + channelBuilder.withLabel(Objects.requireNonNull(channel.getLabel())); + } + if (channel.getDescription() != null) { + channelBuilder.withDescription(Objects.requireNonNull(channel.getDescription())); + } + thingBuilder.withoutChannel(channel.getUID()); + thingBuilder.withChannel(channelBuilder.build()); + modified = true; + } + } + } + + if (modified) { + updateThing(thingBuilder.build()); + } + + attachToClient(); } @Override