]> git.basschouten.com Git - openhab-addons.git/blob
06dd9ef3f81ea508e4bf2f1e930dd1aa73cba713
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.neato.internal.handler;
14
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;
24
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;
39
40 import com.google.gson.Gson;
41
42 /**
43  * Bridge handler to manage Neato Cloud Account
44  *
45  * @author Jeff Lauterbach - Initial Contribution
46  *
47  */
48 public class NeatoAccountHandler extends BaseBridgeHandler {
49
50     private final Logger logger = LoggerFactory.getLogger(NeatoAccountHandler.class);
51
52     public NeatoAccountHandler(Bridge bridge) {
53         super(bridge);
54     }
55
56     @Override
57     public void handleCommand(ChannelUID channelUID, Command command) {
58     }
59
60     private List<Robot> sendGetRobots(String accessToken) {
61         Properties headers = new Properties();
62         headers.setProperty("Accept", "application/vnd.neato.nucleo.v1");
63
64         headers.setProperty("Authorization", "Token token=" + accessToken);
65
66         try {
67             String resultString = HttpUtil.executeUrl("GET", "https://beehive.neatocloud.com/dashboard", headers, null,
68                     "application/json", 20000);
69
70             Gson gson = new Gson();
71             NeatoAccountInformation accountInformation = gson.fromJson(resultString, NeatoAccountInformation.class);
72
73             logger.debug("Result from WS call to get Robots: {}", resultString);
74
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<>();
81         }
82     }
83
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());
88
89         if (accessToken != null) {
90             return sendGetRobots(accessToken);
91         }
92
93         return new ArrayList<>();
94     }
95
96     private String authenticate(String username, String password) {
97         Gson gson = new Gson();
98
99         AuthRequest req = new AuthRequest(username, password, "ios",
100                 new BigInteger(130, new SecureRandom()).toString(64));
101
102         String authenticationResponse = "";
103         try {
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.");
109         }
110
111         BeehiveAuthentication authenticationObject = gson.fromJson(authenticationResponse, BeehiveAuthentication.class);
112         return authenticationObject.getAccessToken();
113     }
114
115     private String sendAuthRequestToNeato(String data) throws IOException {
116         Properties headers = new Properties();
117         headers.setProperty("Accept", "application/vnd.neato.nucleo.v1");
118
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);
122
123         logger.debug("Authentication Response: {}", resultString);
124
125         return resultString;
126     }
127
128     private static class AuthRequest {
129         private String email;
130         private String password;
131         private String os;
132         private String token;
133
134         public AuthRequest(String email, String password, String os, String token) {
135             this.email = email;
136             this.password = password;
137             this.os = os;
138             this.token = token;
139         }
140
141         public String getEmail() {
142             return email;
143         }
144
145         public String getPassword() {
146             return password;
147         }
148
149         public String getOs() {
150             return os;
151         }
152
153         public String getToken() {
154             return token;
155         }
156     }
157 }