2 * Copyright (c) 2010-2020 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.melcloud.internal.discovery;
15 import static org.openhab.binding.melcloud.internal.MelCloudBindingConstants.*;
17 import java.util.HashMap;
18 import java.util.List;
20 import java.util.concurrent.ScheduledFuture;
21 import java.util.concurrent.TimeUnit;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.openhab.binding.melcloud.internal.MelCloudBindingConstants;
25 import org.openhab.binding.melcloud.internal.api.json.Device;
26 import org.openhab.binding.melcloud.internal.exceptions.MelCloudCommException;
27 import org.openhab.binding.melcloud.internal.exceptions.MelCloudLoginException;
28 import org.openhab.binding.melcloud.internal.handler.MelCloudAccountHandler;
29 import org.openhab.core.config.discovery.AbstractDiscoveryService;
30 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
31 import org.openhab.core.config.discovery.DiscoveryService;
32 import org.openhab.core.thing.ThingTypeUID;
33 import org.openhab.core.thing.ThingUID;
34 import org.openhab.core.thing.binding.ThingHandler;
35 import org.openhab.core.thing.binding.ThingHandlerService;
36 import org.osgi.service.component.annotations.Modified;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
41 * The {@link MelCloudDiscoveryService} creates things based on the configured location.
43 * @author Luca Calcaterra - Initial Contribution
44 * @author Pauli Anttila - Refactoring
45 * @author Wietse van Buitenen - Check device type, added heatpump device
47 public class MelCloudDiscoveryService extends AbstractDiscoveryService
48 implements DiscoveryService, ThingHandlerService {
49 private final Logger logger = LoggerFactory.getLogger(MelCloudDiscoveryService.class);
51 private static final int DISCOVER_TIMEOUT_SECONDS = 10;
53 private MelCloudAccountHandler melCloudHandler;
54 private ScheduledFuture<?> scanTask;
57 * Creates a MelCloudDiscoveryService with enabled autostart.
59 public MelCloudDiscoveryService() {
60 super(MelCloudBindingConstants.DISCOVERABLE_THING_TYPE_UIDS, DISCOVER_TIMEOUT_SECONDS, true);
64 protected void activate(Map<String, @Nullable Object> configProperties) {
65 super.activate(configProperties);
69 public void deactivate() {
75 protected void modified(Map<String, @Nullable Object> configProperties) {
76 super.modified(configProperties);
80 protected void startBackgroundDiscovery() {
85 protected void startScan() {
86 if (this.scanTask != null) {
87 scanTask.cancel(true);
89 this.scanTask = scheduler.schedule(() -> discoverDevices(), 0, TimeUnit.SECONDS);
93 protected void stopScan() {
96 if (this.scanTask != null) {
97 this.scanTask.cancel(true);
102 private void discoverDevices() {
103 logger.debug("Discover devices");
105 if (melCloudHandler != null) {
107 List<Device> deviceList = melCloudHandler.getDeviceList();
109 if (deviceList == null) {
110 logger.debug("No devices found");
112 ThingUID bridgeUID = melCloudHandler.getThing().getUID();
114 deviceList.forEach(device -> {
115 ThingTypeUID thingTypeUid = null;
116 if (device.getType() == 0) {
117 thingTypeUid = THING_TYPE_ACDEVICE;
118 } else if (device.getType() == 1) {
119 thingTypeUid = THING_TYPE_HEATPUMPDEVICE;
121 logger.debug("Unsupported device found: name {} : type: {}", device.getDeviceName(),
125 ThingUID deviceThing = new ThingUID(thingTypeUid, melCloudHandler.getThing().getUID(),
126 device.getDeviceID().toString());
128 Map<String, Object> deviceProperties = new HashMap<>();
129 deviceProperties.put("deviceID", device.getDeviceID().toString());
130 deviceProperties.put("serialNumber", device.getSerialNumber().toString());
131 deviceProperties.put("macAddress", device.getMacAddress().toString());
132 deviceProperties.put("deviceName", device.getDeviceName().toString());
133 deviceProperties.put("buildingID", device.getBuildingID().toString());
135 String label = createLabel(device);
136 logger.debug("Found device: {} : {}", label, deviceProperties);
138 thingDiscovered(DiscoveryResultBuilder.create(deviceThing).withLabel(label)
139 .withProperties(deviceProperties)
140 .withRepresentationProperty(device.getDeviceID().toString()).withBridge(bridgeUID)
144 } catch (MelCloudLoginException e) {
145 logger.debug("Login error occurred during device list fetch, reason {}. ", e.getMessage(), e);
146 } catch (MelCloudCommException e) {
147 logger.debug("Error occurred during device list fetch, reason {}. ", e.getMessage(), e);
152 private String createLabel(Device device) {
153 StringBuilder sb = new StringBuilder();
154 if (device.getType() == 0) {
155 sb.append("A.C. Device - ");
156 } else if (device.getType() == 1) {
157 sb.append("Heatpump Device - ");
159 if (device.getBuildingName() != null && device.getBuildingName() instanceof String) {
160 sb.append(device.getBuildingName()).append(" - ");
162 sb.append(device.getDeviceName());
163 return sb.toString();
167 public void setThingHandler(@Nullable ThingHandler handler) {
168 if (handler instanceof MelCloudAccountHandler) {
169 melCloudHandler = (MelCloudAccountHandler) handler;
174 public @Nullable ThingHandler getThingHandler() {
175 return melCloudHandler;