]> git.basschouten.com Git - openhab-addons.git/blob
2e07e040ff7b2f9cf2a1c541e8b698c60cb17349
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.gardena.internal.handler;
14
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.concurrent.TimeUnit;
18
19 import org.openhab.binding.gardena.internal.GardenaSmart;
20 import org.openhab.binding.gardena.internal.GardenaSmartEventListener;
21 import org.openhab.binding.gardena.internal.GardenaSmartImpl;
22 import org.openhab.binding.gardena.internal.config.GardenaConfig;
23 import org.openhab.binding.gardena.internal.discovery.GardenaDeviceDiscoveryService;
24 import org.openhab.binding.gardena.internal.exception.GardenaException;
25 import org.openhab.binding.gardena.internal.model.Device;
26 import org.openhab.binding.gardena.internal.util.UidUtils;
27 import org.openhab.core.thing.Bridge;
28 import org.openhab.core.thing.Channel;
29 import org.openhab.core.thing.ChannelUID;
30 import org.openhab.core.thing.Thing;
31 import org.openhab.core.thing.ThingStatus;
32 import org.openhab.core.thing.ThingStatusDetail;
33 import org.openhab.core.thing.ThingUID;
34 import org.openhab.core.thing.binding.BaseBridgeHandler;
35 import org.openhab.core.thing.binding.ThingHandlerService;
36 import org.openhab.core.types.Command;
37 import org.openhab.core.types.RefreshType;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 /**
42  * The {@link GardenaAccountHandler} is the handler for a Gardena Smart Home access and connects it to the framework.
43  *
44  * @author Gerhard Riegler - Initial contribution
45  */
46 public class GardenaAccountHandler extends BaseBridgeHandler implements GardenaSmartEventListener {
47
48     private final Logger logger = LoggerFactory.getLogger(GardenaAccountHandler.class);
49     private static final long REINITIALIZE_DELAY_SECONDS = 10;
50
51     private GardenaDeviceDiscoveryService discoveryService;
52
53     private GardenaSmart gardenaSmart = new GardenaSmartImpl();
54     private GardenaConfig gardenaConfig;
55
56     public GardenaAccountHandler(Bridge bridge) {
57         super(bridge);
58     }
59
60     @Override
61     public void initialize() {
62         logger.debug("Initializing Gardena account '{}'", getThing().getUID().getId());
63
64         gardenaConfig = getThing().getConfiguration().as(GardenaConfig.class);
65         logger.debug("{}", gardenaConfig);
66
67         initializeGardena();
68     }
69
70     public void setDiscoveryService(GardenaDeviceDiscoveryService discoveryService) {
71         this.discoveryService = discoveryService;
72     }
73
74     /**
75      * Initializes the GardenaSmart account.
76      */
77     private void initializeGardena() {
78         final GardenaAccountHandler instance = this;
79         scheduler.execute(() -> {
80             try {
81                 String id = getThing().getUID().getId();
82                 gardenaSmart.init(id, gardenaConfig, instance, scheduler);
83                 discoveryService.startScan(null);
84                 discoveryService.waitForScanFinishing();
85                 updateStatus(ThingStatus.ONLINE);
86             } catch (GardenaException ex) {
87                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, ex.getMessage());
88                 disposeGardena();
89                 scheduleReinitialize();
90                 logger.debug("{}", ex.getMessage(), ex);
91             }
92         });
93     }
94
95     /**
96      * Schedules a reinitialization, if Gardea Smart Home account is not reachable at startup.
97      */
98     private void scheduleReinitialize() {
99         scheduler.schedule(() -> {
100             initializeGardena();
101         }, REINITIALIZE_DELAY_SECONDS, TimeUnit.SECONDS);
102     }
103
104     @Override
105     public void dispose() {
106         super.dispose();
107         disposeGardena();
108     }
109
110     /**
111      * Disposes the GardenaSmart account.
112      */
113     private void disposeGardena() {
114         logger.debug("Disposing Gardena account '{}'", getThing().getUID().getId());
115
116         discoveryService.stopScan();
117
118         gardenaSmart.dispose();
119     }
120
121     /**
122      * Returns the Gardena Smart Home implementation.
123      */
124     public GardenaSmart getGardenaSmart() {
125         return gardenaSmart;
126     }
127
128     @Override
129     public Collection<Class<? extends ThingHandlerService>> getServices() {
130         return Collections.singleton(GardenaDeviceDiscoveryService.class);
131     }
132
133     @Override
134     public void handleCommand(ChannelUID channelUID, Command command) {
135         if (RefreshType.REFRESH == command) {
136             logger.debug("Refreshing Gardena account '{}'", getThing().getUID().getId());
137             disposeGardena();
138             initializeGardena();
139         }
140     }
141
142     @Override
143     public void onDeviceUpdated(Device device) {
144         for (ThingUID thingUID : UidUtils.getThingUIDs(device, getThing())) {
145             Thing gardenaThing = getThing().getThing(thingUID);
146             try {
147                 GardenaThingHandler gardenaThingHandler = (GardenaThingHandler) gardenaThing.getHandler();
148                 gardenaThingHandler.updateProperties(device);
149                 for (Channel channel : gardenaThing.getChannels()) {
150                     gardenaThingHandler.updateChannel(channel.getUID());
151                 }
152                 gardenaThingHandler.updateSettings(device);
153                 gardenaThingHandler.updateStatus(device);
154             } catch (GardenaException ex) {
155                 logger.error("There is something wrong with your thing '{}', please check or recreate it: {}",
156                         gardenaThing.getUID(), ex.getMessage());
157                 logger.debug("Gardena exception caught on device update.", ex);
158                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, ex.getMessage());
159             } catch (AccountHandlerNotAvailableException ignore) {
160             }
161         }
162     }
163
164     @Override
165     public void onNewDevice(Device device) {
166         if (discoveryService != null) {
167             discoveryService.deviceDiscovered(device);
168         }
169         onDeviceUpdated(device);
170     }
171
172     @Override
173     public void onDeviceDeleted(Device device) {
174         if (discoveryService != null) {
175             discoveryService.deviceRemoved(device);
176         }
177     }
178
179     @Override
180     public void onConnectionLost() {
181         updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Connection lost");
182     }
183
184     @Override
185     public void onConnectionResumed() {
186         updateStatus(ThingStatus.ONLINE);
187     }
188 }