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<>();
List<Channel> channels = new ArrayList<>();
channelsDto.forEach((channelId, channelDto) -> {
ChannelTypeUID channelTypeUID = null;
ChannelKind kind = channelDto.getKind();
String itemType = channelDto.getItemType();
String label = channelDto.label;
String description = channelDto.description;
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();
ChannelTypeUID channelTypeUID = channelDto.type == null ? null
: new ChannelTypeUID(thingUID.getBindingId(), channelDto.type);
Channel channel = createChannel(thingUID, channelId, channelTypeUID, channelDto.getKind(),
channelDto.getItemType(), channelDto.label, channelDto.description, null,
new Configuration(channelDto.config), true);
channels.add(channel);
addedChannelIds.add(channelId);
});
@ -440,6 +405,49 @@ public class YamlThingProvider extends AbstractProvider<Thing>
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) {
String label = source.getLabel();
if (label == null) {
@ -463,7 +471,16 @@ public class YamlThingProvider extends AbstractProvider<Thing>
targetChannel.getConfiguration().put(paramName, channel.getConfiguration().get(paramName));
});
} 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);
}
});