]> git.basschouten.com Git - openhab-addons.git/blob
db60308c350ba7bf705a4892fda00e5d4609ce52
[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.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 != null) {
142                                 if (switchObject.serviceTreeMap.isEmpty()) {
143                                     continue;
144                                 }
145                                 /*
146                                  * if the device has only one switching program then the "activeSwitchProgram" service
147                                  * is
148                                  * not existing. In this case we are using a fix path to this one service.
149                                  */
150                                 if (!currExists) {
151                                     if (switchObject.serviceTreeMap.keySet().size() == 1) {
152                                         currParaRepl = switchObject.serviceTreeMap.entrySet().iterator().next()
153                                                 .getKey();
154                                     }
155                                 }
156                                 KM200SwitchProgramServiceHandler valPara = (KM200SwitchProgramServiceHandler) switchObject.serviceTreeMap
157                                         .entrySet().iterator().next().getValue().getValueParameter();
158                                 if (null != valPara) {
159                                     String posName = valPara.getPositiveSwitch();
160                                     String negName = valPara.getNegativeSwitch();
161                                     if (null == posName || null == negName) {
162                                         logger.warn("Service switches not found!");
163                                         return;
164                                     }
165                                     ThingUID subThingUID = new ThingUID(tType.getThingTypeUID(), bridgeUID,
166                                             key + "-switchprogram");
167                                     Map<String, Object> subProperties = new HashMap<>(4);
168                                     subProperties.put("root", KM200Utils.translatesPathToName(
169                                             root + "/" + key + "/" + SWITCH_PROGRAM_PATH_NAME + "/" + currParaRepl));
170                                     subProperties.put(SWITCH_PROGRAM_CURRENT_PATH_NAME,
171                                             KM200Utils.translatesPathToName(currentPathName));
172                                     subProperties.put(SWITCH_PROGRAM_POSITIVE, posName);
173                                     subProperties.put(SWITCH_PROGRAM_NEGATIVE, negName);
174                                     DiscoveryResult subDiscoveryResult = DiscoveryResultBuilder.create(subThingUID)
175                                             .withBridge(bridgeUID).withLabel(key + " switch program")
176                                             .withProperties(subProperties).build();
177                                     thingDiscovered(subDiscoveryResult);
178                                 }
179                             }
180                         }
181                     }
182                 } else {
183                     String[] sParts = root.split("/");
184                     String key = sParts[sParts.length - 1];
185                     thingUID = new ThingUID(tType.getThingTypeUID(), bridgeUID, key);
186                     Map<String, Object> properties = new HashMap<>(1);
187                     properties.put("root", KM200Utils.translatesPathToName(root));
188                     DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withBridge(bridgeUID)
189                             .withLabel(key).withProperties(properties).build();
190                     thingDiscovered(discoveryResult);
191                 }
192             }
193         }
194     }
195 }