2 * Copyright (c) 2010-2023 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);
75 if (config.pollingInterval < FAST_POLL_INTERVAL || config.pollingInterval > LAZY_POLL_INTERVAL) {
76 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
77 String.format("polling interval out of range [%d..%d]", FAST_POLL_INTERVAL, LAZY_POLL_INTERVAL));
83 public void dispose() {
84 // there is nothing to do
88 * public method: used by RDS smart thermostat handlers return the polling
91 public int getPollInterval() throws RdsCloudException {
92 RdsCloudConfiguration config = this.config;
94 return config.pollingInterval;
96 throw new RdsCloudException("missing polling interval");
100 * private method: check if the current token is valid, and renew it if
103 private synchronized void refreshToken() {
104 RdsCloudConfiguration config = this.config;
105 RdsAccessToken accessToken = this.accessToken;
107 if (accessToken == null || accessToken.isExpired()) {
109 if (config == null) {
110 throw new RdsCloudException("missing configuration");
113 String url = URL_TOKEN;
114 String payload = String.format(TOKEN_REQUEST, config.userEmail, config.userPassword);
116 logger.debug(LOG_HTTP_COMMAND, HTTP_POST, url.length());
117 logger.debug(LOG_PAYLOAD_FMT, LOG_SENDING_MARK, url);
118 logger.debug(LOG_PAYLOAD_FMT, LOG_SENDING_MARK, payload);
120 String json = RdsAccessToken.httpGetTokenJson(config.apiKey, payload);
122 if (logger.isTraceEnabled()) {
123 logger.trace(LOG_CONTENT_LENGTH, LOG_RECEIVED_MSG, json.length());
124 logger.trace(LOG_PAYLOAD_FMT, LOG_RECEIVED_MARK, json);
125 } else if (logger.isDebugEnabled()) {
126 logger.debug(LOG_CONTENT_LENGTH_ABR, LOG_RECEIVED_MSG, json.length());
127 logger.debug(LOG_PAYLOAD_FMT_ABR, LOG_RECEIVED_MARK,
128 json.substring(0, Math.min(json.length(), 30)));
131 accessToken = this.accessToken = RdsAccessToken.createFromJson(json);
132 } catch (RdsCloudException e) {
133 logger.warn(LOG_SYSTEM_EXCEPTION, "refreshToken()", e.getClass().getName(), e.getMessage());
134 } catch (JsonParseException | IOException e) {
135 logger.warn(LOG_RUNTIME_EXCEPTION, "refreshToken()", e.getClass().getName(), e.getMessage());
139 if (accessToken != null) {
140 if (getThing().getStatus() != ThingStatus.ONLINE) {
141 updateStatus(ThingStatus.ONLINE, ThingStatusDetail.NONE, "cloud server responded");
144 if (getThing().getStatus() == ThingStatus.ONLINE) {
145 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
146 "cloud server authentication error");
152 * public method: used by RDS smart thermostat handlers to fetch the current
155 public synchronized String getToken() throws RdsCloudException {
157 RdsAccessToken accessToken = this.accessToken;
158 if (accessToken != null) {
159 return accessToken.getToken();
161 throw new RdsCloudException("no access token");
164 public String getApiKey() throws RdsCloudException {
165 RdsCloudConfiguration config = this.config;
166 if (config != null) {
167 return config.apiKey;
169 throw new RdsCloudException("no api key");