]> git.basschouten.com Git - openhab-addons.git/blob
aedf192a2089b54dee0bdf4deb868e50688f11a0
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.kostalinverter.internal.secondgeneration;
14
15 import java.nio.charset.StandardCharsets;
16 import java.security.MessageDigest;
17 import java.security.NoSuchAlgorithmException;
18 import java.util.Base64;
19 import java.util.concurrent.ExecutionException;
20 import java.util.concurrent.TimeUnit;
21 import java.util.concurrent.TimeoutException;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jetty.client.HttpClient;
25 import org.eclipse.jetty.client.api.ContentResponse;
26 import org.eclipse.jetty.client.api.Request;
27 import org.eclipse.jetty.client.util.StringContentProvider;
28 import org.eclipse.jetty.http.HttpHeader;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 import com.google.gson.JsonArray;
33 import com.google.gson.JsonIOException;
34 import com.google.gson.JsonObject;
35 import com.google.gson.JsonParser;
36
37 /**
38  * The {@link SecondGenerationConfigurationHandler} is responsible for configuration changes,
39  * regarded to second generation part of the binding.
40  *
41  * @author Ã–rjan Backsell - Initial contribution Piko1020, Piko New Generation
42  */
43 @NonNullByDefault
44 public class SecondGenerationConfigurationHandler {
45
46     private static final int REQUEST_TIMEOUT_MS = 5000;
47
48     public static void executeConfigurationChanges(HttpClient httpClient, String url, String username, String password,
49             String dxsId, String value)
50             throws InterruptedException, ExecutionException, TimeoutException, NoSuchAlgorithmException {
51         String urlLogin = url + "/api/login.json?";
52         String salt = "";
53         String sessionId = "";
54
55         Logger logger = LoggerFactory.getLogger(SecondGenerationConfigurationHandler.class);
56
57         String getAuthenticateResponse = httpClient.GET(urlLogin).getContentAsString();
58
59         try {
60             JsonObject getAuthenticateResponseJsonObject = (JsonObject) JsonParser
61                     .parseString(transformJsonResponse(getAuthenticateResponse));
62
63             sessionId = extractSessionId(getAuthenticateResponseJsonObject);
64
65             JsonObject authenticateJsonObject = JsonParser.parseString(getAuthenticateResponse).getAsJsonObject();
66             salt = authenticateJsonObject.get("salt").getAsString();
67
68             String saltedPassword = new StringBuilder(password).append(salt).toString();
69             MessageDigest mDigest = MessageDigest.getInstance("SHA1");
70
71             byte[] mDigestedPassword = mDigest.digest(saltedPassword.getBytes(StandardCharsets.UTF_8));
72             StringBuilder loginPostStringBuilder = new StringBuilder();
73             for (int i = 0; i < mDigestedPassword.length; i++) {
74                 loginPostStringBuilder.append(Integer.toString((mDigestedPassword[i] & 0xff) + 0x100, 16).substring(1));
75             }
76             String saltedmDigestedPwd = Base64.getEncoder().encodeToString(mDigest.digest(saltedPassword.getBytes()));
77
78             String loginPostJsonData = "{\"mode\":1,\"userId\":\"" + username + "\",\"pwh\":\"" + saltedmDigestedPwd
79                     + "\"}";
80
81             Request loginPostJsonResponse = httpClient.POST(urlLogin + "?sessionId=" + sessionId)
82                     .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
83             loginPostJsonResponse.header(HttpHeader.CONTENT_TYPE, "application/json");
84             loginPostJsonResponse.content(new StringContentProvider(loginPostJsonData));
85             ContentResponse loginPostJsonDataContentResponse = loginPostJsonResponse.send();
86
87             String loginPostResponse = new String(loginPostJsonDataContentResponse.getContent(),
88                     StandardCharsets.UTF_8);
89
90             JsonObject loginPostJsonObject = (JsonObject) JsonParser
91                     .parseString(transformJsonResponse(loginPostResponse));
92
93             sessionId = extractSessionId(loginPostJsonObject);
94
95             // Part for sending data to Inverter
96             String postJsonData = "{\"dxsEntries\":[{\"dxsId\":" + dxsId + ",\"value\":" + value + "}]}";
97
98             Request postJsonDataRequest = httpClient.POST(url + "/api/dxs.json?sessionId=" + sessionId)
99                     .timeout(REQUEST_TIMEOUT_MS, TimeUnit.MILLISECONDS);
100             postJsonDataRequest.header(HttpHeader.CONTENT_TYPE, "application/json");
101             postJsonDataRequest.content(new StringContentProvider(postJsonData));
102             postJsonDataRequest.send();
103         } catch (JsonIOException getAuthenticateResponseException) {
104             logger.debug("Could not read the response: {}", getAuthenticateResponseException.getMessage());
105         }
106     }
107
108     static String transformJsonResponse(String jsonResponse) {
109         // Method transformJsonResponse converts response,due to missing [] in ContentResponse
110         // postJsonDataContentResponse.
111
112         int sessionStartPosition = jsonResponse.indexOf("session");
113         int statusStartPosition = jsonResponse.indexOf("status");
114
115         StringBuilder transformStringBuilder = new StringBuilder();
116
117         transformStringBuilder.append(jsonResponse);
118
119         transformStringBuilder.insert(sessionStartPosition + 9, '[');
120         int roleIdStartPosition = jsonResponse.indexOf("roleId");
121         transformStringBuilder.insert(roleIdStartPosition + 11, ']');
122
123         transformStringBuilder.insert(statusStartPosition + 10, '[');
124         int codeStartPosition = jsonResponse.indexOf("code");
125         transformStringBuilder.insert(codeStartPosition + 11, ']');
126
127         return transformStringBuilder.toString();
128     }
129
130     // Method extractSessionId extracts sessionId from JsonObject
131     static String extractSessionId(JsonObject extractJsonObjectSessionId) {
132         Logger sessionIdLogger = LoggerFactory.getLogger(SecondGenerationConfigurationHandler.class);
133         String extractSessionId = "";
134         JsonArray extractJsonArraySessionId = extractJsonObjectSessionId.getAsJsonArray("session");
135
136         int size = extractJsonArraySessionId.size();
137         if (size > 0) {
138             extractSessionId = extractJsonArraySessionId.get(size - 1).getAsJsonObject().get("sessionId").getAsString();
139         }
140         if ("0".equals(extractSessionId)) {
141             sessionIdLogger.debug(" Login Post Json Reponse not OK! , inverter answered with sessionId like: {}",
142                     extractSessionId);
143         }
144         return extractSessionId;
145     }
146
147     // Method extractCode extracts code from JsonObject
148     static String extractCode(JsonObject extractJsonObjectCode) {
149         Logger codeLogger = LoggerFactory.getLogger(SecondGenerationConfigurationHandler.class);
150         String extractCode = "";
151         JsonArray extractJsonArrayCode = extractJsonObjectCode.getAsJsonArray("status");
152
153         int size = extractJsonArrayCode.size();
154         if (size > 0) {
155             extractCode = extractJsonArrayCode.get(size - 1).getAsJsonObject().get("code").getAsString();
156         }
157         if (!"0".equals(extractCode)) {
158             codeLogger.debug(" Login Post Json Reponse not OK! , inverter answered with status code like: {}",
159                     extractCode);
160         }
161         return extractCode;
162     }
163 }