]> git.basschouten.com Git - openhab-addons.git/blob
d865f95ce69642b35c66474094184cf757077496
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.touchwand.internal;
14
15 import static org.openhab.binding.touchwand.internal.TouchWandBindingConstants.*;
16
17 import java.io.UnsupportedEncodingException;
18 import java.net.CookieManager;
19 import java.net.MalformedURLException;
20 import java.net.URL;
21 import java.net.URLEncoder;
22 import java.nio.charset.StandardCharsets;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.concurrent.ExecutionException;
26 import java.util.concurrent.TimeUnit;
27 import java.util.concurrent.TimeoutException;
28
29 import org.eclipse.jdt.annotation.NonNullByDefault;
30 import org.eclipse.jetty.client.HttpClient;
31 import org.eclipse.jetty.client.api.ContentProvider;
32 import org.eclipse.jetty.client.api.ContentResponse;
33 import org.eclipse.jetty.client.api.Request;
34 import org.eclipse.jetty.client.util.StringContentProvider;
35 import org.eclipse.jetty.http.HttpMethod;
36 import org.eclipse.jetty.http.MimeTypes;
37 import org.openhab.core.library.types.OnOffType;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 /**
42  * The {@link TouchWandRestClient} is responsible for handling low level commands units TouchWand WonderFull hub
43  * REST API interface
44  *
45  * @author Roie Geron - Initial contribution
46  */
47 @NonNullByDefault
48 public class TouchWandRestClient {
49
50     private final Logger logger = LoggerFactory.getLogger(TouchWandRestClient.class);
51
52     static CookieManager cookieManager = new CookieManager();
53
54     private static final HttpMethod METHOD_GET = HttpMethod.GET;
55     private static final HttpMethod METHOD_POST = HttpMethod.POST;
56
57     private static final String CMD_LOGIN = "login";
58     private static final String CMD_LIST_UNITS = "listunits";
59     private static final String CMD_LIST_SCENARIOS = "listsencarios";
60     private static final String CMD_UNIT_ACTION = "action";
61     private static final String CMD_GET_UNIT_BY_ID = "getunitbyid";
62
63     private static final String ACTION_SWITCH_OFF = "{\"id\":%s,\"value\":" + SWITCH_STATUS_OFF + "}";
64     private static final String ACTION_SWITCH_ON = "{\"id\":%s,\"value\":" + SWITCH_STATUS_ON + "}";
65     private static final String ACTION_SHUTTER_DOWN = "{\"id\":%s,\"value\":0,\"type\":\"height\"}";
66     private static final String ACTION_SHUTTER_UP = "{\"id\":%s,\"value\":255,\"type\":\"height\"}";
67     private static final String ACTION_SHUTTER_STOP = "{\"id\":%s,\"value\":0,\"type\":\"stop\"}";
68     private static final String ACTION_SHUTTER_POSITION = "{\"id\":%s,\"value\":%s}";
69     private static final String ACTION_DIMMER_POSITION = "{\"id\":%s,\"value\":%s}";
70     private static final String ACTION_THERMOSTAT_ON = "{\"id\":%s,\"value\":" + THERMOSTAT_STATE_ON + "}";
71     private static final String ACTION_THERMOSTAT_OFF = "{\"id\":%s,\"value\":" + THERMOSTAT_STATE_OFF + "}";
72     private static final String ACTION_THERMOSTAT_MODE = "{\"id\":%s,\"ac-all\":\"mode\",\"fan\":\"%s\"}";
73     private static final String ACTION_THERMOSTAT_FAN_LEVEL = "{\"id\":%s,\"ac-all\":\"fan\",\"fan\":\"%s\"}";
74     private static final String ACTION_THERMOSTAT_TARGET_TEMPERATURE = "{\"id\":%s,\"ac-all\":\"temp\",\"temp_val\":%s}";
75
76     private static final String CONTENT_TYPE_APPLICATION_JSON = MimeTypes.Type.APPLICATION_JSON.asString();
77
78     private static final int REQUEST_TIMEOUT_SEC = 10;
79
80     private static final Map<String, String> COMMAND_MAP = new HashMap<String, String>();
81     static {
82         COMMAND_MAP.put(CMD_LOGIN, "/auth/login?");
83         COMMAND_MAP.put(CMD_LIST_UNITS, "/units/listUnits");
84         COMMAND_MAP.put(CMD_LIST_SCENARIOS, "/scenarios/listScenarios");
85         COMMAND_MAP.put(CMD_UNIT_ACTION, "/units/action");
86         COMMAND_MAP.put(CMD_GET_UNIT_BY_ID, "/units/getUnitByID?");
87     }
88
89     private String touchWandIpAddr = "";
90     private String touchWandPort = "";
91     private boolean isConnected = false;
92     private HttpClient httpClient;
93
94     public TouchWandRestClient(HttpClient httpClient) {
95         this.httpClient = httpClient;
96     }
97
98     public final boolean connect(String user, String pass, String ipAddr, String port) {
99         touchWandIpAddr = ipAddr;
100         touchWandPort = port;
101         isConnected = cmdLogin(user, pass, ipAddr);
102
103         return isConnected;
104     }
105
106     private final boolean cmdLogin(String user, String pass, String ipAddr) {
107         String encodedUser;
108         String encodedPass;
109         String response = "";
110
111         try {
112             encodedUser = URLEncoder.encode(user, StandardCharsets.UTF_8.toString());
113             encodedPass = URLEncoder.encode(pass, StandardCharsets.UTF_8.toString());
114             String command = buildUrl(CMD_LOGIN) + "user=" + encodedUser + "&" + "psw=" + encodedPass;
115             response = sendCommand(command, METHOD_GET, "");
116         } catch (UnsupportedEncodingException e) {
117             logger.warn("Error url encoding username or password : {}", e.getMessage());
118         }
119
120         return !response.equals("Unauthorized");
121     }
122
123     public String cmdListUnits() {
124         String response = "";
125         if (isConnected) {
126             String command = buildUrl(CMD_LIST_UNITS);
127             response = sendCommand(command, METHOD_GET, "");
128         }
129         return response;
130     }
131
132     public String cmdGetUnitById(String id) {
133         String response = "";
134
135         if (isConnected) {
136             String command = buildUrl(CMD_GET_UNIT_BY_ID) + "id=" + id;
137             response = sendCommand(command, METHOD_GET, "");
138         }
139         return response;
140     }
141
142     public void cmdSwitchOnOff(String id, OnOffType onoff) {
143         String action;
144
145         if (OnOffType.OFF.equals(onoff)) {
146             action = String.format(ACTION_SWITCH_OFF, id);
147         } else {
148             action = String.format(ACTION_SWITCH_ON, id);
149         }
150         cmdUnitAction(action);
151     }
152
153     public void cmdShutterUp(String id) {
154         String action = String.format(ACTION_SHUTTER_UP, id);
155         cmdUnitAction(action);
156     }
157
158     public void cmdShutterDown(String id) {
159         String action = String.format(ACTION_SHUTTER_DOWN, id);
160         cmdUnitAction(action);
161     }
162
163     public void cmdShutterPosition(String id, String position) {
164         String action = String.format(ACTION_SHUTTER_POSITION, id, position);
165         cmdUnitAction(action);
166     }
167
168     public void cmdShutterStop(String id) {
169         String action = String.format(ACTION_SHUTTER_STOP, id);
170         cmdUnitAction(action);
171     }
172
173     public void cmdDimmerPosition(String id, String position) {
174         String action = String.format(ACTION_DIMMER_POSITION, id, position);
175         cmdUnitAction(action);
176     }
177
178     public void cmdThermostatOnOff(String id, OnOffType onoff) {
179         String action;
180
181         if (OnOffType.OFF.equals(onoff)) {
182             action = String.format(ACTION_THERMOSTAT_OFF, id);
183         } else {
184             action = String.format(ACTION_THERMOSTAT_ON, id);
185         }
186         cmdUnitAction(action);
187     }
188
189     public void cmdThermostatMode(String id, String mode) {
190         String action = String.format(ACTION_THERMOSTAT_MODE, id, mode);
191         cmdUnitAction(action);
192     }
193
194     public void cmdThermostatFanLevel(String id, String fanLevel) {
195         String action = String.format(ACTION_THERMOSTAT_FAN_LEVEL, id, fanLevel);
196         cmdUnitAction(action);
197     }
198
199     public void cmdThermostatTargetTemperature(String id, String targetTemperature) {
200         String action = String.format(ACTION_THERMOSTAT_TARGET_TEMPERATURE, id, targetTemperature);
201         cmdUnitAction(action);
202     }
203
204     private String cmdUnitAction(String action) {
205         String response = "";
206         if (isConnected) {
207             String command = buildUrl(CMD_UNIT_ACTION);
208             response = sendCommand(command, METHOD_POST, action);
209         }
210         return response;
211     }
212
213     private String buildUrl(String command) {
214         String url = "http://" + touchWandIpAddr + ":" + touchWandPort + COMMAND_MAP.get(command);
215         return url;
216     }
217
218     private synchronized String sendCommand(String command, HttpMethod method, String content) {
219         ContentResponse response;
220         Request request;
221
222         URL url = null;
223         try {
224             url = new URL(command);
225         } catch (MalformedURLException e) {
226             logger.warn("Error building URL {} : {}", command, e.getMessage());
227             return "";
228         }
229
230         request = httpClient.newRequest(url.toString()).timeout(REQUEST_TIMEOUT_SEC, TimeUnit.SECONDS).method(method);
231         if (method.equals(METHOD_POST) && (!content.isEmpty())) {
232             ContentProvider contentProvider = new StringContentProvider(CONTENT_TYPE_APPLICATION_JSON, content,
233                     StandardCharsets.UTF_8);
234             request = request.content(contentProvider);
235         }
236
237         try {
238             response = request.send();
239             return response.getContentAsString();
240         } catch (InterruptedException | TimeoutException | ExecutionException e) {
241             logger.warn("Error opening connecton to {} : {} ", touchWandIpAddr, e.getMessage());
242         }
243         return "";
244     }
245 }