2 * Copyright (c) 2010-2020 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.velux.internal.factory;
15 import java.util.HashMap;
16 import java.util.HashSet;
17 import java.util.Hashtable;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.core.config.discovery.DiscoveryService;
24 import org.openhab.core.i18n.LocaleProvider;
25 import org.openhab.core.i18n.TranslationProvider;
26 import org.openhab.core.thing.Bridge;
27 import org.openhab.core.thing.Thing;
28 import org.openhab.core.thing.ThingTypeUID;
29 import org.openhab.core.thing.ThingUID;
30 import org.openhab.core.thing.binding.BaseThingHandlerFactory;
31 import org.openhab.core.thing.binding.ThingHandler;
32 import org.openhab.core.thing.binding.ThingHandlerFactory;
33 import org.openhab.binding.velux.internal.VeluxBindingConstants;
34 import org.openhab.binding.velux.internal.discovery.VeluxDiscoveryService;
35 import org.openhab.binding.velux.internal.handler.VeluxBindingHandler;
36 import org.openhab.binding.velux.internal.handler.VeluxBridgeHandler;
37 import org.openhab.binding.velux.internal.handler.VeluxHandler;
38 import org.openhab.binding.velux.internal.utils.Localization;
39 import org.osgi.framework.ServiceRegistration;
40 import org.osgi.service.component.annotations.Activate;
41 import org.osgi.service.component.annotations.Component;
42 import org.osgi.service.component.annotations.Reference;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
47 * The {@link VeluxHandlerFactory} is responsible for creating things and thing
50 * @author Guenther Schreiner - Initial contribution
53 @Component(service = ThingHandlerFactory.class, name = "binding.velux")
54 public class VeluxHandlerFactory extends BaseThingHandlerFactory {
55 private final Logger logger = LoggerFactory.getLogger(VeluxHandlerFactory.class);
59 private final Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegistrations = new HashMap<>();
61 private Set<VeluxBindingHandler> veluxBindingHandlers = new HashSet<>();
62 private Set<VeluxBridgeHandler> veluxBridgeHandlers = new HashSet<>();
63 private Set<VeluxHandler> veluxHandlers = new HashSet<>();
65 private @NonNullByDefault({}) LocaleProvider localeProvider;
66 private @NonNullByDefault({}) TranslationProvider i18nProvider;
67 private Localization localization = Localization.UNKNOWN;
71 private void registerDeviceDiscoveryService(VeluxBridgeHandler bridgeHandler) {
72 VeluxDiscoveryService discoveryService = new VeluxDiscoveryService(bridgeHandler, localization);
73 ServiceRegistration<?> discoveryServiceReg = bundleContext.registerService(DiscoveryService.class.getName(),
74 discoveryService, new Hashtable<>());
75 discoveryServiceRegistrations.put(bridgeHandler.getThing().getUID(), discoveryServiceReg);
78 // Even if the compiler tells, that the value of <remove> cannot be null, it is possible!
79 // Therefore a @SuppressWarnings("null") is needed to suppress the warning
80 @SuppressWarnings("null")
81 private synchronized void unregisterDeviceDiscoveryService(ThingUID thingUID) {
82 logger.trace("unregisterDeviceDiscoveryService({}) called.", thingUID);
83 ServiceRegistration<?> remove = discoveryServiceRegistrations.remove(thingUID);
89 private @Nullable ThingHandler createBindingHandler(Thing thing) {
90 logger.trace("createBindingHandler({}) called for thing named '{}'.", thing.getUID(), thing.getLabel());
91 VeluxBindingHandler veluxBindingHandler = new VeluxBindingHandler(thing, localization);
92 veluxBindingHandlers.add(veluxBindingHandler);
93 return veluxBindingHandler;
96 private @Nullable ThingHandler createBridgeHandler(Thing thing) {
97 logger.trace("createBridgeHandler({}) called for thing named '{}'.", thing.getUID(), thing.getLabel());
98 VeluxBridgeHandler veluxBridgeHandler = new VeluxBridgeHandler((Bridge) thing, localization);
99 veluxBridgeHandlers.add(veluxBridgeHandler);
100 registerDeviceDiscoveryService(veluxBridgeHandler);
101 return veluxBridgeHandler;
104 private @Nullable ThingHandler createThingHandler(Thing thing) {
105 logger.trace("createThingHandler({}) called for thing named '{}'.", thing.getUID(), thing.getLabel());
106 VeluxHandler veluxHandler = new VeluxHandler(thing, localization);
107 veluxHandlers.add(veluxHandler);
111 private void updateBindingState() {
112 veluxBindingHandlers.forEach((VeluxBindingHandler veluxBindingHandler) -> {
113 veluxBindingHandler.updateBindingState(veluxBridgeHandlers.size(), veluxHandlers.size());
117 private void updateLocalization() {
118 if (localization == Localization.UNKNOWN && localeProvider != null && i18nProvider != null) {
119 logger.trace("updateLocalization(): creating Localization based on locale={},translation={}).",
120 localeProvider, i18nProvider);
121 localization = new Localization(localeProvider, i18nProvider);
128 public VeluxHandlerFactory(final @Reference LocaleProvider givenLocaleProvider,
129 final @Reference TranslationProvider givenI18nProvider) {
130 logger.trace("VeluxHandlerFactory(locale={},translation={}) called.", givenLocaleProvider, givenI18nProvider);
131 localeProvider = givenLocaleProvider;
132 i18nProvider = givenI18nProvider;
136 protected void setLocaleProvider(final LocaleProvider givenLocaleProvider) {
137 logger.trace("setLocaleProvider(): provided locale={}.", givenLocaleProvider);
138 localeProvider = givenLocaleProvider;
139 updateLocalization();
143 protected void setTranslationProvider(TranslationProvider givenI18nProvider) {
144 logger.trace("setTranslationProvider(): provided translation={}.", givenI18nProvider);
145 i18nProvider = givenI18nProvider;
146 updateLocalization();
152 public boolean supportsThingType(ThingTypeUID thingTypeUID) {
153 boolean result = VeluxBindingConstants.SUPPORTED_THINGS_BINDING.contains(thingTypeUID)
154 || VeluxBindingConstants.SUPPORTED_THINGS_BRIDGE.contains(thingTypeUID)
155 || VeluxBindingConstants.SUPPORTED_THINGS_ITEMS.contains(thingTypeUID);
156 logger.trace("supportsThingType({}) called and returns {}.", thingTypeUID, result);
161 protected @Nullable ThingHandler createHandler(Thing thing) {
162 ThingHandler resultHandler = null;
163 ThingTypeUID thingTypeUID = thing.getThingTypeUID();
165 // Handle Binding creation
166 if (VeluxBindingConstants.SUPPORTED_THINGS_BINDING.contains(thingTypeUID)) {
167 resultHandler = createBindingHandler(thing);
169 // Handle Bridge creation
170 if (VeluxBindingConstants.SUPPORTED_THINGS_BRIDGE.contains(thingTypeUID)) {
171 resultHandler = createBridgeHandler(thing);
173 // Handle creation of Things behind the Bridge
174 if (VeluxBindingConstants.SUPPORTED_THINGS_ITEMS.contains(thingTypeUID)) {
175 resultHandler = createThingHandler(thing);
177 logger.warn("createHandler({}) failed: ThingHandler not found for {}.", thingTypeUID, thing.getLabel());
179 updateBindingState();
180 return resultHandler;
184 protected void removeHandler(ThingHandler thingHandler) {
185 // Handle Binding removal
186 if (thingHandler instanceof VeluxBindingHandler) {
187 logger.trace("removeHandler() removing information element '{}'.", thingHandler.toString());
188 veluxBindingHandlers.remove(thingHandler);
190 // Handle Bridge removal
191 if (thingHandler instanceof VeluxBridgeHandler) {
192 logger.trace("removeHandler() removing bridge '{}'.", thingHandler.toString());
193 veluxBridgeHandlers.remove(thingHandler);
194 unregisterDeviceDiscoveryService(thingHandler.getThing().getUID());
196 // Handle removal of Things behind the Bridge
197 if (thingHandler instanceof VeluxHandler) {
198 logger.trace("removeHandler() removing thing '{}'.", thingHandler.toString());
199 veluxHandlers.remove(thingHandler);
201 updateBindingState();
202 super.removeHandler(thingHandler);