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 return gson.fromJson(json, LocalScheduleResponse.class);
106 * Stops a given relay
109 * @return Response message
110 * @throws HydrawiseConnectionException
111 * @throws HydrawiseAuthenticationException
112 * @throws HydrawiseCommandException
114 public String stopRelay(int number)
115 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
116 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("stop").relayNumber(number).toString());
120 * Runs a given relay for the default amount of time
123 * @return Response message
124 * @throws HydrawiseConnectionException
125 * @throws HydrawiseAuthenticationException
126 * @throws HydrawiseCommandException
128 public String runRelay(int number)
129 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
130 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("run").relayNumber(number).toString());
134 * Runs a given relay for a specified numbers of seconds
138 * @return Response message
139 * @throws HydrawiseConnectionException
140 * @throws HydrawiseAuthenticationException
141 * @throws HydrawiseCommandException
143 public String runRelay(int seconds, int number)
144 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
145 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("run").relayNumber(number)
146 .duration(seconds).toString());
152 * @return Response message
153 * @throws HydrawiseConnectionException
154 * @throws HydrawiseAuthenticationException
155 * @throws HydrawiseCommandException
157 public String stopAllRelays()
158 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
159 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("stopall").toString());
163 * Run all relays for the default amount of time
165 * @return Response message
166 * @throws HydrawiseConnectionException
167 * @throws HydrawiseAuthenticationException
168 * @throws HydrawiseCommandException
170 public String runAllRelays()
171 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
172 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("runall").toString());
176 * Run all relays for a given amount of seconds
179 * @return Response message
180 * @throws HydrawiseConnectionException
181 * @throws HydrawiseAuthenticationException
182 * @throws HydrawiseCommandException
184 public String runAllRelays(int seconds)
185 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
186 return relayCommand(new HydrawiseZoneCommandBuilder(localSetURL).action("runall").duration(seconds).toString());
189 private String relayCommand(String url)
190 throws HydrawiseConnectionException, HydrawiseAuthenticationException, HydrawiseCommandException {
191 String json = doGet(url);
192 SetZoneResponse response = gson.fromJson(json, SetZoneResponse.class);
193 if ("error".equals(response.messageType)) {
194 throw new HydrawiseCommandException(response.message);
196 return response.message;
199 private String doGet(String url) throws HydrawiseConnectionException, HydrawiseAuthenticationException {
200 logger.trace("Getting {}", url);
201 ContentResponse response;
203 response = httpClient.newRequest(url).method(HttpMethod.GET).timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
205 } catch (InterruptedException | TimeoutException | ExecutionException e) {
206 throw new HydrawiseConnectionException(e);
208 if (response.getStatus() == 401) {
209 throw new HydrawiseAuthenticationException();
211 if (response.getStatus() != 200) {
212 throw new HydrawiseConnectionException("Error from controller. Response code " + response.getStatus());
214 String stringResponse = response.getContentAsString();
215 logger.trace("Response: {}", stringResponse);
216 return stringResponse;