2 * Copyright (c) 2010-2024 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.tapocontrol.internal.api;
15 import static org.openhab.binding.tapocontrol.internal.constants.TapoBindingSettings.*;
16 import static org.openhab.binding.tapocontrol.internal.constants.TapoComConstants.*;
17 import static org.openhab.binding.tapocontrol.internal.constants.TapoErrorCode.*;
18 import static org.openhab.binding.tapocontrol.internal.helpers.utils.JsonUtils.*;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jetty.client.HttpClient;
22 import org.eclipse.jetty.client.api.Request;
23 import org.openhab.binding.tapocontrol.internal.api.protocol.passthrough.PassthroughProtocol;
24 import org.openhab.binding.tapocontrol.internal.devices.bridge.TapoBridgeHandler;
25 import org.openhab.binding.tapocontrol.internal.devices.bridge.dto.TapoCloudLoginData;
26 import org.openhab.binding.tapocontrol.internal.devices.bridge.dto.TapoCloudLoginResult;
27 import org.openhab.binding.tapocontrol.internal.discovery.dto.TapoDiscoveryResultList;
28 import org.openhab.binding.tapocontrol.internal.dto.TapoRequest;
29 import org.openhab.binding.tapocontrol.internal.dto.TapoResponse;
30 import org.openhab.binding.tapocontrol.internal.helpers.TapoCredentials;
31 import org.openhab.binding.tapocontrol.internal.helpers.TapoErrorHandler;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
36 * Handler class for TAPO-Cloud connections.
38 * @author Christian Wild - Initial contribution
41 public class TapoCloudConnector implements TapoConnectorInterface {
42 private final Logger logger = LoggerFactory.getLogger(TapoCloudConnector.class);
43 private final TapoBridgeHandler bridge;
45 private @NonNullByDefault({}) TapoCloudLoginResult loginResult;
46 private String token = "";
48 private PassthroughProtocol passthrough;
50 /***********************
52 **********************/
54 public TapoCloudConnector(TapoBridgeHandler bridge) {
56 this.uid = bridge.getUID().getAsString();
57 passthrough = new PassthroughProtocol(this);
60 /***********************
62 **********************/
65 * handle received reponse-string
68 public void responsePasstrough(String response, String command) {
72 * handle received response
75 public void handleResponse(TapoResponse tapoResponse, String command) throws TapoErrorHandler {
78 handleLoginResult(tapoResponse);
80 case CLOUD_CMD_GETDEVICES:
81 bridge.getDiscoveryService().addScanResults(getDeviceListFromResponse(tapoResponse));
84 logger.debug("({}) handleResponse - unknown command: {}", uid, command);
85 throw new TapoErrorHandler(ERR_BINDING_NOT_IMPLEMENTED);
93 public void handleError(TapoErrorHandler tapoError) {
94 bridge.setError(tapoError);
97 /***********************
99 **********************/
103 public boolean login(TapoCredentials credentials) throws TapoErrorHandler {
106 TapoCloudLoginData loginData = new TapoCloudLoginData(credentials.username(), credentials.password());
107 TapoRequest request = new TapoRequest(CLOUD_CMD_LOGIN, loginData);
109 passthrough.sendRequest(request);
114 * get response from login and set token
116 private void handleLoginResult(TapoResponse tapoResponse) throws TapoErrorHandler {
117 logger.trace("({}) received login result: {}", uid, tapoResponse);
118 loginResult = getObjectFromJson(tapoResponse.result(), TapoCloudLoginResult.class);
119 token = loginResult.token();
121 throw new TapoErrorHandler(ERR_API_LOGIN);
125 public void logout() {
126 loginResult = new TapoCloudLoginResult();
130 public boolean isLoggedIn() {
131 return !token.isBlank();
134 /***********************
135 * Cloud Action Handlers
136 **********************/
138 * Query DeviceList from cloud
140 public void getDeviceList() {
141 TapoRequest request = new TapoRequest(CLOUD_CMD_GETDEVICES);
142 logger.trace("({}) sending cloud command: {}", uid, request);
144 passthrough.sendRequest(request);
145 } catch (TapoErrorHandler tapoError) {
146 logger.debug("({}) get devicelist failed: {}", uid, tapoError.getCode());
147 handleError(tapoError);
152 * get DeviceList from response
154 private TapoDiscoveryResultList getDeviceListFromResponse(TapoResponse tapoResponse) throws TapoErrorHandler {
155 logger.trace("({}) received devicelist: {}", uid, tapoResponse);
156 return getObjectFromJson(tapoResponse.result(), TapoDiscoveryResultList.class);
159 /***********************
161 **********************/
164 public HttpClient getHttpClient() {
165 return bridge.getHttpClient();
169 public String getThingUID() {
170 return bridge.getUID().toString();
173 /************************
175 ************************/
181 public String getBaseUrl() {
182 String url = TAPO_CLOUD_URL;
183 if (!token.isBlank()) {
184 url = url + "?token=" + token;
192 public Request setHeaders(Request httpRequest) {
193 httpRequest.header("content-type", CONTENT_TYPE_JSON);
194 httpRequest.header("Accept", CONTENT_TYPE_JSON);