]> git.basschouten.com Git - openhab-addons.git/blob
37bf0214eb0290b54aa1c99d4c67ae0ab6b6ca92
[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.digitalstrom.internal;
14
15 import static org.openhab.binding.digitalstrom.internal.DigitalSTROMBindingConstants.*;
16
17 import java.util.HashMap;
18 import java.util.Map;
19
20 import org.apache.commons.lang.StringUtils;
21 import org.openhab.binding.digitalstrom.internal.discovery.DiscoveryServiceManager;
22 import org.openhab.binding.digitalstrom.internal.handler.BridgeHandler;
23 import org.openhab.binding.digitalstrom.internal.handler.CircuitHandler;
24 import org.openhab.binding.digitalstrom.internal.handler.DeviceHandler;
25 import org.openhab.binding.digitalstrom.internal.handler.SceneHandler;
26 import org.openhab.binding.digitalstrom.internal.handler.ZoneTemperatureControlHandler;
27 import org.openhab.binding.digitalstrom.internal.lib.manager.ConnectionManager;
28 import org.openhab.binding.digitalstrom.internal.lib.manager.impl.ConnectionManagerImpl;
29 import org.openhab.binding.digitalstrom.internal.lib.serverconnection.constants.JSONApiResponseKeysEnum;
30 import org.openhab.core.config.core.Configuration;
31 import org.openhab.core.thing.Bridge;
32 import org.openhab.core.thing.Thing;
33 import org.openhab.core.thing.ThingTypeUID;
34 import org.openhab.core.thing.ThingUID;
35 import org.openhab.core.thing.binding.BaseThingHandlerFactory;
36 import org.openhab.core.thing.binding.ThingHandler;
37 import org.openhab.core.thing.binding.ThingHandlerFactory;
38 import org.osgi.service.component.annotations.Component;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
41
42 /**
43  * The {@link DigitalSTROMHandlerFactory} is responsible for creating things and thing
44  * handlers.
45  *
46  * @author Michael Ochel - Initial contribution
47  * @author Mathias Siegele - Initial contribution
48  */
49 @Component(service = ThingHandlerFactory.class, configurationPid = "binding.digitalstrom")
50 public class DigitalSTROMHandlerFactory extends BaseThingHandlerFactory {
51
52     private final Logger logger = LoggerFactory.getLogger(DigitalSTROMHandlerFactory.class);
53     private final Map<String, DiscoveryServiceManager> discoveryServiceManagers = new HashMap<>();
54
55     private Map<ThingUID, BridgeHandler> bridgeHandlers;
56
57     @Override
58     public boolean supportsThingType(ThingTypeUID thingTypeUID) {
59         return BridgeHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)
60                 || SceneHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)
61                 || DeviceHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)
62                 || ZoneTemperatureControlHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)
63                 || CircuitHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID);
64     }
65
66     @Override
67     public Thing createThing(ThingTypeUID thingTypeUID, Configuration configuration, ThingUID thingUID,
68             ThingUID bridgeUID) {
69         if (BridgeHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
70             ThingUID dSSUID = getBridgeThingUID(thingTypeUID, thingUID, configuration);
71             if (dSSUID != null) {
72                 return super.createThing(thingTypeUID, configuration, dSSUID, null);
73             } else {
74                 logger.error("Can't generate thing UID for thing type {}"
75                         + ", because digitalSTROM-Server is not reachable. Please check these points:\n"
76                         + "Are the server address and portnumber correct?\n" + "Is the server turned on?\n"
77                         + "Is the network configured correctly?", thingTypeUID);
78                 return null;
79             }
80         }
81
82         if (DeviceHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
83             ThingUID dsDeviceUID = getDeviceUID(thingTypeUID, thingUID, configuration, bridgeUID);
84             return super.createThing(thingTypeUID, configuration, dsDeviceUID, bridgeUID);
85         }
86
87         if (CircuitHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
88             ThingUID dsDeviceUID = getDeviceUID(thingTypeUID, thingUID, configuration, bridgeUID);
89             return super.createThing(thingTypeUID, configuration, dsDeviceUID, bridgeUID);
90         }
91
92         if (ZoneTemperatureControlHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
93             ThingUID zoneTempConUID = getZoneTemperatureControlUID(thingTypeUID, thingUID, configuration, bridgeUID);
94             return super.createThing(thingTypeUID, configuration, zoneTempConUID, bridgeUID);
95         }
96
97         if (SceneHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
98             ThingUID dsSceneUID = getSceneUID(thingTypeUID, thingUID, configuration, bridgeUID);
99             return super.createThing(thingTypeUID, configuration, dsSceneUID, bridgeUID);
100         }
101         throw new IllegalArgumentException(
102                 "The thing type " + thingTypeUID + " is not supported by the digitalSTROM binding.");
103     }
104
105     @Override
106     protected ThingHandler createHandler(Thing thing) {
107         ThingTypeUID thingTypeUID = thing.getThingTypeUID();
108
109         if (BridgeHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
110             BridgeHandler handler = new BridgeHandler((Bridge) thing);
111             if (bridgeHandlers == null) {
112                 bridgeHandlers = new HashMap<>();
113             }
114             bridgeHandlers.put(thing.getUID(), handler);
115             DiscoveryServiceManager discoveryServiceManager = new DiscoveryServiceManager(handler);
116             discoveryServiceManager.registerDiscoveryServices(bundleContext);
117             discoveryServiceManagers.put(handler.getThing().getUID().getAsString(), discoveryServiceManager);
118             return handler;
119         }
120
121         if (DeviceHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
122             return new DeviceHandler(thing);
123         }
124
125         if (CircuitHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
126             return new CircuitHandler(thing);
127         }
128
129         if (ZoneTemperatureControlHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
130             return new ZoneTemperatureControlHandler(thing);
131         }
132
133         if (SceneHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
134             return new SceneHandler(thing);
135         }
136         return null;
137     }
138
139     private ThingUID getDeviceUID(ThingTypeUID thingTypeUID, ThingUID thingUID, Configuration configuration,
140             ThingUID bridgeUID) {
141         if (thingUID == null && StringUtils.isNotBlank((String) configuration.get(DEVICE_DSID))) {
142             return new ThingUID(thingTypeUID, bridgeUID, configuration.get(DEVICE_DSID).toString());
143         }
144         return thingUID;
145     }
146
147     private ThingUID getZoneTemperatureControlUID(ThingTypeUID thingTypeUID, ThingUID thingUID,
148             Configuration configuration, ThingUID bridgeUID) {
149         if (thingUID == null) {
150             Integer zoneID = ZoneTemperatureControlHandler.getZoneID(configuration, bridgeHandlers.get(bridgeUID));
151             if (zoneID > ZoneTemperatureControlHandler.ZONE_ID_NOT_EXISTS) {
152                 return new ThingUID(thingTypeUID, bridgeUID, zoneID.toString());
153             } else {
154                 switch (zoneID) {
155                     case ZoneTemperatureControlHandler.ZONE_ID_NOT_EXISTS:
156                         logger.error("Configured zone '{}' does not exist, please check your configuration.",
157                                 configuration.get(DigitalSTROMBindingConstants.ZONE_ID));
158                         break;
159                     case ZoneTemperatureControlHandler.ZONE_ID_NOT_SET:
160                         logger.error("ZoneID is missing at your configuration.");
161                         break;
162                     case ZoneTemperatureControlHandler.BRIDGE_IS_NULL:
163                         logger.error("Bridge is missing, can not check the zoneID.");
164                         break;
165                 }
166             }
167         }
168         return thingUID;
169     }
170
171     private ThingUID getSceneUID(ThingTypeUID thingTypeUID, ThingUID thingUID, Configuration configuration,
172             ThingUID bridgeUID) {
173         if (thingUID != null) {
174             return thingUID;
175         }
176         String sceneID = SceneHandler.getSceneID(configuration, bridgeHandlers.get(bridgeUID));
177         switch (sceneID) {
178             case SceneHandler.SCENE_WRONG:
179                 logger.error(
180                         "Configured scene '{}' does not exist or can not be used, please check your configuration.",
181                         configuration.get(DigitalSTROMBindingConstants.SCENE_ID));
182                 break;
183             case SceneHandler.ZONE_WRONG:
184                 logger.error("Configured zone '{}' does not exist, please check your configuration.",
185                         configuration.get(DigitalSTROMBindingConstants.ZONE_ID));
186                 break;
187             case SceneHandler.GROUP_WRONG:
188                 logger.error("Configured group '{}' does not exist, please check your configuration.",
189                         configuration.get(DigitalSTROMBindingConstants.GROUP_ID));
190                 break;
191             case SceneHandler.NO_STRUC_MAN:
192                 logger.error("Waiting for building digitalSTROM model.");
193                 break;
194             case SceneHandler.NO_SCENE:
195                 logger.error("No Scene-ID is set!");
196                 break;
197             case SceneHandler.NO_BRIDGE:
198                 logger.error("No related bridge found!");
199             default:
200                 return new ThingUID(thingTypeUID, bridgeUID, sceneID);
201         }
202         return thingUID;
203     }
204
205     private ThingUID getBridgeThingUID(ThingTypeUID thingTypeUID, ThingUID thingUID, Configuration configuration) {
206         if (thingUID != null) {
207             return thingUID;
208         }
209         String dSID;
210         if (StringUtils.isBlank((String) configuration.get(DS_ID))) {
211             dSID = getDSSid(configuration);
212             if (dSID != null) {
213                 configuration.put(DS_ID, dSID);
214             }
215         } else {
216             dSID = configuration.get(DS_ID).toString();
217         }
218         if (dSID != null) {
219             return new ThingUID(thingTypeUID, dSID);
220         } else {
221             return null;
222         }
223     }
224
225     private String getDSSid(Configuration configuration) {
226         String dSID = null;
227         if (StringUtils.isNotBlank((String) configuration.get(HOST))) {
228             String host = configuration.get(HOST).toString();
229             String applicationToken = null;
230             String user = null;
231             String pw = null;
232
233             if (StringUtils.isNotBlank((String) configuration.get(APPLICATION_TOKEN))) {
234                 applicationToken = configuration.get(APPLICATION_TOKEN).toString();
235             }
236
237             if (checkUserPassword(configuration)) {
238                 user = configuration.get(USER_NAME).toString();
239                 pw = configuration.get(PASSWORD).toString();
240             }
241             ConnectionManager connMan = new ConnectionManagerImpl(host, user, pw, applicationToken, false, true);
242             Map<String, String> dsidMap = connMan.getDigitalSTROMAPI().getDSID(connMan.getSessionToken());
243             if (dsidMap != null) {
244                 dSID = dsidMap.get(JSONApiResponseKeysEnum.DSID.getKey());
245             }
246         }
247         return dSID;
248     }
249
250     private boolean checkUserPassword(Configuration configuration) {
251         return StringUtils.isNotBlank((String) configuration.get(USER_NAME))
252                 && StringUtils.isNotBlank((String) configuration.get(PASSWORD));
253     }
254
255     @Override
256     protected synchronized void removeHandler(ThingHandler thingHandler) {
257         if (thingHandler instanceof BridgeHandler) {
258             String uid = thingHandler.getThing().getUID().getAsString();
259             if (discoveryServiceManagers.get(uid) != null) {
260                 discoveryServiceManagers.get(uid).unregisterDiscoveryServices(bundleContext);
261                 discoveryServiceManagers.remove(uid);
262             }
263         }
264     }
265 }