]> git.basschouten.com Git - openhab-addons.git/blob
e17ebb6f2c1b641dbbbbad78b6f470eba28fbcf0
[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.hydrawise.internal.api;
14
15 import java.util.concurrent.TimeUnit;
16
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jetty.client.HttpClient;
19 import org.eclipse.jetty.client.api.ContentResponse;
20 import org.eclipse.jetty.http.HttpMethod;
21 import org.openhab.binding.hydrawise.internal.api.model.CustomerDetailsResponse;
22 import org.openhab.binding.hydrawise.internal.api.model.Response;
23 import org.openhab.binding.hydrawise.internal.api.model.SetControllerResponse;
24 import org.openhab.binding.hydrawise.internal.api.model.SetZoneResponse;
25 import org.openhab.binding.hydrawise.internal.api.model.StatusScheduleResponse;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 import com.google.gson.FieldNamingPolicy;
30 import com.google.gson.Gson;
31 import com.google.gson.GsonBuilder;
32
33 /**
34  * The {@link HydrawiseCloudApiClient} communicates with the cloud based Hydrawise API service
35  *
36  * @author Dan Cunningham - Initial contribution
37  */
38 @NonNullByDefault
39 public class HydrawiseCloudApiClient {
40     private final Logger logger = LoggerFactory.getLogger(HydrawiseCloudApiClient.class);
41
42     private final Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
43             .create();
44     private static final String BASE_URL = "https://app.hydrawise.com/api/v1/";
45     private static final String STATUS_SCHEDUE_URL = BASE_URL
46             + "statusschedule.php?api_key=%s&controller_id=%d&hours=168";
47     private static final String CUSTOMER_DETAILS_URL = BASE_URL + "customerdetails.php?api_key=%s&type=controllers";
48     private static final String SET_CONTROLLER_URL = BASE_URL
49             + "setcontroller.php?api_key=%s&controller_id=%d&json=true";
50     private static final String SET_ZONE_URL = BASE_URL + "setzone.php?period_id=999";
51     private static final int TIMEOUT_SECONDS = 30;
52     private final HttpClient httpClient;
53     private String apiKey;
54
55     /**
56      * Initializes the API client with a HydraWise API key from a user's account and the HTTPClient to use
57      *
58      */
59     public HydrawiseCloudApiClient(String apiKey, HttpClient httpClient) {
60         this.apiKey = apiKey;
61         this.httpClient = httpClient;
62     }
63
64     /**
65      * Initializes the API client with a HTTPClient to use
66      *
67      */
68     public HydrawiseCloudApiClient(HttpClient httpClient) {
69         this("", httpClient);
70     }
71
72     /**
73      * Set a new API key to use for requests
74      *
75      * @param apiKey
76      */
77     public void setApiKey(String apiKey) {
78         this.apiKey = apiKey;
79     }
80
81     /**
82      * Retrieves the {@link StatusScheduleResponse} for a given controller
83      *
84      * @param controllerId
85      * @return
86      * @throws HydrawiseConnectionException
87      * @throws HydrawiseAuthenticationException
88      */
89     public StatusScheduleResponse getStatusSchedule(int controllerId)
90             throws HydrawiseConnectionException, HydrawiseAuthenticationException {
91         String json = doGet(String.format(STATUS_SCHEDUE_URL, apiKey, controllerId));
92         StatusScheduleResponse response = gson.fromJson(json, StatusScheduleResponse.class);
93         throwExceptionIfResponseError(response);
94         return response;
95     }
96
97     /***
98      * Retrieves the {@link CustomerDetailsResponse}
99      *
100      * @return
101      * @throws HydrawiseConnectionException
102      * @throws HydrawiseAuthenticationException
103      */
104     public CustomerDetailsResponse getCustomerDetails()
105             throws HydrawiseConnectionException, HydrawiseAuthenticationException {
106         String json = doGet(String.format(CUSTOMER_DETAILS_URL, apiKey));
107         CustomerDetailsResponse response = gson.fromJson(json, CustomerDetailsResponse.class);
108         throwExceptionIfResponseError(response);
109         return response;
110     }
111
112     /***
113      * Sets the controller with supplied {@value id} as the current controller
114      *
115      * @param id
116      * @return SetControllerResponse
117      * @throws HydrawiseConnectionException
118      * @throws HydrawiseAuthenticationException
119      * @throws HydrawiseCommandException
120      */
121     public SetControllerResponse setController(int id)
122             throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
123         String json = doGet(String.format(SET_CONTROLLER_URL, apiKey, id));
124         SetControllerResponse response = gson.fromJson(json, SetControllerResponse.class);
125         throwExceptionIfResponseError(response);
126         if (!response.message.equals("OK")) {
127             throw new HydrawiseCommandException(response.message);
128         }
129         return response;
130     }
131
132     /***
133      * Stops a given relay
134      *
135      * @param relayId
136      * @return Response message
137      * @throws HydrawiseConnectionException
138      * @throws HydrawiseAuthenticationException
139      * @throws HydrawiseCommandException
140      */
141     public String stopRelay(int relayId)
142             throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
143         return relayCommand(
144                 new HydrawiseZoneCommandBuilder(SET_ZONE_URL, apiKey).action("stop").relayId(relayId).toString());
145     }
146
147     /**
148      * Stops all relays on a given controller
149      *
150      * @param controllerId
151      * @return Response message
152      * @throws HydrawiseConnectionException
153      * @throws HydrawiseAuthenticationException
154      * @throws HydrawiseCommandException
155      */
156     public String stopAllRelays(int controllerId)
157             throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
158         return relayCommand(new HydrawiseZoneCommandBuilder(SET_ZONE_URL, apiKey).action("stopall")
159                 .controllerId(controllerId).toString());
160     }
161
162     /**
163      * Runs a relay for the default amount of time
164      *
165      * @param relayId
166      * @return Response message
167      * @throws HydrawiseConnectionException
168      * @throws HydrawiseAuthenticationException
169      * @throws HydrawiseCommandException
170      */
171     public String runRelay(int relayId)
172             throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
173         return relayCommand(
174                 new HydrawiseZoneCommandBuilder(SET_ZONE_URL, apiKey).action("run").relayId(relayId).toString());
175     }
176
177     /**
178      * Runs a relay for the given amount of seconds
179      *
180      * @param seconds
181      * @param relayId
182      * @return Response message
183      * @throws HydrawiseConnectionException
184      * @throws HydrawiseAuthenticationException
185      * @throws HydrawiseCommandException
186      */
187     public String runRelay(int seconds, int relayId)
188             throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
189         return relayCommand(new HydrawiseZoneCommandBuilder(SET_ZONE_URL, apiKey).action("run").relayId(relayId)
190                 .duration(seconds).toString());
191     }
192
193     /**
194      * Run all relays on a given controller for the default amount of time
195      *
196      * @param controllerId
197      * @return Response message
198      * @throws HydrawiseConnectionException
199      * @throws HydrawiseAuthenticationException
200      * @throws HydrawiseCommandException
201      */
202     public String runAllRelays(int controllerId)
203             throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
204         return relayCommand(new HydrawiseZoneCommandBuilder(SET_ZONE_URL, apiKey).action("runall")
205                 .controllerId(controllerId).toString());
206     }
207
208     /***
209      * Run all relays on a given controller for the amount of seconds
210      *
211      * @param seconds
212      * @param controllerId
213      * @return Response message
214      * @throws HydrawiseConnectionException
215      * @throws HydrawiseAuthenticationException
216      * @throws HydrawiseCommandException
217      */
218     public String runAllRelays(int seconds, int controllerId)
219             throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
220         return relayCommand(new HydrawiseZoneCommandBuilder(SET_ZONE_URL, apiKey).action("runall")
221                 .controllerId(controllerId).duration(seconds).toString());
222     }
223
224     /**
225      * Suspends a given relay
226      *
227      * @param relayId
228      * @return Response message
229      * @throws HydrawiseConnectionException
230      * @throws HydrawiseAuthenticationException
231      * @throws HydrawiseCommandException
232      */
233     public String suspendRelay(int relayId)
234             throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
235         return relayCommand(
236                 new HydrawiseZoneCommandBuilder(SET_ZONE_URL, apiKey).action("suspend").relayId(relayId).toString());
237     }
238
239     /**
240      * Suspends a given relay for an amount of seconds
241      *
242      * @param seconds
243      * @param relayId
244      * @return Response message
245      * @throws HydrawiseConnectionException
246      * @throws HydrawiseAuthenticationException
247      * @throws HydrawiseCommandException
248      */
249     public String suspendRelay(int seconds, int relayId)
250             throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
251         return relayCommand(new HydrawiseZoneCommandBuilder(SET_ZONE_URL, apiKey).action("suspend").relayId(relayId)
252                 .duration(seconds).toString());
253     }
254
255     /**
256      * Suspend all relays on a given controller for an amount of seconds
257      *
258      * @param seconds
259      * @param controllerId
260      * @return Response message
261      * @throws HydrawiseConnectionException
262      * @throws HydrawiseAuthenticationException
263      * @throws HydrawiseCommandException
264      */
265     public String suspendAllRelays(int seconds, int controllerId)
266             throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
267         return relayCommand(new HydrawiseZoneCommandBuilder(SET_ZONE_URL, apiKey).action("suspendall")
268                 .controllerId(controllerId).duration(seconds).toString());
269     }
270
271     private String relayCommand(String url)
272             throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
273         String json = doGet(url);
274         SetZoneResponse response = gson.fromJson(json, SetZoneResponse.class);
275         throwExceptionIfResponseError(response);
276         if ("error".equals(response.messageType)) {
277             throw new HydrawiseCommandException(response.message);
278         }
279         return response.message;
280     }
281
282     private String doGet(String url) throws HydrawiseConnectionException {
283         logger.trace("Getting {}", url);
284         ContentResponse response;
285         try {
286             response = httpClient.newRequest(url).method(HttpMethod.GET).timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
287                     .send();
288         } catch (Exception e) {
289             throw new HydrawiseConnectionException(e);
290         }
291         if (response.getStatus() != 200) {
292             throw new HydrawiseConnectionException(
293                     "Could not connect to Hydrawise API.  Response code " + response.getStatus());
294         }
295         String stringResponse = response.getContentAsString();
296         logger.trace("Response: {}", stringResponse);
297         return stringResponse;
298     }
299
300     private void throwExceptionIfResponseError(Response response)
301             throws HydrawiseConnectionException, HydrawiseAuthenticationException {
302         String error = response.errorMsg;
303         if (error != null) {
304             if (error.equalsIgnoreCase("unauthorized")) {
305                 throw new HydrawiseAuthenticationException();
306             } else {
307                 throw new HydrawiseConnectionException(response.errorMsg);
308             }
309         }
310     }
311 }