2 * Copyright (c) 2010-2023 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.km200.internal.discovery;
15 import static org.openhab.binding.km200.internal.KM200BindingConstants.*;
17 import java.util.HashMap;
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;
37 * The {@link KM200GatewayDiscoveryService} class discovers things through a gateway
39 * @author Markus Eckhardt - Initial contribution
42 public class KM200GatewayDiscoveryService extends AbstractDiscoveryService implements KM200GatewayStatusListener {
44 private final Logger logger = LoggerFactory.getLogger(KM200GatewayDiscoveryService.class);
46 private static int timeOut = 120;
48 KM200GatewayHandler gateway;
50 public KM200GatewayDiscoveryService(KM200GatewayHandler gateway) {
51 super(KM200GatewayHandler.SUPPORTED_THING_TYPES_UIDS, timeOut, true);
52 this.gateway = gateway;
53 this.gateway.addGatewayStatusListener(this);
57 protected void startScan() {
62 protected void startBackgroundDiscovery() {
67 public void gatewayStatusChanged(ThingStatus status) {
68 if (status.equals(ThingStatus.ONLINE)) {
74 protected void deactivate() {
75 gateway.removeHubStatusListener(this);
80 * Discovers devices connected to a hub
82 private void discoverDevices() {
83 if (!gateway.getDevice().getInited()) {
84 logger.debug("Gateway not configured, scanning postponed.");
87 ThingUID thingUID = null;
88 ThingUID bridgeUID = gateway.getThing().getUID();
89 for (KM200ThingType tType : KM200ThingType.values()) {
90 String root = tType.getRootPath();
94 String checkService = tType.getActiveCheckSubPath();
95 if (gateway.getDevice().containsService(root)) {
96 boolean enumOnly = true;
97 KM200ServiceObject object = gateway.getDevice().getServiceObject(root);
99 logger.warn("No root service object found");
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())) {
110 /* If there are refEnum only, then create for every one an own thing */
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)) {
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);
139 KM200ServiceObject switchObject = object.serviceTreeMap.get(key).serviceTreeMap
140 .get(SWITCH_PROGRAM_PATH_NAME);
141 if (switchObject != null) {
142 if (switchObject.serviceTreeMap.isEmpty()) {
146 * if the device has only one switching program then the "activeSwitchProgram" service
148 * not existing. In this case we are using a fix path to this one service.
151 if (switchObject.serviceTreeMap.keySet().size() == 1) {
152 currParaRepl = switchObject.serviceTreeMap.entrySet().iterator().next()
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!");
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);
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);