[knx] dynamic channel-types (#15072)

Signed-off-by: Jan N. Klug <github@klug.nrw>
This commit is contained in:
J-N-K 2023-06-11 21:04:09 +02:00 committed by GitHub
parent 13a036e30d
commit 47eaf63698
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 51 additions and 3 deletions

View File

@ -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<InboundSpec> 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