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