2 * Copyright (c) 2010-2024 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.NonNull;
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.AbstractThingHandlerDiscoveryService;
30 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
31 import org.openhab.core.thing.Thing;
32 import org.openhab.core.thing.ThingTypeUID;
33 import org.openhab.core.thing.ThingUID;
34 import org.osgi.service.component.annotations.Component;
35 import org.osgi.service.component.annotations.ServiceScope;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 * The {@link MelCloudDiscoveryService} creates things based on the configured location.
42 * @author Luca Calcaterra - Initial Contribution
43 * @author Pauli Anttila - Refactoring
44 * @author Wietse van Buitenen - Check device type, added heatpump device
46 @Component(scope = ServiceScope.PROTOTYPE, service = MelCloudDiscoveryService.class)
47 public class MelCloudDiscoveryService extends AbstractThingHandlerDiscoveryService<@NonNull MelCloudAccountHandler> {
48 private final Logger logger = LoggerFactory.getLogger(MelCloudDiscoveryService.class);
50 private static final String PROPERTY_DEVICE_ID = "deviceID";
51 private static final int DISCOVER_TIMEOUT_SECONDS = 10;
53 private ScheduledFuture<?> scanTask;
56 * Creates a MelCloudDiscoveryService with enabled autostart.
58 public MelCloudDiscoveryService() {
59 super(MelCloudAccountHandler.class, MelCloudBindingConstants.DISCOVERABLE_THING_TYPE_UIDS,
60 DISCOVER_TIMEOUT_SECONDS, true);
64 protected void startBackgroundDiscovery() {
69 protected void startScan() {
70 if (this.scanTask != null) {
71 scanTask.cancel(true);
73 this.scanTask = scheduler.schedule(() -> discoverDevices(), 0, TimeUnit.SECONDS);
77 protected void stopScan() {
80 if (this.scanTask != null) {
81 this.scanTask.cancel(true);
86 private void discoverDevices() {
87 logger.debug("Discover devices");
89 List<Device> deviceList = thingHandler.getDeviceList();
91 if (deviceList == null) {
92 logger.debug("No devices found");
94 ThingUID bridgeUID = thingHandler.getThing().getUID();
96 deviceList.forEach(device -> {
97 ThingTypeUID thingTypeUid = null;
98 if (device.getType() == 0) {
99 thingTypeUid = THING_TYPE_ACDEVICE;
100 } else if (device.getType() == 1) {
101 thingTypeUid = THING_TYPE_HEATPUMPDEVICE;
103 logger.debug("Unsupported device found: name {} : type: {}", device.getDeviceName(),
107 ThingUID deviceThing = new ThingUID(thingTypeUid, thingHandler.getThing().getUID(),
108 device.getDeviceID().toString());
110 Map<String, Object> deviceProperties = new HashMap<>();
111 deviceProperties.put(PROPERTY_DEVICE_ID, device.getDeviceID().toString());
112 deviceProperties.put(Thing.PROPERTY_SERIAL_NUMBER, device.getSerialNumber());
113 deviceProperties.put(Thing.PROPERTY_MAC_ADDRESS, device.getMacAddress());
114 deviceProperties.put("deviceName", device.getDeviceName());
115 deviceProperties.put("buildingID", device.getBuildingID().toString());
117 String label = createLabel(device);
118 logger.debug("Found device: {} : {}", label, deviceProperties);
121 DiscoveryResultBuilder.create(deviceThing).withLabel(label).withProperties(deviceProperties)
122 .withRepresentationProperty(PROPERTY_DEVICE_ID).withBridge(bridgeUID).build());
125 } catch (MelCloudLoginException e) {
126 logger.debug("Login error occurred during device list fetch, reason {}. ", e.getMessage(), e);
127 } catch (MelCloudCommException e) {
128 logger.debug("Error occurred during device list fetch, reason {}. ", e.getMessage(), e);
132 private String createLabel(Device device) {
133 StringBuilder sb = new StringBuilder();
134 if (device.getType() == 0) {
135 sb.append("A.C. Device - ");
136 } else if (device.getType() == 1) {
137 sb.append("Heatpump Device - ");
139 if (device.getBuildingName() instanceof String) {
140 sb.append(device.getBuildingName()).append(" - ");
142 sb.append(device.getDeviceName());
143 return sb.toString();