]> git.basschouten.com Git - openhab-addons.git/blob
ff5b0f0623f2367f4ae571c91bec62b36b6612d8
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.amazonechocontrol.internal;
14
15 import static org.openhab.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.SUPPORTED_ECHO_THING_TYPES_UIDS;
16 import static org.openhab.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.SUPPORTED_SMART_HOME_THING_TYPES_UIDS;
17 import static org.openhab.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.THING_TYPE_ACCOUNT;
18 import static org.openhab.binding.amazonechocontrol.internal.AmazonEchoControlBindingConstants.THING_TYPE_FLASH_BRIEFING_PROFILE;
19
20 import java.util.ArrayList;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.Hashtable;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27
28 import org.eclipse.jdt.annotation.NonNullByDefault;
29 import org.eclipse.jdt.annotation.Nullable;
30 import org.openhab.binding.amazonechocontrol.internal.discovery.AmazonEchoDiscovery;
31 import org.openhab.binding.amazonechocontrol.internal.discovery.SmartHomeDevicesDiscovery;
32 import org.openhab.binding.amazonechocontrol.internal.handler.AccountHandler;
33 import org.openhab.binding.amazonechocontrol.internal.handler.EchoHandler;
34 import org.openhab.binding.amazonechocontrol.internal.handler.FlashBriefingProfileHandler;
35 import org.openhab.binding.amazonechocontrol.internal.handler.SmartHomeDeviceHandler;
36 import org.openhab.core.config.discovery.AbstractDiscoveryService;
37 import org.openhab.core.config.discovery.DiscoveryService;
38 import org.openhab.core.storage.Storage;
39 import org.openhab.core.storage.StorageService;
40 import org.openhab.core.thing.Bridge;
41 import org.openhab.core.thing.Thing;
42 import org.openhab.core.thing.ThingTypeUID;
43 import org.openhab.core.thing.ThingUID;
44 import org.openhab.core.thing.binding.BaseThingHandlerFactory;
45 import org.openhab.core.thing.binding.ThingHandler;
46 import org.openhab.core.thing.binding.ThingHandlerFactory;
47 import org.osgi.framework.ServiceRegistration;
48 import org.osgi.service.component.ComponentContext;
49 import org.osgi.service.component.annotations.Activate;
50 import org.osgi.service.component.annotations.Component;
51 import org.osgi.service.component.annotations.Reference;
52 import org.osgi.service.http.HttpService;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
55
56 import com.google.gson.Gson;
57
58 /**
59  * The {@link AmazonEchoControlHandlerFactory} is responsible for creating things and thing
60  * handlers.
61  *
62  * @author Michael Geramb - Initial contribution
63  */
64 @Component(service = { ThingHandlerFactory.class,
65         AmazonEchoControlHandlerFactory.class }, configurationPid = "binding.amazonechocontrol")
66 @NonNullByDefault
67 public class AmazonEchoControlHandlerFactory extends BaseThingHandlerFactory {
68     private final Logger logger = LoggerFactory.getLogger(AmazonEchoControlHandlerFactory.class);
69     private final Map<ThingUID, @Nullable List<ServiceRegistration<?>>> discoveryServiceRegistrations = new HashMap<>();
70
71     private final Set<AccountHandler> accountHandlers = new HashSet<>();
72     private final HttpService httpService;
73     private final StorageService storageService;
74     private final BindingServlet bindingServlet;
75     private final Gson gson;
76
77     @Activate
78     public AmazonEchoControlHandlerFactory(@Reference HttpService httpService,
79             @Reference StorageService storageService) {
80         this.storageService = storageService;
81         this.httpService = httpService;
82         this.gson = new Gson();
83         this.bindingServlet = new BindingServlet(httpService);
84     }
85
86     @Override
87     public boolean supportsThingType(ThingTypeUID thingTypeUID) {
88         return SUPPORTED_ECHO_THING_TYPES_UIDS.contains(thingTypeUID)
89                 || SUPPORTED_SMART_HOME_THING_TYPES_UIDS.contains(thingTypeUID);
90     }
91
92     @Override
93     protected void deactivate(ComponentContext componentContext) {
94         bindingServlet.dispose();
95         super.deactivate(componentContext);
96     }
97
98     @Override
99     protected @Nullable ThingHandler createHandler(Thing thing) {
100         ThingTypeUID thingTypeUID = thing.getThingTypeUID();
101
102         if (thingTypeUID.equals(THING_TYPE_ACCOUNT)) {
103             Storage<String> storage = storageService.getStorage(thing.getUID().toString(),
104                     String.class.getClassLoader());
105             AccountHandler bridgeHandler = new AccountHandler((Bridge) thing, httpService, storage, gson);
106             accountHandlers.add(bridgeHandler);
107             registerDiscoveryService(bridgeHandler);
108             bindingServlet.addAccountThing(thing);
109             return bridgeHandler;
110         } else if (thingTypeUID.equals(THING_TYPE_FLASH_BRIEFING_PROFILE)) {
111             Storage<String> storage = storageService.getStorage(thing.getUID().toString(),
112                     String.class.getClassLoader());
113             return new FlashBriefingProfileHandler(thing, storage);
114         } else if (SUPPORTED_ECHO_THING_TYPES_UIDS.contains(thingTypeUID)) {
115             return new EchoHandler(thing, gson);
116         } else if (SUPPORTED_SMART_HOME_THING_TYPES_UIDS.contains(thingTypeUID)) {
117             return new SmartHomeDeviceHandler(thing, gson);
118         }
119         return null;
120     }
121
122     private synchronized void registerDiscoveryService(AccountHandler bridgeHandler) {
123         List<ServiceRegistration<?>> discoveryServiceRegistration = discoveryServiceRegistrations
124                 .computeIfAbsent(bridgeHandler.getThing().getUID(), k -> new ArrayList<>());
125         SmartHomeDevicesDiscovery smartHomeDevicesDiscovery = new SmartHomeDevicesDiscovery(bridgeHandler);
126         smartHomeDevicesDiscovery.activate();
127         discoveryServiceRegistration.add(bundleContext.registerService(DiscoveryService.class.getName(),
128                 smartHomeDevicesDiscovery, new Hashtable<>()));
129
130         AmazonEchoDiscovery discoveryService = new AmazonEchoDiscovery(bridgeHandler);
131         discoveryService.activate();
132         discoveryServiceRegistration.add(
133                 bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()));
134     }
135
136     @Override
137     protected synchronized void removeHandler(ThingHandler thingHandler) {
138         if (thingHandler instanceof AccountHandler) {
139             accountHandlers.remove(thingHandler);
140             BindingServlet bindingServlet = this.bindingServlet;
141             bindingServlet.removeAccountThing(thingHandler.getThing());
142
143             List<ServiceRegistration<?>> discoveryServiceRegistration = discoveryServiceRegistrations
144                     .remove(thingHandler.getThing().getUID());
145             if (discoveryServiceRegistration != null) {
146                 discoveryServiceRegistration.forEach(serviceReg -> {
147                     AbstractDiscoveryService service = (AbstractDiscoveryService) bundleContext
148                             .getService(serviceReg.getReference());
149                     serviceReg.unregister();
150                     if (service != null) {
151                         if (service instanceof AmazonEchoDiscovery) {
152                             ((AmazonEchoDiscovery) service).deactivate();
153                         } else if (service instanceof SmartHomeDevicesDiscovery) {
154                             ((SmartHomeDevicesDiscovery) service).deactivate();
155                         } else {
156                             logger.warn("Found unknown discovery-service instance: {}", service);
157                         }
158                     }
159                 });
160             }
161         }
162     }
163
164     public Set<AccountHandler> getAccountHandlers() {
165         return accountHandlers;
166     }
167 }