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