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.siemensrds.internal;
15 import static org.openhab.binding.siemensrds.internal.RdsBindingConstants.*;
17 import java.io.IOException;
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;
30 import com.google.gson.JsonParseException;
33 * The {@link RdsCloudHandler} is the handler for Siemens RDS cloud account (
34 * also known as the Climatix IC server account )
36 * @author Andrew Fiddian-Green - Initial contribution
40 public class RdsCloudHandler extends BaseBridgeHandler {
42 private final Logger logger = LoggerFactory.getLogger(RdsCloudHandler.class);
44 private @Nullable RdsCloudConfiguration config = null;
46 private @Nullable RdsAccessToken accessToken = null;
48 public RdsCloudHandler(Bridge bridge) {
53 public void handleCommand(ChannelUID channelUID, Command command) {
54 // there is nothing to do
58 public void initialize() {
59 RdsCloudConfiguration config = this.config = getConfigAs(RdsCloudConfiguration.class);
61 if (config.userEmail.isEmpty()) {
62 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "missing email address");
66 if (config.userPassword.isEmpty()) {
67 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "missing password");
71 if (logger.isDebugEnabled())
72 logger.debug("polling interval={}", config.pollingInterval);
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));
82 public void dispose() {
83 // there is nothing to do
87 * public method: used by RDS smart thermostat handlers return the polling
90 public int getPollInterval() throws RdsCloudException {
91 RdsCloudConfiguration config = this.config;
93 return config.pollingInterval;
95 throw new RdsCloudException("missing polling interval");
99 * private method: check if the current token is valid, and renew it if
102 private synchronized void refreshToken() {
103 RdsCloudConfiguration config = this.config;
104 RdsAccessToken accessToken = this.accessToken;
106 if (accessToken == null || accessToken.isExpired()) {
108 if (config == null) {
109 throw new RdsCloudException("missing configuration");
112 String url = URL_TOKEN;
113 String payload = String.format(TOKEN_REQUEST, config.userEmail, config.userPassword);
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);
119 String json = RdsAccessToken.httpGetTokenJson(config.apiKey, payload);
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)));
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());
138 if (accessToken != null) {
139 if (getThing().getStatus() != ThingStatus.ONLINE) {
140 updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, "cloud server responded");
143 if (getThing().getStatus() == ThingStatus.ONLINE) {
144 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
145 "cloud server authentication error");
151 * public method: used by RDS smart thermostat handlers to fetch the current
154 public synchronized String getToken() throws RdsCloudException {
156 RdsAccessToken accessToken = this.accessToken;
157 if (accessToken != null) {
158 return accessToken.getToken();
160 throw new RdsCloudException("no access token");
163 public String getApiKey() throws RdsCloudException {
164 RdsCloudConfiguration config = this.config;
165 if (config != null) {
166 return config.apiKey;
168 throw new RdsCloudException("no api key");