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