2 * Copyright (c) 2010-2023 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.local;
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.jdt.annotation.Nullable;
22 import org.eclipse.jetty.client.HttpClient;
23 import org.eclipse.jetty.client.api.AuthenticationStore;
24 import org.eclipse.jetty.client.api.ContentResponse;
25 import org.eclipse.jetty.client.util.BasicAuthentication;
26 import org.eclipse.jetty.http.HttpMethod;
27 import org.openhab.binding.hydrawise.internal.api.HydrawiseAuthenticationException;
28 import org.openhab.binding.hydrawise.internal.api.HydrawiseCommandException;
29 import org.openhab.binding.hydrawise.internal.api.HydrawiseConnectionException;
30 import org.openhab.binding.hydrawise.internal.api.local.dto.LocalScheduleResponse;
31 import org.openhab.binding.hydrawise.internal.api.local.dto.SetZoneResponse;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
35 import com.google.gson.FieldNamingPolicy;
36 import com.google.gson.Gson;
37 import com.google.gson.GsonBuilder;
40 * The {@link HydrawiseLocalApiClient} communicates with a network local Hydrawise controller.
42 * @author Dan Cunningham - Initial contribution
45 public class HydrawiseLocalApiClient {
46 private final Logger logger = LoggerFactory.getLogger(HydrawiseLocalApiClient.class);
48 private final Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
51 private static final String GET_LOCAL_DATA_URL = "%s/get_sched_json.php?hours=720";
52 private static final String SET_LOCAL_DATA_URL = "%s/set_manual_data.php?period_id=998";
54 private static final int TIMEOUT_SECONDS = 30;
55 private HttpClient httpClient;
56 private String localSetURL = "";
57 private String localGetURL = "";
59 public HydrawiseLocalApiClient(HttpClient httpClient) {
60 this.httpClient = httpClient;
64 * Initializes the {@link HydrawiseLocalApiClient} to talk with the network local Hydrawise API
70 public HydrawiseLocalApiClient(String host, String username, String password, HttpClient httpClient) {
71 this.httpClient = httpClient;
72 setCredentials(host, username, password);
76 * Sets the local credentials and controller host
82 public void setCredentials(String host, String username, String password) {
83 String url = "http://" + host;
84 localSetURL = String.format(SET_LOCAL_DATA_URL, url);
85 localGetURL = String.format(GET_LOCAL_DATA_URL, url);
86 AuthenticationStore auth = httpClient.getAuthenticationStore();
87 URI uri = URI.create(url);
88 auth.addAuthenticationResult(new BasicAuthentication.BasicResult(uri, username, password));
92 * Retrieves the {@link LocalScheduleResponse} for the controller
94 * @return the local schedule response
95 * @throws HydrawiseConnectionException
96 * @throws HydrawiseAuthenticationException
99 public LocalScheduleResponse getLocalSchedule()
100 throws HydrawiseConnectionException, HydrawiseAuthenticationException {
101 String json = doGet(localGetURL);
102 LocalScheduleResponse response = gson.fromJson(json, LocalScheduleResponse.class);
107 * Stops a given relay
110 * @return Response message
111 * @throws HydrawiseConnectionException
112 * @throws HydrawiseAuthenticationException
113 * @throws HydrawiseCommandException
115 public String stopRelay(int number)
116 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
117 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("stop").relayNumber(number).toString());
121 * Runs a given relay for the default amount of time
124 * @return Response message
125 * @throws HydrawiseConnectionException
126 * @throws HydrawiseAuthenticationException
127 * @throws HydrawiseCommandException
129 public String runRelay(int number)
130 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
131 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("run").relayNumber(number).toString());
135 * Runs a given relay for a specified numbers of seconds
139 * @return Response message
140 * @throws HydrawiseConnectionException
141 * @throws HydrawiseAuthenticationException
142 * @throws HydrawiseCommandException
144 public String runRelay(int seconds, int number)
145 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
146 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("run").relayNumber(number)
147 .duration(seconds).toString());
153 * @return Response message
154 * @throws HydrawiseConnectionException
155 * @throws HydrawiseAuthenticationException
156 * @throws HydrawiseCommandException
158 public String stopAllRelays()
159 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
160 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("stopall").toString());
164 * Run all relays for the default amount of time
166 * @return Response message
167 * @throws HydrawiseConnectionException
168 * @throws HydrawiseAuthenticationException
169 * @throws HydrawiseCommandException
171 public String runAllRelays()
172 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
173 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("runall").toString());
177 * Run all relays for a given amount of seconds
180 * @return Response message
181 * @throws HydrawiseConnectionException
182 * @throws HydrawiseAuthenticationException
183 * @throws HydrawiseCommandException
185 public String runAllRelays(int seconds)
186 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
187 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("runall").duration(seconds).toString());
190 private String relayCommand(String url)
191 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
192 String json = doGet(url);
193 SetZoneResponse response = gson.fromJson(json, SetZoneResponse.class);
194 if (response.messageType.equals("error")) {
195 throw new HydrawiseCommandException(response.message);
197 return response.message;
200 private String doGet(String url) throws HydrawiseConnectionException, HydrawiseAuthenticationException {
201 logger.trace("Getting {}", url);
202 ContentResponse response;
204 response = httpClient.newRequest(url).method(HttpMethod.GET).timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
206 } catch (InterruptedException | TimeoutException | ExecutionException e) {
207 throw new HydrawiseConnectionException(e);
209 if (response.getStatus() == 401) {
210 throw new HydrawiseAuthenticationException();
212 if (response.getStatus() != 200) {
213 throw new HydrawiseConnectionException("Error from controller. Response code " + response.getStatus());
215 String stringResponse = response.getContentAsString();
216 logger.trace("Response: {}", stringResponse);
217 return stringResponse;