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