2 * Copyright (c) 2010-2021 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.handler;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.concurrent.TimeUnit;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.binding.gardena.internal.GardenaSmart;
22 import org.openhab.binding.gardena.internal.GardenaSmartEventListener;
23 import org.openhab.binding.gardena.internal.GardenaSmartImpl;
24 import org.openhab.binding.gardena.internal.config.GardenaConfig;
25 import org.openhab.binding.gardena.internal.discovery.GardenaDeviceDiscoveryService;
26 import org.openhab.binding.gardena.internal.exception.GardenaException;
27 import org.openhab.binding.gardena.internal.model.dto.Device;
28 import org.openhab.binding.gardena.internal.util.UidUtils;
29 import org.openhab.core.io.net.http.HttpClientFactory;
30 import org.openhab.core.io.net.http.WebSocketFactory;
31 import org.openhab.core.thing.*;
32 import org.openhab.core.thing.binding.BaseBridgeHandler;
33 import org.openhab.core.thing.binding.ThingHandlerService;
34 import org.openhab.core.types.Command;
35 import org.openhab.core.types.RefreshType;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 * The {@link GardenaAccountHandler} is the handler for a Gardena smart system access and connects it to the framework.
42 * @author Gerhard Riegler - Initial contribution
45 public class GardenaAccountHandler extends BaseBridgeHandler implements GardenaSmartEventListener {
46 private final Logger logger = LoggerFactory.getLogger(GardenaAccountHandler.class);
47 private final long REINITIALIZE_DELAY_SECONDS = 10;
49 private @Nullable GardenaDeviceDiscoveryService discoveryService;
51 private @Nullable GardenaSmart gardenaSmart;
52 private HttpClientFactory httpClientFactory;
53 private WebSocketFactory webSocketFactory;
55 public GardenaAccountHandler(Bridge bridge, HttpClientFactory httpClientFactory,
56 WebSocketFactory webSocketFactory) {
58 this.httpClientFactory = httpClientFactory;
59 this.webSocketFactory = webSocketFactory;
63 public void initialize() {
64 logger.debug("Initializing Gardena account '{}'", getThing().getUID().getId());
68 public void setDiscoveryService(GardenaDeviceDiscoveryService discoveryService) {
69 this.discoveryService = discoveryService;
73 * Initializes the GardenaSmart account.
75 private void initializeGardena() {
76 final GardenaAccountHandler instance = this;
77 scheduler.execute(() -> {
79 GardenaConfig gardenaConfig = getThing().getConfiguration().as(GardenaConfig.class);
80 logger.debug("{}", gardenaConfig);
82 String id = getThing().getUID().getId();
83 gardenaSmart = new GardenaSmartImpl(id, gardenaConfig, instance, scheduler, httpClientFactory,
85 final GardenaDeviceDiscoveryService discoveryService = this.discoveryService;
86 if (discoveryService != null) {
87 discoveryService.startScan(null);
88 discoveryService.waitForScanFinishing();
90 updateStatus(ThingStatus.ONLINE);
91 } catch (GardenaException ex) {
92 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, ex.getMessage());
94 scheduleReinitialize();
95 logger.warn("{}", ex.getMessage());
101 * Schedules a reinitialization, if Gardena smart system account is not reachable.
103 private void scheduleReinitialize() {
104 scheduler.schedule(() -> {
105 if (getThing().getStatus() != ThingStatus.UNINITIALIZED) {
108 }, REINITIALIZE_DELAY_SECONDS, TimeUnit.SECONDS);
112 public void dispose() {
118 * Disposes the GardenaSmart account.
120 private void disposeGardena() {
121 logger.debug("Disposing Gardena account '{}'", getThing().getUID().getId());
122 final GardenaDeviceDiscoveryService discoveryService = this.discoveryService;
123 if (discoveryService != null) {
124 discoveryService.stopScan();
126 final GardenaSmart gardenaSmart = this.gardenaSmart;
127 if (gardenaSmart != null) {
128 gardenaSmart.dispose();
133 * Returns the Gardena smart system implementation.
135 public @Nullable GardenaSmart getGardenaSmart() {
140 public Collection<Class<? extends ThingHandlerService>> getServices() {
141 return Collections.singleton(GardenaDeviceDiscoveryService.class);
145 public void handleCommand(ChannelUID channelUID, Command command) {
146 if (RefreshType.REFRESH == command) {
147 logger.debug("Refreshing Gardena account '{}'", getThing().getUID().getId());
154 public void onDeviceUpdated(Device device) {
155 for (ThingUID thingUID : UidUtils.getThingUIDs(device, getThing())) {
156 final Thing gardenaThing;
157 final GardenaThingHandler gardenaThingHandler;
158 if ((gardenaThing = getThing().getThing(thingUID)) != null
159 && (gardenaThingHandler = (GardenaThingHandler) gardenaThing.getHandler()) != null) {
161 gardenaThingHandler.updateProperties(device);
162 for (Channel channel : gardenaThing.getChannels()) {
163 gardenaThingHandler.updateChannel(channel.getUID());
165 gardenaThingHandler.updateStatus(device);
166 } catch (GardenaException ex) {
167 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, ex.getMessage());
168 } catch (AccountHandlerNotAvailableException ignore) {
175 public void onNewDevice(Device device) {
176 final GardenaDeviceDiscoveryService discoveryService = this.discoveryService;
177 if (discoveryService != null) {
178 discoveryService.deviceDiscovered(device);
180 onDeviceUpdated(device);
184 public void onError() {
185 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Connection lost");
187 scheduleReinitialize();