2 * Copyright (c) 2010-2022 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.netatmo.internal;
15 import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
17 import java.util.Dictionary;
18 import java.util.HashMap;
19 import java.util.Hashtable;
22 import javax.servlet.http.HttpServlet;
24 import org.eclipse.jdt.annotation.NonNullByDefault;
25 import org.eclipse.jdt.annotation.Nullable;
26 import org.openhab.binding.netatmo.internal.discovery.NetatmoModuleDiscoveryService;
27 import org.openhab.binding.netatmo.internal.handler.NetatmoBridgeHandler;
28 import org.openhab.binding.netatmo.internal.homecoach.NAHealthyHomeCoachHandler;
29 import org.openhab.binding.netatmo.internal.presence.NAPresenceCameraHandler;
30 import org.openhab.binding.netatmo.internal.station.NAMainHandler;
31 import org.openhab.binding.netatmo.internal.station.NAModule1Handler;
32 import org.openhab.binding.netatmo.internal.station.NAModule2Handler;
33 import org.openhab.binding.netatmo.internal.station.NAModule3Handler;
34 import org.openhab.binding.netatmo.internal.station.NAModule4Handler;
35 import org.openhab.binding.netatmo.internal.thermostat.NAPlugHandler;
36 import org.openhab.binding.netatmo.internal.thermostat.NATherm1Handler;
37 import org.openhab.binding.netatmo.internal.webhook.WelcomeWebHookServlet;
38 import org.openhab.binding.netatmo.internal.welcome.NAWelcomeCameraHandler;
39 import org.openhab.binding.netatmo.internal.welcome.NAWelcomeHomeHandler;
40 import org.openhab.binding.netatmo.internal.welcome.NAWelcomePersonHandler;
41 import org.openhab.core.config.discovery.DiscoveryService;
42 import org.openhab.core.i18n.LocaleProvider;
43 import org.openhab.core.i18n.TimeZoneProvider;
44 import org.openhab.core.i18n.TranslationProvider;
45 import org.openhab.core.thing.Bridge;
46 import org.openhab.core.thing.Thing;
47 import org.openhab.core.thing.ThingTypeUID;
48 import org.openhab.core.thing.ThingUID;
49 import org.openhab.core.thing.binding.BaseThingHandlerFactory;
50 import org.openhab.core.thing.binding.ThingHandler;
51 import org.openhab.core.thing.binding.ThingHandlerFactory;
52 import org.osgi.framework.ServiceRegistration;
53 import org.osgi.service.component.ComponentContext;
54 import org.osgi.service.component.annotations.Activate;
55 import org.osgi.service.component.annotations.Component;
56 import org.osgi.service.component.annotations.Reference;
57 import org.osgi.service.http.HttpService;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
62 * The {@link NetatmoHandlerFactory} is responsible for creating things and
65 * @author Gaƫl L'hopital - Initial contribution
68 @Component(service = ThingHandlerFactory.class, configurationPid = "binding.netatmo")
69 public class NetatmoHandlerFactory extends BaseThingHandlerFactory {
70 private final Logger logger = LoggerFactory.getLogger(NetatmoHandlerFactory.class);
71 private final Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
72 private final Map<ThingUID, ServiceRegistration<?>> webHookServiceRegs = new HashMap<>();
73 private final HttpService httpService;
74 private final NATherm1StateDescriptionProvider stateDescriptionProvider;
75 private final TimeZoneProvider timeZoneProvider;
76 private final LocaleProvider localeProvider;
77 private final TranslationProvider translationProvider;
78 private boolean backgroundDiscovery;
81 public NetatmoHandlerFactory(final @Reference HttpService httpService,
82 final @Reference NATherm1StateDescriptionProvider stateDescriptionProvider,
83 final @Reference TimeZoneProvider timeZoneProvider, final @Reference LocaleProvider localeProvider,
84 final @Reference TranslationProvider translationProvider) {
85 this.httpService = httpService;
86 this.stateDescriptionProvider = stateDescriptionProvider;
87 this.timeZoneProvider = timeZoneProvider;
88 this.localeProvider = localeProvider;
89 this.translationProvider = translationProvider;
93 protected void activate(ComponentContext componentContext) {
94 super.activate(componentContext);
95 Dictionary<String, Object> properties = componentContext.getProperties();
96 Object property = properties.get("backgroundDiscovery");
97 if (property instanceof Boolean) {
98 backgroundDiscovery = ((Boolean) property).booleanValue();
100 backgroundDiscovery = false;
102 logger.debug("backgroundDiscovery {}", backgroundDiscovery);
106 public boolean supportsThingType(ThingTypeUID thingTypeUID) {
107 return (SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID));
111 protected @Nullable ThingHandler createHandler(Thing thing) {
112 ThingTypeUID thingTypeUID = thing.getThingTypeUID();
113 if (thingTypeUID.equals(APIBRIDGE_THING_TYPE)) {
114 WelcomeWebHookServlet servlet = registerWebHookServlet(thing.getUID());
115 NetatmoBridgeHandler bridgeHandler = new NetatmoBridgeHandler((Bridge) thing, servlet);
116 registerDeviceDiscoveryService(bridgeHandler);
117 return bridgeHandler;
118 } else if (thingTypeUID.equals(MODULE1_THING_TYPE)) {
119 return new NAModule1Handler(thing, timeZoneProvider);
120 } else if (thingTypeUID.equals(MODULE2_THING_TYPE)) {
121 return new NAModule2Handler(thing, timeZoneProvider);
122 } else if (thingTypeUID.equals(MODULE3_THING_TYPE)) {
123 return new NAModule3Handler(thing, timeZoneProvider);
124 } else if (thingTypeUID.equals(MODULE4_THING_TYPE)) {
125 return new NAModule4Handler(thing, timeZoneProvider);
126 } else if (thingTypeUID.equals(MAIN_THING_TYPE)) {
127 return new NAMainHandler(thing, timeZoneProvider);
128 } else if (thingTypeUID.equals(HOMECOACH_THING_TYPE)) {
129 return new NAHealthyHomeCoachHandler(thing, timeZoneProvider);
130 } else if (thingTypeUID.equals(PLUG_THING_TYPE)) {
131 return new NAPlugHandler(thing, timeZoneProvider);
132 } else if (thingTypeUID.equals(THERM1_THING_TYPE)) {
133 return new NATherm1Handler(thing, stateDescriptionProvider, timeZoneProvider);
134 } else if (thingTypeUID.equals(WELCOME_HOME_THING_TYPE)) {
135 return new NAWelcomeHomeHandler(thing, timeZoneProvider);
136 } else if (thingTypeUID.equals(WELCOME_CAMERA_THING_TYPE)) {
137 return new NAWelcomeCameraHandler(thing, timeZoneProvider);
138 } else if (thingTypeUID.equals(PRESENCE_CAMERA_THING_TYPE)) {
139 return new NAPresenceCameraHandler(thing, timeZoneProvider);
140 } else if (thingTypeUID.equals(WELCOME_PERSON_THING_TYPE)) {
141 return new NAWelcomePersonHandler(thing, timeZoneProvider);
143 logger.warn("ThingHandler not found for {}", thing.getThingTypeUID());
149 protected void removeHandler(ThingHandler thingHandler) {
150 if (thingHandler instanceof NetatmoBridgeHandler) {
151 ThingUID thingUID = thingHandler.getThing().getUID();
152 unregisterDeviceDiscoveryService(thingUID);
153 unregisterWebHookServlet(thingUID);
157 private synchronized void registerDeviceDiscoveryService(NetatmoBridgeHandler netatmoBridgeHandler) {
158 if (bundleContext != null) {
159 NetatmoModuleDiscoveryService discoveryService = new NetatmoModuleDiscoveryService(netatmoBridgeHandler,
160 localeProvider, translationProvider);
161 Map<String, Object> configProperties = new HashMap<>();
162 configProperties.put(DiscoveryService.CONFIG_PROPERTY_BACKGROUND_DISCOVERY,
163 Boolean.valueOf(backgroundDiscovery));
164 discoveryService.activate(configProperties);
165 discoveryServiceRegs.put(netatmoBridgeHandler.getThing().getUID(), bundleContext
166 .registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()));
170 private synchronized void unregisterDeviceDiscoveryService(ThingUID thingUID) {
171 ServiceRegistration<?> serviceReg = discoveryServiceRegs.remove(thingUID);
172 if (serviceReg != null) {
173 NetatmoModuleDiscoveryService service = (NetatmoModuleDiscoveryService) bundleContext
174 .getService(serviceReg.getReference());
175 serviceReg.unregister();
176 if (service != null) {
177 service.deactivate();
182 private synchronized @Nullable WelcomeWebHookServlet registerWebHookServlet(ThingUID thingUID) {
183 WelcomeWebHookServlet servlet = null;
184 if (bundleContext != null) {
185 servlet = new WelcomeWebHookServlet(httpService, thingUID.getId());
186 webHookServiceRegs.put(thingUID,
187 bundleContext.registerService(HttpServlet.class.getName(), servlet, new Hashtable<>()));
192 private synchronized void unregisterWebHookServlet(ThingUID thingUID) {
193 ServiceRegistration<?> serviceReg = webHookServiceRegs.remove(thingUID);
194 if (serviceReg != null) {
195 serviceReg.unregister();