]> git.basschouten.com Git - openhab-addons.git/blob
c33c4c9d2f7f48a5d8cce7656bf056b1f3f3d393
[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.km200.internal.discovery;
14
15 import static org.openhab.binding.km200.internal.KM200BindingConstants.*;
16
17 import java.util.HashMap;
18 import java.util.Map;
19 import java.util.Set;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.openhab.binding.km200.internal.KM200ServiceObject;
23 import org.openhab.binding.km200.internal.KM200ThingType;
24 import org.openhab.binding.km200.internal.KM200Utils;
25 import org.openhab.binding.km200.internal.handler.KM200GatewayHandler;
26 import org.openhab.binding.km200.internal.handler.KM200GatewayStatusListener;
27 import org.openhab.binding.km200.internal.handler.KM200SwitchProgramServiceHandler;
28 import org.openhab.core.config.discovery.AbstractDiscoveryService;
29 import org.openhab.core.config.discovery.DiscoveryResult;
30 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
31 import org.openhab.core.thing.ThingStatus;
32 import org.openhab.core.thing.ThingUID;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35
36 /**
37  * The {@link KM200GatewayDiscoveryService} class discovers things through a gateway
38  *
39  * @author Markus Eckhardt - Initial contribution
40  */
41 @NonNullByDefault
42 public class KM200GatewayDiscoveryService extends AbstractDiscoveryService implements KM200GatewayStatusListener {
43
44     private final Logger logger = LoggerFactory.getLogger(KM200GatewayDiscoveryService.class);
45
46     private static int timeOut = 120;
47
48     KM200GatewayHandler gateway;
49
50     public KM200GatewayDiscoveryService(KM200GatewayHandler gateway) {
51         super(KM200GatewayHandler.SUPPORTED_THING_TYPES_UIDS, timeOut, true);
52         this.gateway = gateway;
53         this.gateway.addGatewayStatusListener(this);
54     }
55
56     @Override
57     protected void startScan() {
58         discoverDevices();
59     }
60
61     @Override
62     protected void startBackgroundDiscovery() {
63         discoverDevices();
64     }
65
66     @Override
67     public void gatewayStatusChanged(ThingStatus status) {
68         if (status.equals(ThingStatus.ONLINE)) {
69             discoverDevices();
70         }
71     }
72
73     @Override
74     protected void deactivate() {
75         gateway.removeHubStatusListener(this);
76         super.deactivate();
77     }
78
79     /**
80      * Discovers devices connected to a hub
81      */
82     private void discoverDevices() {
83         if (!gateway.getDevice().getInited()) {
84             logger.debug("Gateway not configured, scanning postponed.");
85             return;
86         }
87         ThingUID thingUID = null;
88         ThingUID bridgeUID = gateway.getThing().getUID();
89         for (KM200ThingType tType : KM200ThingType.values()) {
90             String root = tType.getRootPath();
91             if (root.isEmpty()) {
92                 continue;
93             }
94             String checkService = tType.getActiveCheckSubPath();
95             if (gateway.getDevice().containsService(root)) {
96                 boolean enumOnly = true;
97                 KM200ServiceObject object = gateway.getDevice().getServiceObject(root);
98                 if (null == object) {
99                     logger.warn("No root service object found");
100                     return;
101                 }
102                 Set<String> keys = object.serviceTreeMap.keySet();
103                 /* Check whether all sub services are refEnum */
104                 for (String key : keys) {
105                     if (!DATA_TYPE_REF_ENUM.equals(object.serviceTreeMap.get(key).getServiceType())) {
106                         enumOnly = false;
107                         break;
108                     }
109                 }
110                 /* If there are refEnum only, then create for every one an own thing */
111                 if (enumOnly) {
112                     for (String key : keys) {
113                         /* Check whether this part of heating system is inactive. If its then ignore it */
114                         if (checkService != null) {
115                             String checkServicePath = root + "/" + key + "/" + checkService;
116                             if (gateway.getDevice().containsService(checkServicePath)) {
117                                 KM200ServiceObject serviceObject = gateway.getDevice()
118                                         .getServiceObject(checkServicePath);
119                                 if (null != serviceObject) {
120                                     Object val = serviceObject.getValue();
121                                     if (null != val && "INACTIVE".equals(val)) {
122                                         continue;
123                                     }
124                                 }
125                             }
126                         }
127                         thingUID = new ThingUID(tType.getThingTypeUID(), bridgeUID, key);
128                         Map<String, Object> properties = new HashMap<>(1);
129                         properties.put("root", KM200Utils.translatesPathToName(root) + "#" + key);
130                         DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withBridge(bridgeUID)
131                                 .withLabel(key).withProperties(properties).build();
132                         thingDiscovered(discoveryResult);
133                         if (object.serviceTreeMap.get(key).serviceTreeMap.containsKey(SWITCH_PROGRAM_PATH_NAME)) {
134                             String currentPathName = root + "/" + key + "/" + SWITCH_PROGRAM_CURRENT_PATH_NAME;
135                             String currParaRepl = SWITCH_PROGRAM_REPLACEMENT;
136                             boolean currExists = object.serviceTreeMap.get(key).serviceTreeMap
137                                     .containsKey(SWITCH_PROGRAM_CURRENT_PATH_NAME);
138
139                             KM200ServiceObject switchObject = object.serviceTreeMap.get(key).serviceTreeMap
140                                     .get(SWITCH_PROGRAM_PATH_NAME);
141                             if (switchObject.serviceTreeMap.isEmpty()) {
142                                 continue;
143                             }
144                             /*
145                              * if the device has only one switching program then the "activeSwitchProgram" service is
146                              * not existing. In this case we are using a fix path to this one service.
147                              */
148                             if (!currExists) {
149                                 if (switchObject.serviceTreeMap.keySet().size() == 1) {
150                                     currParaRepl = switchObject.serviceTreeMap.entrySet().iterator().next().getKey();
151                                 }
152                             }
153                             KM200SwitchProgramServiceHandler valPara = (KM200SwitchProgramServiceHandler) switchObject.serviceTreeMap
154                                     .entrySet().iterator().next().getValue().getValueParameter();
155                             if (null != valPara) {
156                                 String posName = valPara.getPositiveSwitch();
157                                 String negName = valPara.getNegativeSwitch();
158                                 if (null == posName || null == negName) {
159                                     logger.warn("Service switches not found!");
160                                     return;
161                                 }
162                                 ThingUID subThingUID = new ThingUID(tType.getThingTypeUID(), bridgeUID,
163                                         key + "-switchprogram");
164                                 Map<String, Object> subProperties = new HashMap<>(4);
165                                 subProperties.put("root", KM200Utils.translatesPathToName(
166                                         root + "/" + key + "/" + SWITCH_PROGRAM_PATH_NAME + "/" + currParaRepl));
167                                 subProperties.put(SWITCH_PROGRAM_CURRENT_PATH_NAME,
168                                         KM200Utils.translatesPathToName(currentPathName));
169                                 subProperties.put(SWITCH_PROGRAM_POSITIVE, posName);
170                                 subProperties.put(SWITCH_PROGRAM_NEGATIVE, negName);
171                                 DiscoveryResult subDiscoveryResult = DiscoveryResultBuilder.create(subThingUID)
172                                         .withBridge(bridgeUID).withLabel(key + " switch program")
173                                         .withProperties(subProperties).build();
174                                 thingDiscovered(subDiscoveryResult);
175                             }
176                         }
177                     }
178                 } else {
179                     String[] sParts = root.split("/");
180                     String key = sParts[sParts.length - 1];
181                     thingUID = new ThingUID(tType.getThingTypeUID(), bridgeUID, key);
182                     Map<String, Object> properties = new HashMap<>(1);
183                     properties.put("root", KM200Utils.translatesPathToName(root));
184                     DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withBridge(bridgeUID)
185                             .withLabel(key).withProperties(properties).build();
186                     thingDiscovered(discoveryResult);
187                 }
188             }
189         }
190     }
191 }