2 * Copyright (c) 2010-2024 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.mqtt.generic;
16 import java.util.Collection;
17 import java.util.Locale;
20 import java.util.concurrent.ConcurrentHashMap;
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.openhab.binding.mqtt.generic.internal.MqttThingHandlerFactory;
25 import org.openhab.core.thing.ThingTypeUID;
26 import org.openhab.core.thing.binding.ThingTypeProvider;
27 import org.openhab.core.thing.type.ChannelGroupType;
28 import org.openhab.core.thing.type.ChannelGroupTypeProvider;
29 import org.openhab.core.thing.type.ChannelGroupTypeUID;
30 import org.openhab.core.thing.type.ChannelType;
31 import org.openhab.core.thing.type.ChannelTypeProvider;
32 import org.openhab.core.thing.type.ChannelTypeUID;
33 import org.openhab.core.thing.type.ThingType;
34 import org.openhab.core.thing.type.ThingTypeBuilder;
35 import org.openhab.core.thing.type.ThingTypeRegistry;
36 import org.osgi.service.component.annotations.Activate;
37 import org.osgi.service.component.annotations.Component;
38 import org.osgi.service.component.annotations.Reference;
41 * An MQTT Extension might want to provide additional, dynamic channel types, based on auto-discovery.
43 * Just retrieve the `MqttChannelTypeProvider` OSGi service and add (and remove) your channel types.
45 * This provider is started on-demand only, as soon as {@link MqttThingHandlerFactory} or an extension requires it.
47 * @author David Graeff - Initial contribution
51 @Component(immediate = false, service = { ThingTypeProvider.class, ChannelTypeProvider.class,
52 ChannelGroupTypeProvider.class, MqttChannelTypeProvider.class })
53 public class MqttChannelTypeProvider implements ThingTypeProvider, ChannelGroupTypeProvider, ChannelTypeProvider {
54 private final ThingTypeRegistry typeRegistry;
56 private final Map<ChannelTypeUID, ChannelType> types = new ConcurrentHashMap<>();
57 private final Map<ChannelGroupTypeUID, ChannelGroupType> groups = new ConcurrentHashMap<>();
58 private final Map<ThingTypeUID, ThingType> things = new ConcurrentHashMap<>();
61 public MqttChannelTypeProvider(@Reference ThingTypeRegistry typeRegistry) {
63 this.typeRegistry = typeRegistry;
67 public Collection<ChannelType> getChannelTypes(@Nullable Locale locale) {
68 return types.values();
72 public @Nullable ChannelType getChannelType(ChannelTypeUID channelTypeUID, @Nullable Locale locale) {
73 return types.get(channelTypeUID);
77 public @Nullable ChannelGroupType getChannelGroupType(ChannelGroupTypeUID channelGroupTypeUID,
78 @Nullable Locale locale) {
79 return groups.get(channelGroupTypeUID);
83 public Collection<ChannelGroupType> getChannelGroupTypes(@Nullable Locale locale) {
84 return groups.values();
88 public Collection<ThingType> getThingTypes(@Nullable Locale locale) {
89 return things.values();
92 public Set<ThingTypeUID> getThingTypeUIDs() {
93 return things.keySet();
97 public @Nullable ThingType getThingType(ThingTypeUID thingTypeUID, @Nullable Locale locale) {
98 return things.get(thingTypeUID);
101 public void removeChannelType(ChannelTypeUID uid) {
105 public void removeChannelGroupType(ChannelGroupTypeUID uid) {
109 public void setChannelGroupType(ChannelGroupTypeUID uid, ChannelGroupType type) {
110 groups.put(uid, type);
113 public void setChannelType(ChannelTypeUID uid, ChannelType type) {
114 types.put(uid, type);
117 public void removeThingType(ThingTypeUID uid) {
121 public void setThingType(ThingTypeUID uid, ThingType type) {
122 things.put(uid, type);
125 public void setThingTypeIfAbsent(ThingTypeUID uid, ThingType type) {
126 things.putIfAbsent(uid, type);
129 public ThingTypeBuilder derive(ThingTypeUID newTypeId, ThingTypeUID baseTypeId) {
130 ThingType baseType = typeRegistry.getThingType(baseTypeId);
132 ThingTypeBuilder result = ThingTypeBuilder.instance(newTypeId, baseType.getLabel())
133 .withChannelGroupDefinitions(baseType.getChannelGroupDefinitions())
134 .withChannelDefinitions(baseType.getChannelDefinitions())
135 .withExtensibleChannelTypeIds(baseType.getExtensibleChannelTypeIds())
136 .withSupportedBridgeTypeUIDs(baseType.getSupportedBridgeTypeUIDs())
137 .withProperties(baseType.getProperties()).isListed(false);
139 String representationProperty = baseType.getRepresentationProperty();
140 if (representationProperty != null) {
141 result = result.withRepresentationProperty(representationProperty);
143 URI configDescriptionURI = baseType.getConfigDescriptionURI();
144 if (configDescriptionURI != null) {
145 result = result.withConfigDescriptionURI(configDescriptionURI);
147 String category = baseType.getCategory();
148 if (category != null) {
149 result = result.withCategory(category);
151 String description = baseType.getDescription();
152 if (description != null) {
153 result = result.withDescription(description);