2 * Copyright (c) 2010-2021 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.automower.internal.rest.api.automowerconnect;
15 import java.util.concurrent.ExecutionException;
16 import java.util.concurrent.TimeUnit;
17 import java.util.concurrent.TimeoutException;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jetty.client.HttpClient;
21 import org.eclipse.jetty.client.api.ContentResponse;
22 import org.eclipse.jetty.client.api.Request;
23 import org.eclipse.jetty.client.util.StringContentProvider;
24 import org.eclipse.jetty.http.HttpMethod;
25 import org.eclipse.jetty.http.HttpStatus;
26 import org.openhab.binding.automower.internal.rest.api.HusqvarnaApi;
27 import org.openhab.binding.automower.internal.rest.api.automowerconnect.dto.MowerCommandRequest;
28 import org.openhab.binding.automower.internal.rest.api.automowerconnect.dto.MowerListResult;
29 import org.openhab.binding.automower.internal.rest.api.automowerconnect.dto.MowerResult;
30 import org.openhab.binding.automower.internal.rest.exceptions.AutomowerCommunicationException;
31 import org.openhab.binding.automower.internal.rest.exceptions.UnauthorizedException;
33 import com.google.gson.JsonSyntaxException;
36 * Allows access to the AutomowerConnectApi
38 * @author Markus Pfleger - Initial contribution
41 public class AutomowerConnectApi extends HusqvarnaApi {
43 public AutomowerConnectApi(HttpClient httpClient) {
48 public String getBaseUrl() {
49 return "https://api.amc.husqvarna.dev/v1";
52 public MowerListResult getMowers(String appKey, String token) throws AutomowerCommunicationException {
53 final Request request = getHttpClient().newRequest(getBaseUrl() + "/mowers");
54 request.method(HttpMethod.GET);
56 ContentResponse response = executeRequest(appKey, token, request);
58 return parseResponse(response, MowerListResult.class);
61 public MowerResult getMower(String appKey, String token, String mowerId) throws AutomowerCommunicationException {
62 final Request request = getHttpClient().newRequest(getBaseUrl() + "/mowers/" + mowerId);
63 request.method(HttpMethod.GET);
65 ContentResponse response = executeRequest(appKey, token, request);
67 return parseResponse(response, MowerResult.class);
70 public void sendCommand(String appKey, String token, String id, MowerCommandRequest command)
71 throws AutomowerCommunicationException {
72 final Request request = getHttpClient().newRequest(getBaseUrl() + "/mowers/" + id + "/actions");
73 request.method(HttpMethod.POST);
75 request.content(new StringContentProvider(gson.toJson(command)));
77 ContentResponse response = executeRequest(appKey, token, request);
79 checkForError(response, response.getStatus());
82 private ContentResponse executeRequest(String appKey, String token, final Request request)
83 throws AutomowerCommunicationException {
85 request.timeout(10, TimeUnit.SECONDS);
87 request.header("Authorization-Provider", "husqvarna");
88 request.header("Authorization", "Bearer " + token);
89 request.header("X-Api-Key", appKey);
90 request.header("Content-Type", "application/vnd.api+json");
92 ContentResponse response;
94 response = request.send();
95 } catch (InterruptedException | TimeoutException | ExecutionException e) {
96 throw new AutomowerCommunicationException(e);
101 private <T> T parseResponse(ContentResponse response, Class<T> type) throws AutomowerCommunicationException {
102 int statusCode = response.getStatus();
104 checkForError(response, statusCode);
107 return gson.fromJson(response.getContentAsString(), type);
108 } catch (JsonSyntaxException e) {
109 throw new AutomowerCommunicationException(e);
113 private void checkForError(ContentResponse response, int statusCode) throws AutomowerCommunicationException {
114 if (statusCode >= 200 && statusCode < 300) {
118 switch (statusCode) {
119 case HttpStatus.NOT_FOUND_404:
120 throw new AutomowerCommunicationException(statusCode, "Target '" + response.getRequest().getURI()
121 + "' seems to be not available: " + response.getContentAsString());
123 case HttpStatus.FORBIDDEN_403:
124 case HttpStatus.UNAUTHORIZED_401:
125 throw new UnauthorizedException(statusCode, response.getContentAsString());
128 throw new AutomowerCommunicationException(statusCode, response.getContentAsString());