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.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) {
61 public void initialize() {
62 updateStatus(ThingStatus.ONLINE);
65 private List<Robot> sendGetRobots(String accessToken) {
66 Properties headers = new Properties();
67 headers.setProperty("Accept", "application/vnd.neato.nucleo.v1");
69 headers.setProperty("Authorization", "Token token=" + accessToken);
72 String resultString = HttpUtil.executeUrl("GET", "https://beehive.neatocloud.com/dashboard", headers, null,
73 "application/json", 20000);
75 Gson gson = new Gson();
76 NeatoAccountInformation accountInformation = gson.fromJson(resultString, NeatoAccountInformation.class);
78 logger.debug("Result from WS call to get Robots: {}", resultString);
80 return accountInformation.getRobots();
81 } catch (IOException e) {
82 logger.debug("Error attempting to find robots registered to account", e);
83 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
84 "Error attempting to find robots registered to account");
85 return new ArrayList<>();
89 public @NonNull List<Robot> getRobotsFromNeato() {
90 logger.debug("Attempting to find robots tied to account");
91 NeatoAccountConfig accountConfig = getConfigAs(NeatoAccountConfig.class);
92 String accessToken = authenticate(accountConfig.getEmail(), accountConfig.getPassword());
94 if (accessToken != null) {
95 return sendGetRobots(accessToken);
98 return new ArrayList<>();
101 private String authenticate(String username, String password) {
102 Gson gson = new Gson();
104 AuthRequest req = new AuthRequest(username, password, "ios",
105 new BigInteger(130, new SecureRandom()).toString(64));
107 String authenticationResponse = "";
109 authenticationResponse = sendAuthRequestToNeato(gson.toJson(req));
110 } catch (IOException e) {
111 logger.debug("Error when sending Authentication request to Neato.", e);
112 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
113 "Error when sending Authentication request to Neato.");
116 BeehiveAuthentication authenticationObject = gson.fromJson(authenticationResponse, BeehiveAuthentication.class);
117 return authenticationObject.getAccessToken();
120 private String sendAuthRequestToNeato(String data) throws IOException {
121 Properties headers = new Properties();
122 headers.setProperty("Accept", "application/vnd.neato.nucleo.v1");
124 InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
125 String resultString = HttpUtil.executeUrl("POST", "https://beehive.neatocloud.com/sessions", headers, stream,
126 "application/json", 20000);
128 logger.debug("Authentication Response: {}", resultString);
133 private static class AuthRequest {
134 private String email;
135 private String password;
137 private String token;
139 public AuthRequest(String email, String password, String os, String token) {
141 this.password = password;
146 public String getEmail() {
150 public String getPassword() {
154 public String getOs() {
158 public String getToken() {