]> git.basschouten.com Git - openhab-addons.git/blob
5ada1988aa90abfc3e65ebd5cb2c4d538c90e57b
[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.mihome.internal;
14
15 import static org.openhab.binding.mihome.internal.XiaomiGatewayBindingConstants.*;
16
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.Hashtable;
20 import java.util.Map;
21 import java.util.Set;
22 import java.util.stream.Collectors;
23 import java.util.stream.Stream;
24
25 import org.openhab.binding.mihome.internal.discovery.XiaomiItemDiscoveryService;
26 import org.openhab.binding.mihome.internal.handler.XiaomiActorCurtainHandler;
27 import org.openhab.binding.mihome.internal.handler.XiaomiActorGatewayHandler;
28 import org.openhab.binding.mihome.internal.handler.XiaomiActorPlugHandler;
29 import org.openhab.binding.mihome.internal.handler.XiaomiAqaraActorSwitch1Handler;
30 import org.openhab.binding.mihome.internal.handler.XiaomiAqaraActorSwitch2Handler;
31 import org.openhab.binding.mihome.internal.handler.XiaomiAqaraSensorSwitch1Handler;
32 import org.openhab.binding.mihome.internal.handler.XiaomiAqaraSensorSwitch2Handler;
33 import org.openhab.binding.mihome.internal.handler.XiaomiBridgeHandler;
34 import org.openhab.binding.mihome.internal.handler.XiaomiDeviceBaseHandler;
35 import org.openhab.binding.mihome.internal.handler.XiaomiSensorCubeHandler;
36 import org.openhab.binding.mihome.internal.handler.XiaomiSensorGasHandler;
37 import org.openhab.binding.mihome.internal.handler.XiaomiSensorHtHandler;
38 import org.openhab.binding.mihome.internal.handler.XiaomiSensorLockHandler;
39 import org.openhab.binding.mihome.internal.handler.XiaomiSensorMagnetHandler;
40 import org.openhab.binding.mihome.internal.handler.XiaomiSensorMotionHandler;
41 import org.openhab.binding.mihome.internal.handler.XiaomiSensorSmokeHandler;
42 import org.openhab.binding.mihome.internal.handler.XiaomiSensorSwitchHandler;
43 import org.openhab.binding.mihome.internal.handler.XiaomiSensorVibrationHandler;
44 import org.openhab.binding.mihome.internal.handler.XiaomiSensorWaterHandler;
45 import org.openhab.core.config.core.Configuration;
46 import org.openhab.core.config.discovery.DiscoveryService;
47 import org.openhab.core.thing.Bridge;
48 import org.openhab.core.thing.Thing;
49 import org.openhab.core.thing.ThingTypeUID;
50 import org.openhab.core.thing.ThingUID;
51 import org.openhab.core.thing.binding.BaseThingHandlerFactory;
52 import org.openhab.core.thing.binding.ThingHandler;
53 import org.openhab.core.thing.binding.ThingHandlerFactory;
54 import org.osgi.framework.ServiceRegistration;
55 import org.osgi.service.component.annotations.Component;
56
57 /**
58  * The {@link XiaomiHandlerFactory} is responsible for creating things and thing
59  * handlers.
60  *
61  * @author Patrick Boos - Initial contribution
62  * @author Dieter Schmidt - Refactor, add devices
63  * @author Daniel Walters - Added Aqara Door/Window sensor and Aqara temperature, humidity and pressure sensor
64  * @author Kuba Wolanin - Added Water Leak sensor and Aqara motion sensor
65  */
66 @Component(service = ThingHandlerFactory.class, configurationPid = "binding.mihome")
67 public class XiaomiHandlerFactory extends BaseThingHandlerFactory {
68
69     private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections
70             .unmodifiableSet(Stream.concat(XiaomiBridgeHandler.SUPPORTED_THING_TYPES.stream(),
71                     XiaomiDeviceBaseHandler.SUPPORTED_THING_TYPES.stream()).collect(Collectors.toSet()));
72
73     private Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
74
75     @Override
76     public Thing createThing(ThingTypeUID thingTypeUID, Configuration configuration, ThingUID thingUID,
77             ThingUID bridgeUID) {
78         if (XiaomiBridgeHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
79             ThingUID newBridgeUID = getBridgeThingUID(thingTypeUID, thingUID, configuration);
80             return super.createThing(thingTypeUID, configuration, newBridgeUID, null);
81         } else if (XiaomiDeviceBaseHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
82             ThingUID newThingUID = getThingUID(thingTypeUID, thingUID, configuration, bridgeUID);
83             return super.createThing(thingTypeUID, configuration, newThingUID, bridgeUID);
84         }
85         throw new IllegalArgumentException(
86                 "The thing type " + thingTypeUID + " is not supported by the mihome binding.");
87     }
88
89     @Override
90     public boolean supportsThingType(ThingTypeUID thingTypeUID) {
91         return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
92     }
93
94     private ThingUID getBridgeThingUID(ThingTypeUID thingTypeUID, ThingUID thingUID, Configuration configuration) {
95         if (thingUID == null) {
96             String serialNumber = (String) configuration.get(SERIAL_NUMBER);
97             return new ThingUID(thingTypeUID, serialNumber);
98         }
99         return thingUID;
100     }
101
102     private ThingUID getThingUID(ThingTypeUID thingTypeUID, ThingUID thingUID, Configuration configuration,
103             ThingUID bridgeUID) {
104         if (thingUID == null) {
105             String itemId = (String) configuration.get(ITEM_ID);
106             return new ThingUID(thingTypeUID, itemId, bridgeUID.getId());
107         }
108         return thingUID;
109     }
110
111     @Override
112     protected ThingHandler createHandler(Thing thing) {
113         ThingTypeUID thingTypeUID = thing.getThingTypeUID();
114
115         if (THING_TYPE_BRIDGE.equals(thingTypeUID)) {
116             XiaomiBridgeHandler handler = new XiaomiBridgeHandler((Bridge) thing);
117             registerItemDiscoveryService(handler);
118             return handler;
119         } else if (THING_TYPE_GATEWAY.equals(thingTypeUID)) {
120             return new XiaomiActorGatewayHandler(thing);
121         } else if (THING_TYPE_SENSOR_HT.equals(thingTypeUID)) {
122             return new XiaomiSensorHtHandler(thing);
123         } else if (THING_TYPE_SENSOR_MOTION.equals(thingTypeUID)) {
124             return new XiaomiSensorMotionHandler(thing);
125         } else if (THING_TYPE_SENSOR_SWITCH.equals(thingTypeUID)) {
126             return new XiaomiSensorSwitchHandler(thing);
127         } else if (THING_TYPE_SENSOR_AQARA_SWITCH.equals(thingTypeUID)) {
128             return new XiaomiSensorSwitchHandler(thing);
129         } else if (THING_TYPE_SENSOR_MAGNET.equals(thingTypeUID)) {
130             return new XiaomiSensorMagnetHandler(thing);
131         } else if (THING_TYPE_SENSOR_CUBE.equals(thingTypeUID)) {
132             return new XiaomiSensorCubeHandler(thing);
133         } else if (THING_TYPE_SENSOR_SMOKE.equals(thingTypeUID)) {
134             return new XiaomiSensorSmokeHandler(thing);
135         } else if (THING_TYPE_SENSOR_GAS.equals(thingTypeUID)) {
136             return new XiaomiSensorGasHandler(thing);
137         } else if (THING_TYPE_SENSOR_WATER.equals(thingTypeUID)) {
138             return new XiaomiSensorWaterHandler(thing);
139         } else if (THING_TYPE_SENSOR_AQARA1.equals(thingTypeUID)) {
140             return new XiaomiAqaraSensorSwitch1Handler(thing);
141         } else if (THING_TYPE_SENSOR_AQARA2.equals(thingTypeUID)) {
142             return new XiaomiAqaraSensorSwitch2Handler(thing);
143         } else if (THING_TYPE_ACTOR_AQARA1.equals(thingTypeUID)) {
144             return new XiaomiAqaraActorSwitch1Handler(thing);
145         } else if (THING_TYPE_ACTOR_AQARA2.equals(thingTypeUID)) {
146             return new XiaomiAqaraActorSwitch2Handler(thing);
147         } else if (THING_TYPE_ACTOR_PLUG.equals(thingTypeUID)) {
148             return new XiaomiActorPlugHandler(thing);
149         } else if (THING_TYPE_ACTOR_AQARA_ZERO1.equals(thingTypeUID)) {
150             return new XiaomiAqaraActorSwitch1Handler(thing);
151         } else if (THING_TYPE_ACTOR_AQARA_ZERO2.equals(thingTypeUID)) {
152             return new XiaomiAqaraActorSwitch2Handler(thing);
153         } else if (THING_TYPE_ACTOR_CURTAIN.equals(thingTypeUID)) {
154             return new XiaomiActorCurtainHandler(thing);
155         } else if (THING_TYPE_SENSOR_AQARA_WEATHER_V1.equals(thingTypeUID)) {
156             return new XiaomiSensorHtHandler(thing);
157         } else if (THING_TYPE_SENSOR_AQARA_MAGNET.equals(thingTypeUID)) {
158             return new XiaomiSensorMagnetHandler(thing);
159         } else if (THING_TYPE_SENSOR_AQARA_MOTION.equals(thingTypeUID)) {
160             return new XiaomiSensorMotionHandler(thing);
161         } else if (THING_TYPE_SENSOR_AQARA_VIBRATION.equals(thingTypeUID)) {
162             return new XiaomiSensorVibrationHandler(thing);
163         } else if (THING_TYPE_SENSOR_AQARA_LOCK.equals(thingTypeUID)) {
164             return new XiaomiSensorLockHandler(thing);
165         } else if (THING_TYPE_BASIC.equals(thingTypeUID)) {
166             return new XiaomiDeviceBaseHandler(thing);
167         } else {
168             return null;
169         }
170     }
171
172     @Override
173     protected synchronized void removeHandler(ThingHandler thingHandler) {
174         if (thingHandler instanceof XiaomiBridgeHandler) {
175             ServiceRegistration<?> serviceReg = this.discoveryServiceRegs.remove(thingHandler.getThing().getUID());
176             if (serviceReg != null) {
177                 // remove discovery service, if bridge handler is removed
178                 XiaomiItemDiscoveryService service = (XiaomiItemDiscoveryService) bundleContext
179                         .getService(serviceReg.getReference());
180                 serviceReg.unregister();
181                 if (service != null) {
182                     service.onHandlerRemoved();
183                     service.deactivate();
184                 }
185             }
186         }
187     }
188
189     private synchronized void registerItemDiscoveryService(XiaomiBridgeHandler bridgeHandler) {
190         XiaomiItemDiscoveryService discoveryService = new XiaomiItemDiscoveryService(bridgeHandler);
191         this.discoveryServiceRegs.put(bridgeHandler.getThing().getUID(),
192                 bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()));
193     }
194 }