*/
package org.openhab.binding.remoteopenhab.internal;
+import static org.openhab.binding.remoteopenhab.internal.RemoteopenhabBindingConstants.BINDING_ID;
+
import java.util.Collection;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.type.ChannelType;
import org.openhab.core.thing.type.ChannelTypeProvider;
import org.openhab.core.thing.type.ChannelTypeUID;
+import org.openhab.core.types.StateDescription;
import org.osgi.service.component.annotations.Component;
/**
@NonNullByDefault
public class RemoteopenhabChannelTypeProvider implements ChannelTypeProvider {
private final List<ChannelType> channelTypes = new CopyOnWriteArrayList<>();
+ private final Map<String, List<ChannelType>> channelTypesForItemTypes = new ConcurrentHashMap<>();
@Override
public Collection<ChannelType> getChannelTypes(@Nullable Locale locale) {
return null;
}
- public void addChannelType(ChannelType type) {
- channelTypes.add(type);
+ public @Nullable ChannelType getChannelType(String itemType, boolean readOnly, String pattern) {
+ List<ChannelType> channelTypesForItemType = channelTypesForItemTypes.get(itemType);
+ if (channelTypesForItemType != null) {
+ for (ChannelType channelType : channelTypesForItemType) {
+ boolean channelTypeReadOnly = false;
+ String channelTypePattern = null;
+ StateDescription stateDescription = channelType.getState();
+ if (stateDescription != null) {
+ channelTypeReadOnly = stateDescription.isReadOnly();
+ channelTypePattern = stateDescription.getPattern();
+ }
+ if (channelTypePattern == null) {
+ channelTypePattern = "";
+ }
+ if (channelTypeReadOnly == readOnly && channelTypePattern.equals(pattern)) {
+ return channelType;
+ }
+ }
+ }
+ return null;
+ }
+
+ public ChannelTypeUID buildNewChannelTypeUID(String itemType) {
+ List<ChannelType> channelTypesForItemType = channelTypesForItemTypes.get(itemType);
+ int nb = channelTypesForItemType == null ? 0 : channelTypesForItemType.size();
+ return new ChannelTypeUID(BINDING_ID, String.format("item%s%d", itemType.replace(":", ""), nb + 1));
}
- public void removeChannelType(ChannelType type) {
- channelTypes.remove(type);
+ public void addChannelType(String itemType, ChannelType channelType) {
+ channelTypes.add(channelType);
+ List<ChannelType> channelTypesForItemType = channelTypesForItemTypes.computeIfAbsent(itemType,
+ type -> new CopyOnWriteArrayList<>());
+ if (channelTypesForItemType != null) {
+ channelTypesForItemType.add(channelType);
+ }
+ }
+
+ public void removeChannelType(String itemType, ChannelType channelType) {
+ channelTypes.remove(channelType);
+ List<ChannelType> channelTypesForItemType = channelTypesForItemTypes.get(itemType);
+ if (channelTypesForItemType != null) {
+ channelTypesForItemType.remove(channelType);
+ }
}
}
*/
package org.openhab.binding.remoteopenhab.internal.handler;
-import static org.openhab.binding.remoteopenhab.internal.RemoteopenhabBindingConstants.BINDING_ID;
-
import java.net.MalformedURLException;
import java.net.URL;
import java.time.ZonedDateTime;
synchronized (updateThingLock) {
try {
int nbGroups = 0;
+ int nbChannelTypesCreated = 0;
List<Channel> channels = new ArrayList<>();
for (RemoteopenhabItem item : items) {
String itemType = item.type;
readOnly = true;
}
}
- String channelTypeId = String.format("item%s%s", itemType.replace(":", ""), readOnly ? "RO" : "");
- ChannelTypeUID channelTypeUID = new ChannelTypeUID(BINDING_ID, channelTypeId);
- ChannelType channelType = channelTypeProvider.getChannelType(channelTypeUID, null);
+ // Ignore pattern containing a transformation (detected by a parenthesis in the pattern)
+ RemoteopenhabStateDescription stateDescription = item.stateDescription;
+ String pattern = (stateDescription == null || stateDescription.pattern.contains("(")) ? ""
+ : stateDescription.pattern;
+ ChannelTypeUID channelTypeUID;
+ ChannelType channelType = channelTypeProvider.getChannelType(itemType, readOnly, pattern);
String label;
String description;
if (channelType == null) {
- logger.trace("Create the channel type {} for item type {}", channelTypeUID, itemType);
+ channelTypeUID = channelTypeProvider.buildNewChannelTypeUID(itemType);
+ logger.trace("Create the channel type {} for item type {} ({} and with pattern {})",
+ channelTypeUID, itemType, readOnly ? "read only" : "read write", pattern);
label = String.format("Remote %s Item", itemType);
description = String.format("An item of type %s from the remote server.", itemType);
+ StateDescriptionFragmentBuilder stateDescriptionBuilder = StateDescriptionFragmentBuilder
+ .create().withReadOnly(readOnly);
+ if (!pattern.isEmpty()) {
+ stateDescriptionBuilder = stateDescriptionBuilder.withPattern(pattern);
+ }
channelType = ChannelTypeBuilder.state(channelTypeUID, label, itemType)
.withDescription(description)
- .withStateDescriptionFragment(
- StateDescriptionFragmentBuilder.create().withReadOnly(readOnly).build())
+ .withStateDescriptionFragment(stateDescriptionBuilder.build())
.withAutoUpdatePolicy(AutoUpdatePolicy.VETO).build();
- channelTypeProvider.addChannelType(channelType);
+ channelTypeProvider.addChannelType(itemType, channelType);
+ nbChannelTypesCreated++;
+ } else {
+ channelTypeUID = channelType.getUID();
}
ChannelUID channelUID = new ChannelUID(getThing().getUID(), item.name);
logger.trace("Create the channel {} of type {}", channelUID, channelTypeUID);
if (replace) {
thingBuilder.withChannels(channels);
updateThing(thingBuilder.build());
- logger.debug("{} channels defined for the thing {} (from {} items including {} groups)",
- channels.size(), getThing().getUID(), items.size(), nbGroups);
+ logger.debug(
+ "{} channels defined (with {} different channel types) for the thing {} (from {} items including {} groups)",
+ channels.size(), nbChannelTypesCreated, getThing().getUID(), items.size(), nbGroups);
} else if (channels.size() > 0) {
int nbRemoved = 0;
for (Channel channel : channels) {