]> git.basschouten.com Git - openhab-addons.git/blob
2e1d0f1b65f95140de4aca1cec1ac2d7a6c55944
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.netatmo.internal;
14
15 import static org.openhab.binding.netatmo.internal.NetatmoBindingConstants.*;
16
17 import java.util.Dictionary;
18 import java.util.HashMap;
19 import java.util.Hashtable;
20 import java.util.Map;
21
22 import javax.servlet.http.HttpServlet;
23
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;
60
61 /**
62  * The {@link NetatmoHandlerFactory} is responsible for creating things and
63  * thing handlers.
64  *
65  * @author GaĆ«l L'hopital - Initial contribution
66  */
67 @NonNullByDefault
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;
79
80     @Activate
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;
90     }
91
92     @Override
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();
99         } else {
100             backgroundDiscovery = false;
101         }
102         logger.debug("backgroundDiscovery {}", backgroundDiscovery);
103     }
104
105     @Override
106     public boolean supportsThingType(ThingTypeUID thingTypeUID) {
107         return (SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID));
108     }
109
110     @Override
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);
142         } else {
143             logger.warn("ThingHandler not found for {}", thing.getThingTypeUID());
144             return null;
145         }
146     }
147
148     @Override
149     protected void removeHandler(ThingHandler thingHandler) {
150         if (thingHandler instanceof NetatmoBridgeHandler) {
151             ThingUID thingUID = thingHandler.getThing().getUID();
152             unregisterDeviceDiscoveryService(thingUID);
153             unregisterWebHookServlet(thingUID);
154         }
155     }
156
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<>()));
167         }
168     }
169
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();
178             }
179         }
180     }
181
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<>()));
188         }
189         return servlet;
190     }
191
192     private synchronized void unregisterWebHookServlet(ThingUID thingUID) {
193         ServiceRegistration<?> serviceReg = webHookServiceRegs.remove(thingUID);
194         if (serviceReg != null) {
195             serviceReg.unregister();
196         }
197     }
198 }