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.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.Device;
29 import org.openhab.binding.gardena.internal.model.Location;
30 import org.openhab.binding.gardena.internal.util.UidUtils;
31 import org.openhab.core.config.discovery.AbstractDiscoveryService;
32 import org.openhab.core.config.discovery.DiscoveryResult;
33 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
34 import org.openhab.core.config.discovery.DiscoveryService;
35 import org.openhab.core.thing.Thing;
36 import org.openhab.core.thing.ThingTypeUID;
37 import org.openhab.core.thing.ThingUID;
38 import org.openhab.core.thing.binding.ThingHandler;
39 import org.openhab.core.thing.binding.ThingHandlerService;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
44 * The {@link GardenaDeviceDiscoveryService} is used to discover devices that are connected to Gardena Smart Home.
46 * @author Gerhard Riegler - Initial contribution
48 public class GardenaDeviceDiscoveryService extends AbstractDiscoveryService
49 implements DiscoveryService, ThingHandlerService {
51 private final Logger logger = LoggerFactory.getLogger(GardenaDeviceDiscoveryService.class);
52 private static final int DISCOVER_TIMEOUT_SECONDS = 30;
54 private @NonNullByDefault({}) GardenaAccountHandler accountHandler;
55 private Future<?> scanFuture;
57 public GardenaDeviceDiscoveryService() {
58 super(Collections.unmodifiableSet(Stream.of(new ThingTypeUID(BINDING_ID, "-")).collect(Collectors.toSet())),
59 DISCOVER_TIMEOUT_SECONDS, false);
63 public void setThingHandler(@Nullable ThingHandler handler) {
64 if (handler instanceof GardenaAccountHandler) {
65 this.accountHandler = (GardenaAccountHandler) handler;
66 this.accountHandler.setDiscoveryService(this);
71 public @Nullable ThingHandler getThingHandler() {
72 return accountHandler;
76 * Called on component activation.
79 public void activate() {
84 public void deactivate() {
89 protected void startScan() {
90 logger.debug("Starting Gardena discovery scan");
95 public void stopScan() {
96 logger.debug("Stopping Gardena discovery scan");
97 if (scanFuture != null) {
98 scanFuture.cancel(true);
104 * Starts a thread which loads all Gardena devices registered in the account
106 public void loadDevices() {
107 if (scanFuture == null) {
108 scanFuture = scheduler.submit(() -> {
110 GardenaSmart gardena = accountHandler.getGardenaSmart();
111 gardena.loadAllDevices();
112 for (Location location : gardena.getLocations()) {
113 for (String deviceId : location.getDeviceIds()) {
114 deviceDiscovered(gardena.getDevice(deviceId));
118 for (Thing thing : accountHandler.getThing().getThings()) {
120 gardena.getDevice(UidUtils.getGardenaDeviceId(thing));
121 } catch (GardenaException ex) {
122 thingRemoved(thing.getUID());
126 logger.debug("Finished Gardena device discovery scan on gateway '{}'",
127 accountHandler.getGardenaSmart().getId());
128 } catch (GardenaException ex) {
129 logger.error("{}", ex.getMessage(), ex);
132 removeOlderResults(getTimestampOfLastScan());
136 logger.debug("Gardena device discovery scan in progress");
141 * Waits for the discovery scan to finish and then returns.
143 public void waitForScanFinishing() {
144 if (scanFuture != null) {
145 logger.debug("Waiting for finishing Gardena device discovery scan");
148 logger.debug("Gardena device discovery scan finished");
149 } catch (CancellationException ex) {
151 } catch (Exception ex) {
152 logger.error("Error waiting for device discovery scan: {}", ex.getMessage(), ex);
158 * Generates the DiscoveryResult from a Gardena device.
160 public void deviceDiscovered(Device device) {
161 ThingUID accountUID = accountHandler.getThing().getUID();
162 ThingUID thingUID = UidUtils.generateThingUID(device, accountHandler.getThing());
164 DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withBridge(accountUID)
165 .withLabel(device.getName()).build();
166 thingDiscovered(discoveryResult);
170 * Removes the Gardena device.
172 public void deviceRemoved(Device device) {
173 ThingUID thingUID = UidUtils.generateThingUID(device, accountHandler.getThing());
174 thingRemoved(thingUID);