2 * Copyright (c) 2010-2020 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.hydrawise.internal.api;
16 import java.util.concurrent.ExecutionException;
17 import java.util.concurrent.TimeUnit;
18 import java.util.concurrent.TimeoutException;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jetty.client.HttpClient;
22 import org.eclipse.jetty.client.api.AuthenticationStore;
23 import org.eclipse.jetty.client.api.ContentResponse;
24 import org.eclipse.jetty.client.util.BasicAuthentication;
25 import org.eclipse.jetty.http.HttpMethod;
26 import org.openhab.binding.hydrawise.internal.api.model.LocalScheduleResponse;
27 import org.openhab.binding.hydrawise.internal.api.model.SetZoneResponse;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
31 import com.google.gson.FieldNamingPolicy;
32 import com.google.gson.Gson;
33 import com.google.gson.GsonBuilder;
36 * The {@link HydrawiseLocalApiClient} communicates with a network local Hydrawise controller.
38 * @author Dan Cunningham - Initial contribution
41 public class HydrawiseLocalApiClient {
42 private final Logger logger = LoggerFactory.getLogger(HydrawiseLocalApiClient.class);
44 private final Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
47 private static final String GET_LOCAL_DATA_URL = "%s/get_sched_json.php?hours=720";
48 private static final String SET_LOCAL_DATA_URL = "%s/set_manual_data.php?period_id=998";
50 private static final int TIMEOUT_SECONDS = 30;
51 private HttpClient httpClient;
52 private String localSetURL = "";
53 private String localGetURL = "";
55 public HydrawiseLocalApiClient(HttpClient httpClient) {
56 this.httpClient = httpClient;
60 * Initializes the {@link HydrawiseLocalApiClient} to talk with the network local Hydrawise API
66 public HydrawiseLocalApiClient(String host, String username, String password, HttpClient httpClient) {
67 this.httpClient = httpClient;
68 setCredentials(host, username, password);
72 * Sets the local credentials and controller host
78 public void setCredentials(String host, String username, String password) {
79 String url = "http://" + host;
80 localSetURL = String.format(SET_LOCAL_DATA_URL, url);
81 localGetURL = String.format(GET_LOCAL_DATA_URL, url);
82 AuthenticationStore auth = httpClient.getAuthenticationStore();
83 URI uri = URI.create(url);
84 auth.addAuthenticationResult(new BasicAuthentication.BasicResult(uri, username, password));
88 * Retrieves the {@link LocalScheduleResponse} for the controller
90 * @return the local schedule response
91 * @throws HydrawiseConnectionException
92 * @throws HydrawiseAuthenticationException
94 public LocalScheduleResponse getLocalSchedule()
95 throws HydrawiseConnectionException, HydrawiseAuthenticationException {
96 String json = doGet(localGetURL);
97 LocalScheduleResponse response = gson.fromJson(json, LocalScheduleResponse.class);
102 * Stops a given relay
105 * @return Response message
106 * @throws HydrawiseConnectionException
107 * @throws HydrawiseAuthenticationException
108 * @throws HydrawiseCommandException
110 public String stopRelay(int number)
111 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
112 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("stop").relayNumber(number).toString());
116 * Runs a given relay for the default amount of time
119 * @return Response message
120 * @throws HydrawiseConnectionException
121 * @throws HydrawiseAuthenticationException
122 * @throws HydrawiseCommandException
124 public String runRelay(int number)
125 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
126 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("run").relayNumber(number).toString());
130 * Runs a given relay for a specified numbers of seconds
134 * @return Response message
135 * @throws HydrawiseConnectionException
136 * @throws HydrawiseAuthenticationException
137 * @throws HydrawiseCommandException
139 public String runRelay(int seconds, int number)
140 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
141 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("run").relayNumber(number)
142 .duration(seconds).toString());
148 * @return Response message
149 * @throws HydrawiseConnectionException
150 * @throws HydrawiseAuthenticationException
151 * @throws HydrawiseCommandException
153 public String stopAllRelays()
154 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
155 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("stopall").toString());
159 * Run all relays for the default amount of time
161 * @return Response message
162 * @throws HydrawiseConnectionException
163 * @throws HydrawiseAuthenticationException
164 * @throws HydrawiseCommandException
166 public String runAllRelays()
167 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
168 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("runall").toString());
172 * Run all relays for a given amount of seconds
175 * @return Response message
176 * @throws HydrawiseConnectionException
177 * @throws HydrawiseAuthenticationException
178 * @throws HydrawiseCommandException
180 public String runAllRelays(int seconds)
181 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
182 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("runall").duration(seconds).toString());
185 private String relayCommand(String url)
186 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
187 String json = doGet(url);
188 SetZoneResponse response = gson.fromJson(json, SetZoneResponse.class);
189 if (response.messageType.equals("error")) {
190 throw new HydrawiseCommandException(response.message);
192 return response.message;
195 private String doGet(String url) throws HydrawiseConnectionException, HydrawiseAuthenticationException {
196 logger.trace("Getting {}", url);
197 ContentResponse response;
199 response = httpClient.newRequest(url).method(HttpMethod.GET).timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
201 } catch (InterruptedException | TimeoutException | ExecutionException e) {
202 throw new HydrawiseConnectionException(e);
204 if (response.getStatus() == 401) {
205 throw new HydrawiseAuthenticationException();
207 if (response.getStatus() != 200) {
208 throw new HydrawiseConnectionException("Error from controller. Response code " + response.getStatus());
210 String stringResponse = response.getContentAsString();
211 logger.trace("Response: {}", stringResponse);
212 return stringResponse;