2 * Copyright (c) 2010-2021 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.digitalstrom.internal;
15 import static org.openhab.binding.digitalstrom.internal.DigitalSTROMBindingConstants.*;
17 import java.util.HashMap;
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;
43 * The {@link DigitalSTROMHandlerFactory} is responsible for creating things and thing
46 * @author Michael Ochel - Initial contribution
47 * @author Mathias Siegele - Initial contribution
49 @Component(service = ThingHandlerFactory.class, configurationPid = "binding.digitalstrom")
50 public class DigitalSTROMHandlerFactory extends BaseThingHandlerFactory {
52 private final Logger logger = LoggerFactory.getLogger(DigitalSTROMHandlerFactory.class);
53 private final Map<String, DiscoveryServiceManager> discoveryServiceManagers = new HashMap<>();
55 private Map<ThingUID, BridgeHandler> bridgeHandlers;
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);
67 public Thing createThing(ThingTypeUID thingTypeUID, Configuration configuration, ThingUID thingUID,
69 if (BridgeHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
70 ThingUID dSSUID = getBridgeThingUID(thingTypeUID, thingUID, configuration);
72 return super.createThing(thingTypeUID, configuration, dSSUID, null);
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);
82 if (DeviceHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
83 ThingUID dsDeviceUID = getDeviceUID(thingTypeUID, thingUID, configuration, bridgeUID);
84 return super.createThing(thingTypeUID, configuration, dsDeviceUID, bridgeUID);
87 if (CircuitHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
88 ThingUID dsDeviceUID = getDeviceUID(thingTypeUID, thingUID, configuration, bridgeUID);
89 return super.createThing(thingTypeUID, configuration, dsDeviceUID, bridgeUID);
92 if (ZoneTemperatureControlHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
93 ThingUID zoneTempConUID = getZoneTemperatureControlUID(thingTypeUID, thingUID, configuration, bridgeUID);
94 return super.createThing(thingTypeUID, configuration, zoneTempConUID, bridgeUID);
97 if (SceneHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
98 ThingUID dsSceneUID = getSceneUID(thingTypeUID, thingUID, configuration, bridgeUID);
99 return super.createThing(thingTypeUID, configuration, dsSceneUID, bridgeUID);
101 throw new IllegalArgumentException(
102 "The thing type " + thingTypeUID + " is not supported by the digitalSTROM binding.");
106 protected ThingHandler createHandler(Thing thing) {
107 ThingTypeUID thingTypeUID = thing.getThingTypeUID();
109 if (BridgeHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
110 BridgeHandler handler = new BridgeHandler((Bridge) thing);
111 if (bridgeHandlers == null) {
112 bridgeHandlers = new HashMap<>();
114 bridgeHandlers.put(thing.getUID(), handler);
115 DiscoveryServiceManager discoveryServiceManager = new DiscoveryServiceManager(handler);
116 discoveryServiceManager.registerDiscoveryServices(bundleContext);
117 discoveryServiceManagers.put(handler.getThing().getUID().getAsString(), discoveryServiceManager);
121 if (DeviceHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
122 return new DeviceHandler(thing);
125 if (CircuitHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
126 return new CircuitHandler(thing);
129 if (ZoneTemperatureControlHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
130 return new ZoneTemperatureControlHandler(thing);
133 if (SceneHandler.SUPPORTED_THING_TYPES.contains(thingTypeUID)) {
134 return new SceneHandler(thing);
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());
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());
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));
159 case ZoneTemperatureControlHandler.ZONE_ID_NOT_SET:
160 logger.error("ZoneID is missing at your configuration.");
162 case ZoneTemperatureControlHandler.BRIDGE_IS_NULL:
163 logger.error("Bridge is missing, can not check the zoneID.");
171 private ThingUID getSceneUID(ThingTypeUID thingTypeUID, ThingUID thingUID, Configuration configuration,
172 ThingUID bridgeUID) {
173 if (thingUID != null) {
176 String sceneID = SceneHandler.getSceneID(configuration, bridgeHandlers.get(bridgeUID));
178 case SceneHandler.SCENE_WRONG:
180 "Configured scene '{}' does not exist or can not be used, please check your configuration.",
181 configuration.get(DigitalSTROMBindingConstants.SCENE_ID));
183 case SceneHandler.ZONE_WRONG:
184 logger.error("Configured zone '{}' does not exist, please check your configuration.",
185 configuration.get(DigitalSTROMBindingConstants.ZONE_ID));
187 case SceneHandler.GROUP_WRONG:
188 logger.error("Configured group '{}' does not exist, please check your configuration.",
189 configuration.get(DigitalSTROMBindingConstants.GROUP_ID));
191 case SceneHandler.NO_STRUC_MAN:
192 logger.error("Waiting for building digitalSTROM model.");
194 case SceneHandler.NO_SCENE:
195 logger.error("No Scene-ID is set!");
197 case SceneHandler.NO_BRIDGE:
198 logger.error("No related bridge found!");
200 return new ThingUID(thingTypeUID, bridgeUID, sceneID);
205 private ThingUID getBridgeThingUID(ThingTypeUID thingTypeUID, ThingUID thingUID, Configuration configuration) {
206 if (thingUID != null) {
210 if (StringUtils.isBlank((String) configuration.get(DS_ID))) {
211 dSID = getDSSid(configuration);
213 configuration.put(DS_ID, dSID);
216 dSID = configuration.get(DS_ID).toString();
219 return new ThingUID(thingTypeUID, dSID);
225 private String getDSSid(Configuration configuration) {
227 if (StringUtils.isNotBlank((String) configuration.get(HOST))) {
228 String host = configuration.get(HOST).toString();
229 String applicationToken = null;
233 if (StringUtils.isNotBlank((String) configuration.get(APPLICATION_TOKEN))) {
234 applicationToken = configuration.get(APPLICATION_TOKEN).toString();
237 if (checkUserPassword(configuration)) {
238 user = configuration.get(USER_NAME).toString();
239 pw = configuration.get(PASSWORD).toString();
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());
250 private boolean checkUserPassword(Configuration configuration) {
251 return StringUtils.isNotBlank((String) configuration.get(USER_NAME))
252 && StringUtils.isNotBlank((String) configuration.get(PASSWORD));
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);