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.neato.internal.handler;
15 import java.io.ByteArrayInputStream;
16 import java.io.IOException;
17 import java.io.InputStream;
18 import java.math.BigInteger;
19 import java.nio.charset.StandardCharsets;
20 import java.security.SecureRandom;
21 import java.util.ArrayList;
22 import java.util.List;
23 import java.util.Properties;
25 import org.eclipse.jdt.annotation.NonNull;
26 import org.openhab.binding.neato.internal.classes.BeehiveAuthentication;
27 import org.openhab.binding.neato.internal.classes.NeatoAccountInformation;
28 import org.openhab.binding.neato.internal.classes.Robot;
29 import org.openhab.binding.neato.internal.config.NeatoAccountConfig;
30 import org.openhab.core.io.net.http.HttpUtil;
31 import org.openhab.core.thing.Bridge;
32 import org.openhab.core.thing.ChannelUID;
33 import org.openhab.core.thing.ThingStatus;
34 import org.openhab.core.thing.ThingStatusDetail;
35 import org.openhab.core.thing.binding.BaseBridgeHandler;
36 import org.openhab.core.types.Command;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
40 import com.google.gson.Gson;
43 * Bridge handler to manage Neato Cloud Account
45 * @author Jeff Lauterbach - Initial Contribution
48 public class NeatoAccountHandler extends BaseBridgeHandler {
50 private final Logger logger = LoggerFactory.getLogger(NeatoAccountHandler.class);
52 public NeatoAccountHandler(Bridge bridge) {
57 public void handleCommand(ChannelUID channelUID, Command command) {
60 private List<Robot> sendGetRobots(String accessToken) {
61 Properties headers = new Properties();
62 headers.setProperty("Accept", "application/vnd.neato.nucleo.v1");
64 headers.setProperty("Authorization", "Token token=" + accessToken);
67 String resultString = HttpUtil.executeUrl("GET", "https://beehive.neatocloud.com/dashboard", headers, null,
68 "application/json", 20000);
70 Gson gson = new Gson();
71 NeatoAccountInformation accountInformation = gson.fromJson(resultString, NeatoAccountInformation.class);
73 logger.debug("Result from WS call to get Robots: {}", resultString);
75 return accountInformation.getRobots();
76 } catch (IOException e) {
77 logger.debug("Error attempting to find robots registered to account", e);
78 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
79 "Error attempting to find robots registered to account");
80 return new ArrayList<>();
84 public @NonNull List<Robot> getRobotsFromNeato() {
85 logger.debug("Attempting to find robots tied to account");
86 NeatoAccountConfig accountConfig = getConfigAs(NeatoAccountConfig.class);
87 String accessToken = authenticate(accountConfig.getEmail(), accountConfig.getPassword());
89 if (accessToken != null) {
90 return sendGetRobots(accessToken);
93 return new ArrayList<>();
96 private String authenticate(String username, String password) {
97 Gson gson = new Gson();
99 AuthRequest req = new AuthRequest(username, password, "ios",
100 new BigInteger(130, new SecureRandom()).toString(64));
102 String authenticationResponse = "";
104 authenticationResponse = sendAuthRequestToNeato(gson.toJson(req));
105 } catch (IOException e) {
106 logger.debug("Error when sending Authentication request to Neato.", e);
107 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
108 "Error when sending Authentication request to Neato.");
111 BeehiveAuthentication authenticationObject = gson.fromJson(authenticationResponse, BeehiveAuthentication.class);
112 return authenticationObject.getAccessToken();
115 private String sendAuthRequestToNeato(String data) throws IOException {
116 Properties headers = new Properties();
117 headers.setProperty("Accept", "application/vnd.neato.nucleo.v1");
119 InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
120 String resultString = HttpUtil.executeUrl("POST", "https://beehive.neatocloud.com/sessions", headers, stream,
121 "application/json", 20000);
123 logger.debug("Authentication Response: {}", resultString);
128 private static class AuthRequest {
129 private String email;
130 private String password;
132 private String token;
134 public AuthRequest(String email, String password, String os, String token) {
136 this.password = password;
141 public String getEmail() {
145 public String getPassword() {
149 public String getOs() {
153 public String getToken() {