YAML config: fix user defined channels creation when binding loads late (#4823)

While things can now be loaded even when the binding is not yet available, channel types for user defined channels could be not yet in the registry when these channels are first created.
So when the binding is finally available, the thing is updated and user defined channels are now created again to retrieve properties from channel types.

This fix avoids warnings at startup regarding missing channel types.

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
pull/4826/head
lolodomo 2025-05-25 21:18:17 +02:00 committed by GitHub
parent 26c2631296
commit fb62bf33cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 58 additions and 41 deletions

View File

@ -376,46 +376,11 @@ public class YamlThingProvider extends AbstractProvider<Thing>
Set<String> addedChannelIds = new HashSet<>(); Set<String> addedChannelIds = new HashSet<>();
List<Channel> channels = new ArrayList<>(); List<Channel> channels = new ArrayList<>();
channelsDto.forEach((channelId, channelDto) -> { channelsDto.forEach((channelId, channelDto) -> {
ChannelTypeUID channelTypeUID = null; ChannelTypeUID channelTypeUID = channelDto.type == null ? null
ChannelKind kind = channelDto.getKind(); : new ChannelTypeUID(thingUID.getBindingId(), channelDto.type);
String itemType = channelDto.getItemType(); Channel channel = createChannel(thingUID, channelId, channelTypeUID, channelDto.getKind(),
String label = channelDto.label; channelDto.getItemType(), channelDto.label, channelDto.description, null,
String description = channelDto.description; new Configuration(channelDto.config), true);
AutoUpdatePolicy autoUpdatePolicy = null;
Configuration configuration = new Configuration(channelDto.config);
if (channelDto.type != null) {
channelTypeUID = new ChannelTypeUID(thingUID.getBindingId(), channelDto.type);
ChannelType channelType = channelTypeRegistry.getChannelType(channelTypeUID,
localeProvider.getLocale());
if (channelType != null) {
kind = channelType.getKind();
itemType = channelType.getItemType();
if (label == null) {
label = channelType.getLabel();
}
if (description == null) {
description = channelType.getDescription();
}
autoUpdatePolicy = channelType.getAutoUpdatePolicy();
URI descUriO = channelType.getConfigDescriptionURI();
if (descUriO != null) {
ConfigUtil.applyDefaultConfiguration(configuration,
configDescriptionRegistry.getConfigDescription(descUriO));
}
} else {
logger.warn("Channel type {} could not be found for thing '{}'.", channelTypeUID, thingUID);
}
}
ChannelBuilder builder = ChannelBuilder.create(new ChannelUID(thingUID, channelId), itemType).withKind(kind)
.withConfiguration(configuration).withType(channelTypeUID).withAutoUpdatePolicy(autoUpdatePolicy);
if (label != null) {
builder.withLabel(label);
}
if (description != null) {
builder.withDescription(description);
}
Channel channel = builder.build();
channels.add(channel); channels.add(channel);
addedChannelIds.add(channelId); addedChannelIds.add(channelId);
}); });
@ -440,6 +405,49 @@ public class YamlThingProvider extends AbstractProvider<Thing>
return channels; return channels;
} }
private Channel createChannel(ThingUID thingUID, String channelId, @Nullable ChannelTypeUID channelTypeUID,
ChannelKind channelKind, @Nullable String channelItemType, @Nullable String channelLabel,
@Nullable String channelDescription, @Nullable AutoUpdatePolicy channelAutoUpdatePolicy,
Configuration channelConfiguration, boolean ignoreMissingChannelType) {
ChannelKind kind = channelKind;
String itemType = channelItemType;
String label = channelLabel;
String description = channelDescription;
AutoUpdatePolicy autoUpdatePolicy = channelAutoUpdatePolicy;
Configuration configuration = new Configuration(channelConfiguration);
if (channelTypeUID != null) {
ChannelType channelType = channelTypeRegistry.getChannelType(channelTypeUID, localeProvider.getLocale());
if (channelType != null) {
kind = channelType.getKind();
itemType = channelType.getItemType();
if (label == null) {
label = channelType.getLabel();
}
if (description == null) {
description = channelType.getDescription();
}
autoUpdatePolicy = channelType.getAutoUpdatePolicy();
URI descUriO = channelType.getConfigDescriptionURI();
if (descUriO != null) {
ConfigUtil.applyDefaultConfiguration(configuration,
configDescriptionRegistry.getConfigDescription(descUriO));
}
} else if (!ignoreMissingChannelType) {
logger.warn("Channel type {} could not be found for thing '{}'.", channelTypeUID, thingUID);
}
}
ChannelBuilder builder = ChannelBuilder.create(new ChannelUID(thingUID, channelId), itemType).withKind(kind)
.withConfiguration(configuration).withType(channelTypeUID).withAutoUpdatePolicy(autoUpdatePolicy);
if (label != null) {
builder.withLabel(label);
}
if (description != null) {
builder.withDescription(description);
}
return builder.build();
}
private void mergeThing(Thing target, Thing source) { private void mergeThing(Thing target, Thing source) {
String label = source.getLabel(); String label = source.getLabel();
if (label == null) { if (label == null) {
@ -463,7 +471,16 @@ public class YamlThingProvider extends AbstractProvider<Thing>
targetChannel.getConfiguration().put(paramName, channel.getConfiguration().get(paramName)); targetChannel.getConfiguration().put(paramName, channel.getConfiguration().get(paramName));
}); });
} else { } else {
channelsToAdd.add(channel); Channel newChannel = channel;
if (channel.getChannelTypeUID() != null) {
// We create again the user defined channel because channel type was potentially not yet
// in the registry when the channel was initially created
newChannel = createChannel(target.getUID(), channel.getUID().getIdWithoutGroup(),
channel.getChannelTypeUID(), channel.getKind(), channel.getAcceptedItemType(),
channel.getLabel(), channel.getDescription(), channel.getAutoUpdatePolicy(),
channel.getConfiguration(), false);
}
channelsToAdd.add(newChannel);
} }
}); });