]> git.basschouten.com Git - openhab-addons.git/blob
140c2c693a07cff56110f2039b3573d8e10fea0a
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.bsblan.internal.api;
14
15 import static org.openhab.binding.bsblan.internal.BsbLanBindingConstants.*;
16
17 import java.io.ByteArrayInputStream;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.nio.charset.Charset;
21 import java.util.HashSet;
22 import java.util.Set;
23
24 import org.apache.commons.lang.StringUtils;
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.eclipse.jdt.annotation.Nullable;
27 import org.openhab.binding.bsblan.internal.api.dto.BsbLanApiContentDTO;
28 import org.openhab.binding.bsblan.internal.api.dto.BsbLanApiParameterQueryResponseDTO;
29 import org.openhab.binding.bsblan.internal.api.dto.BsbLanApiParameterSetRequestDTO;
30 import org.openhab.binding.bsblan.internal.api.dto.BsbLanApiParameterSetResponseDTO;
31 import org.openhab.binding.bsblan.internal.api.dto.BsbLanApiParameterSetResultDTO;
32 import org.openhab.binding.bsblan.internal.configuration.BsbLanBridgeConfiguration;
33 import org.openhab.core.io.net.http.HttpUtil;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 /**
38  * Utility class to call the BSB-LAN REST API.
39  *
40  * @author Peter Schraffl - Initial contribution
41  */
42 @NonNullByDefault
43 public class BsbLanApiCaller {
44
45     private final Logger logger = LoggerFactory.getLogger(BsbLanApiCaller.class);
46     private final BsbLanBridgeConfiguration bridgeConfig;
47
48     public BsbLanApiCaller(BsbLanBridgeConfiguration config) {
49         bridgeConfig = config;
50     }
51
52     public @Nullable BsbLanApiParameterQueryResponseDTO queryParameter(Integer parameterId) {
53         Set<Integer> parameters = new HashSet<>();
54
55         parameters.add(parameterId);
56         return queryParameters(parameters);
57     }
58
59     public @Nullable BsbLanApiParameterQueryResponseDTO queryParameters(Set<Integer> parameterIds) {
60         // note: make the request even if parameterIds is empty as
61         // thing OFFLINE/ONLINE detection relies on a response
62
63         String apiPath = String.format("/JQ=%s", StringUtils.join(parameterIds, ","));
64         return makeRestCall(BsbLanApiParameterQueryResponseDTO.class, "GET", apiPath, null);
65     }
66
67     public boolean setParameter(Integer parameterId, String value, BsbLanApiParameterSetRequestDTO.Type type) {
68         // prepare request content
69         BsbLanApiParameterSetRequestDTO request = new BsbLanApiParameterSetRequestDTO();
70         request.parameter = parameterId.toString();
71         request.value = value;
72         request.type = type;
73
74         // make REST call and process response
75         BsbLanApiParameterSetResponseDTO setResponse = makeRestCall(BsbLanApiParameterSetResponseDTO.class, "POST",
76                 "/JS", request);
77         if (setResponse == null) {
78             logger.debug("Failed to set parameter {} to '{}': no response received", parameterId, value);
79             return false;
80         }
81
82         BsbLanApiParameterSetResultDTO result = setResponse.getOrDefault(parameterId, null);
83         if (result == null) {
84             logger.debug("Failed to set parameter {} to '{}'': result is null", parameterId, value);
85             return false;
86         }
87         if (result.status == null) {
88             logger.debug("Failed to set parameter {} to '{}': status is null", parameterId, value);
89             return false;
90         }
91         if (result.status != BsbLanApiParameterSetResultDTO.Status.SUCCESS) {
92             logger.debug("Failed to set parameter {} to '{}': status = {}", parameterId, value, result.status);
93             return false;
94         }
95         return true;
96     }
97
98     private String createApiBaseUrl() {
99         final String host = StringUtils.trimToEmpty(bridgeConfig.host);
100         final String username = StringUtils.trimToEmpty(bridgeConfig.username);
101         final String password = StringUtils.trimToEmpty(bridgeConfig.password);
102         final String passkey = StringUtils.trimToEmpty(bridgeConfig.passkey);
103
104         StringBuilder url = new StringBuilder();
105         url.append("http://");
106         if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password)) {
107             url.append(username).append(":").append(password).append("@");
108         }
109         url.append(host);
110         if (bridgeConfig.port != 80) {
111             url.append(":").append(bridgeConfig.port);
112         }
113         if (StringUtils.isNotBlank(passkey)) {
114             url.append("/").append(passkey);
115         }
116         return url.toString();
117     }
118
119     /**
120      * @param responseType response class type
121      * @param httpMethod to execute
122      * @param apiPath to request
123      * @param content to add to request
124      * @return the object representation of the json response
125      */
126     private <T> @Nullable T makeRestCall(Class<T> responseType, String httpMethod, String apiPath,
127             @Nullable BsbLanApiContentDTO request) {
128         try {
129             String url = createApiBaseUrl() + apiPath;
130             logger.trace("api request url = '{}'", url);
131
132             InputStream contentStream = null;
133             String contentType = null;
134             if (request != null) {
135                 String content = BsbLanApiContentConverter.toJson(request);
136                 logger.trace("api request content: '{}'", content);
137                 if (StringUtils.isNotBlank(content)) {
138                     contentStream = new ByteArrayInputStream(content.getBytes(Charset.forName("UTF-8")));
139                     contentType = "application/json";
140                 }
141             }
142
143             String response = HttpUtil.executeUrl(httpMethod, url, contentStream, contentType, API_TIMEOUT);
144             if (response == null) {
145                 logger.debug("no response returned");
146                 return null;
147             }
148
149             logger.trace("api response content: '{}'", response);
150             return BsbLanApiContentConverter.fromJson(response, responseType);
151         } catch (IOException | IllegalStateException e) {
152             logger.debug("Error executing bsb-lan api request: {}", e.getMessage());
153             return null;
154         }
155     }
156 }