]> git.basschouten.com Git - openhab-addons.git/blob
e7064327a0e22d0fa17cbab4e61bf770ba015f72
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.tado.internal.handler;
14
15 import java.io.IOException;
16 import java.util.List;
17 import java.util.concurrent.ScheduledFuture;
18 import java.util.concurrent.TimeUnit;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.tado.internal.TadoBindingConstants;
23 import org.openhab.binding.tado.internal.TadoBindingConstants.TemperatureUnit;
24 import org.openhab.binding.tado.internal.api.ApiException;
25 import org.openhab.binding.tado.internal.api.HomeApiFactory;
26 import org.openhab.binding.tado.internal.api.client.HomeApi;
27 import org.openhab.binding.tado.internal.api.model.HomeInfo;
28 import org.openhab.binding.tado.internal.api.model.HomePresence;
29 import org.openhab.binding.tado.internal.api.model.HomeState;
30 import org.openhab.binding.tado.internal.api.model.PresenceState;
31 import org.openhab.binding.tado.internal.api.model.User;
32 import org.openhab.binding.tado.internal.api.model.UserHomes;
33 import org.openhab.binding.tado.internal.config.TadoHomeConfig;
34 import org.openhab.core.library.types.OnOffType;
35 import org.openhab.core.thing.Bridge;
36 import org.openhab.core.thing.ChannelUID;
37 import org.openhab.core.thing.ThingStatus;
38 import org.openhab.core.thing.ThingStatusDetail;
39 import org.openhab.core.thing.binding.BaseBridgeHandler;
40 import org.openhab.core.types.Command;
41 import org.openhab.core.types.RefreshType;
42 import org.openhab.core.types.State;
43 import org.openhab.core.types.UnDefType;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47 /**
48  * The {@link TadoHomeHandler} is the bridge of all home-based things.
49  *
50  * @author Dennis Frommknecht - Initial contribution
51  */
52 @NonNullByDefault
53 public class TadoHomeHandler extends BaseBridgeHandler {
54
55     private Logger logger = LoggerFactory.getLogger(TadoHomeHandler.class);
56
57     private TadoHomeConfig configuration;
58     private final HomeApi api;
59
60     private @Nullable Long homeId;
61     private @Nullable TadoBatteryChecker batteryChecker;
62     private @Nullable ScheduledFuture<?> initializationFuture;
63
64     public TadoHomeHandler(Bridge bridge) {
65         super(bridge);
66         batteryChecker = new TadoBatteryChecker(this);
67         configuration = getConfigAs(TadoHomeConfig.class);
68         api = new HomeApiFactory().create(configuration.username, configuration.password);
69     }
70
71     public TemperatureUnit getTemperatureUnit() {
72         String temperatureUnitStr = this.thing.getProperties()
73                 .getOrDefault(TadoBindingConstants.PROPERTY_HOME_TEMPERATURE_UNIT, "CELSIUS");
74         return TemperatureUnit.valueOf(temperatureUnitStr);
75     }
76
77     @Override
78     public void initialize() {
79         configuration = getConfigAs(TadoHomeConfig.class);
80         ScheduledFuture<?> initializationFuture = this.initializationFuture;
81         if (initializationFuture == null || initializationFuture.isDone()) {
82             this.initializationFuture = scheduler.scheduleWithFixedDelay(
83                     this::initializeBridgeStatusAndPropertiesIfOffline, 0, 300, TimeUnit.SECONDS);
84         }
85     }
86
87     private void initializeBridgeStatusAndPropertiesIfOffline() {
88         Bridge bridge = getBridge();
89         if (bridge != null && bridge.getStatus() == ThingStatus.ONLINE) {
90             return;
91         }
92
93         try {
94             // Get user info to verify successful authentication and connection to server
95             User user = api.showUser();
96             if (user == null) {
97                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
98                         "Cannot connect to server. Username and/or password might be invalid");
99                 return;
100             }
101
102             List<UserHomes> homes = user.getHomes();
103             if (homes == null || homes.isEmpty()) {
104                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
105                         "User does not have access to any home");
106                 return;
107             }
108
109             Integer firstHomeId = homes.get(0).getId();
110             if (firstHomeId == null) {
111                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Missing Home Id");
112                 return;
113             }
114
115             homeId = firstHomeId.longValue();
116
117             HomeInfo homeInfo = api.showHome(homeId);
118             TemperatureUnit temperatureUnit = org.openhab.binding.tado.internal.api.model.TemperatureUnit.FAHRENHEIT == homeInfo
119                     .getTemperatureUnit() ? TemperatureUnit.FAHRENHEIT : TemperatureUnit.CELSIUS;
120             updateProperty(TadoBindingConstants.PROPERTY_HOME_TEMPERATURE_UNIT, temperatureUnit.name());
121         } catch (IOException | ApiException e) {
122             logger.debug("Error accessing tado server: {}", e.getMessage(), e);
123             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
124                     "Could not connect to server due to " + e.getMessage());
125             return;
126         }
127
128         updateStatus(ThingStatus.ONLINE);
129     }
130
131     @Override
132     public void dispose() {
133         super.dispose();
134         ScheduledFuture<?> initializationFuture = this.initializationFuture;
135         if (initializationFuture != null && !initializationFuture.isCancelled()) {
136             initializationFuture.cancel(true);
137         }
138     }
139
140     public HomeApi getApi() {
141         return api;
142     }
143
144     public @Nullable Long getHomeId() {
145         return homeId;
146     }
147
148     public HomeState getHomeState() throws IOException, ApiException {
149         return api.homeState(getHomeId());
150     }
151
152     public void updateHomeState() {
153         try {
154             updateState(TadoBindingConstants.CHANNEL_HOME_PRESENCE_MODE,
155                     getHomeState().getPresence() == PresenceState.HOME ? OnOffType.ON : OnOffType.OFF);
156         } catch (IOException | ApiException e) {
157             logger.debug("Error accessing tado server: {}", e.getMessage(), e);
158         }
159     }
160
161     @Override
162     public void handleCommand(ChannelUID channelUID, Command command) {
163         String id = channelUID.getId();
164
165         if (command == RefreshType.REFRESH) {
166             updateHomeState();
167             return;
168         }
169
170         switch (id) {
171             case TadoBindingConstants.CHANNEL_HOME_PRESENCE_MODE:
172                 HomePresence presence = new HomePresence();
173                 presence.setHomePresence(command.toFullString().toUpperCase().equals("ON")
174                         || command.toFullString().toUpperCase().equals("HOME") ? PresenceState.HOME
175                                 : PresenceState.AWAY);
176                 try {
177                     api.updatePresenceLock(homeId, presence);
178                 } catch (IOException | ApiException e) {
179                     logger.warn("Error setting home presence: {}", e.getMessage(), e);
180                 }
181
182                 break;
183
184         }
185     }
186
187     public State getBatteryLowAlarm(long zoneId) {
188         TadoBatteryChecker batteryChecker = this.batteryChecker;
189         return batteryChecker != null ? batteryChecker.getBatteryLowAlarm(zoneId) : UnDefType.UNDEF;
190     }
191 }