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.gardena.internal.discovery;
15 import static org.openhab.binding.gardena.internal.GardenaBindingConstants.BINDING_ID;
17 import java.util.Collections;
18 import java.util.concurrent.CancellationException;
19 import java.util.concurrent.Future;
20 import java.util.stream.Collectors;
21 import java.util.stream.Stream;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.gardena.internal.GardenaSmart;
26 import org.openhab.binding.gardena.internal.exception.GardenaException;
27 import org.openhab.binding.gardena.internal.handler.GardenaAccountHandler;
28 import org.openhab.binding.gardena.internal.model.dto.Device;
29 import org.openhab.binding.gardena.internal.util.PropertyUtils;
30 import org.openhab.binding.gardena.internal.util.UidUtils;
31 import org.openhab.core.config.discovery.AbstractThingHandlerDiscoveryService;
32 import org.openhab.core.config.discovery.DiscoveryResult;
33 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
34 import org.openhab.core.thing.Thing;
35 import org.openhab.core.thing.ThingTypeUID;
36 import org.openhab.core.thing.ThingUID;
37 import org.osgi.service.component.annotations.Component;
38 import org.osgi.service.component.annotations.ServiceScope;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
43 * The {@link GardenaDeviceDiscoveryService} is used to discover devices that are connected to Gardena smart system.
45 * @author Gerhard Riegler - Initial contribution
47 @Component(scope = ServiceScope.PROTOTYPE, service = GardenaDeviceDiscoveryService.class)
49 public class GardenaDeviceDiscoveryService extends AbstractThingHandlerDiscoveryService<GardenaAccountHandler> {
51 private final Logger logger = LoggerFactory.getLogger(GardenaDeviceDiscoveryService.class);
52 private static final int DISCOVER_TIMEOUT_SECONDS = 5;
53 private @Nullable Future<?> scanFuture;
55 public GardenaDeviceDiscoveryService() {
56 super(GardenaAccountHandler.class,
57 Collections.unmodifiableSet(Stream.of(new ThingTypeUID(BINDING_ID, "-")).collect(Collectors.toSet())),
58 DISCOVER_TIMEOUT_SECONDS, false);
62 public void initialize() {
63 thingHandler.setDiscoveryService(this);
68 protected void startScan() {
69 logger.debug("Starting Gardena discovery scan");
74 public void stopScan() {
75 logger.debug("Stopping Gardena discovery scan");
76 final Future<?> scanFuture = this.scanFuture;
77 if (scanFuture != null) {
78 scanFuture.cancel(true);
84 * Starts a thread which loads all Gardena devices registered in the account.
86 private void loadDevices() {
87 if (scanFuture == null) {
88 scanFuture = scheduler.submit(() -> {
89 GardenaSmart gardena = thingHandler.getGardenaSmart();
90 if (gardena != null) {
91 for (Device device : gardena.getAllDevices()) {
92 deviceDiscovered(device);
95 for (Thing thing : thingHandler.getThing().getThings()) {
97 gardena.getDevice(UidUtils.getGardenaDeviceId(thing));
98 } catch (GardenaException ex) {
99 thingRemoved(thing.getUID());
103 logger.debug("Finished Gardena device discovery scan on gateway '{}'", gardena.getId());
105 removeOlderResults(getTimestampOfLastScan());
109 logger.debug("Gardena device discovery scan in progress");
114 * Waits for the discovery scan to finish and then returns.
116 public void waitForScanFinishing() {
117 final Future<?> scanFuture = this.scanFuture;
118 if (scanFuture != null) {
119 logger.debug("Waiting for finishing Gardena device discovery scan");
122 logger.debug("Gardena device discovery scan finished");
123 } catch (CancellationException ex) {
125 } catch (Exception ex) {
126 logger.error("Error waiting for device discovery scan: {}", ex.getMessage(), ex);
132 * Generates the DiscoveryResult from a Gardena device.
134 public void deviceDiscovered(Device device) {
136 ThingUID accountUID = thingHandler.getThing().getUID();
137 ThingUID thingUID = UidUtils.generateThingUID(device, thingHandler.getThing());
140 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withBridge(accountUID)
141 .withLabel(PropertyUtils.getPropertyValue(device, "common.attributes.name.value", String.class))
142 .withProperty("id", device.id).withProperty("type", device.deviceType)
143 .withRepresentationProperty("id").build();
144 thingDiscovered(discoveryResult);
145 } catch (GardenaException ex) {
146 logger.warn("{}", ex.getMessage());