]> git.basschouten.com Git - openhab-addons.git/blob
8e4b67be28912bf35277b7db958ab65ad54ec88f
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.siemensrds.internal;
14
15 import static org.openhab.binding.siemensrds.internal.RdsBindingConstants.*;
16
17 import java.io.IOException;
18
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.openhab.core.thing.Bridge;
22 import org.openhab.core.thing.ChannelUID;
23 import org.openhab.core.thing.ThingStatus;
24 import org.openhab.core.thing.ThingStatusDetail;
25 import org.openhab.core.thing.binding.BaseBridgeHandler;
26 import org.openhab.core.types.Command;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 import com.google.gson.JsonParseException;
31
32 /**
33  * The {@link RdsCloudHandler} is the handler for Siemens RDS cloud account (
34  * also known as the Climatix IC server account )
35  *
36  * @author Andrew Fiddian-Green - Initial contribution
37  * 
38  */
39 @NonNullByDefault
40 public class RdsCloudHandler extends BaseBridgeHandler {
41
42     private final Logger logger = LoggerFactory.getLogger(RdsCloudHandler.class);
43
44     private @Nullable RdsCloudConfiguration config = null;
45
46     private @Nullable RdsAccessToken accessToken = null;
47
48     public RdsCloudHandler(Bridge bridge) {
49         super(bridge);
50     }
51
52     @Override
53     public void handleCommand(ChannelUID channelUID, Command command) {
54         // there is nothing to do
55     }
56
57     @Override
58     public void initialize() {
59         RdsCloudConfiguration config = this.config = getConfigAs(RdsCloudConfiguration.class);
60
61         if (config.userEmail.isEmpty()) {
62             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "missing email address");
63             return;
64         }
65
66         if (config.userPassword.isEmpty()) {
67             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "missing password");
68             return;
69         }
70
71         if (logger.isDebugEnabled())
72             logger.debug("polling interval={}", config.pollingInterval);
73
74         if (config.pollingInterval < FAST_POLL_INTERVAL || config.pollingInterval > LAZY_POLL_INTERVAL) {
75             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
76                     String.format("polling interval out of range [%d..%d]", FAST_POLL_INTERVAL, LAZY_POLL_INTERVAL));
77             return;
78         }
79     }
80
81     @Override
82     public void dispose() {
83         // there is nothing to do
84     }
85
86     /*
87      * public method: used by RDS smart thermostat handlers return the polling
88      * interval (seconds)
89      */
90     public int getPollInterval() throws RdsCloudException {
91         RdsCloudConfiguration config = this.config;
92         if (config != null) {
93             return config.pollingInterval;
94         }
95         throw new RdsCloudException("missing polling interval");
96     }
97
98     /*
99      * private method: check if the current token is valid, and renew it if
100      * necessary
101      */
102     private synchronized void refreshToken() {
103         RdsCloudConfiguration config = this.config;
104         RdsAccessToken accessToken = this.accessToken;
105
106         if (accessToken == null || accessToken.isExpired()) {
107             try {
108                 if (config == null) {
109                     throw new RdsCloudException("missing configuration");
110                 }
111
112                 String url = URL_TOKEN;
113                 String payload = String.format(TOKEN_REQUEST, config.userEmail, config.userPassword);
114
115                 logger.debug(LOG_HTTP_COMMAND, HTTP_POST, url.length());
116                 logger.debug(LOG_PAYLOAD_FMT, LOG_SENDING_MARK, url);
117                 logger.debug(LOG_PAYLOAD_FMT, LOG_SENDING_MARK, payload);
118
119                 String json = RdsAccessToken.httpGetTokenJson(config.apiKey, payload);
120
121                 if (logger.isTraceEnabled()) {
122                     logger.trace(LOG_CONTENT_LENGTH, LOG_RECEIVED_MSG, json.length());
123                     logger.trace(LOG_PAYLOAD_FMT, LOG_RECEIVED_MARK, json);
124                 } else if (logger.isDebugEnabled()) {
125                     logger.debug(LOG_CONTENT_LENGTH_ABR, LOG_RECEIVED_MSG, json.length());
126                     logger.debug(LOG_PAYLOAD_FMT_ABR, LOG_RECEIVED_MARK,
127                             json.substring(0, Math.min(json.length(), 30)));
128                 }
129
130                 accessToken = this.accessToken = RdsAccessToken.createFromJson(json);
131             } catch (RdsCloudException e) {
132                 logger.warn(LOG_SYSTEM_EXCEPTION, "refreshToken()", e.getClass().getName(), e.getMessage());
133             } catch (JsonParseException | IOException e) {
134                 logger.warn(LOG_RUNTIME_EXCEPTION, "refreshToken()", e.getClass().getName(), e.getMessage());
135             }
136         }
137
138         if (accessToken != null) {
139             if (getThing().getStatus() != ThingStatus.ONLINE) {
140                 updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, "cloud server responded");
141             }
142         } else {
143             if (getThing().getStatus() == ThingStatus.ONLINE) {
144                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
145                         "cloud server authentication error");
146             }
147         }
148     }
149
150     /*
151      * public method: used by RDS smart thermostat handlers to fetch the current
152      * token
153      */
154     public synchronized String getToken() throws RdsCloudException {
155         refreshToken();
156         RdsAccessToken accessToken = this.accessToken;
157         if (accessToken != null) {
158             return accessToken.getToken();
159         }
160         throw new RdsCloudException("no access token");
161     }
162
163     public String getApiKey() throws RdsCloudException {
164         RdsCloudConfiguration config = this.config;
165         if (config != null) {
166             return config.apiKey;
167         }
168         throw new RdsCloudException("no api key");
169     }
170 }