]> git.basschouten.com Git - openhab-addons.git/blob
8801ba79459351b3e16f8c1f8ee14cbc6784a28e
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.neohub.internal;
14
15 import static java.nio.charset.StandardCharsets.US_ASCII;
16
17 import java.io.IOException;
18 import java.io.InputStreamReader;
19 import java.io.OutputStreamWriter;
20 import java.net.InetSocketAddress;
21 import java.net.Socket;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * NeoHubConnector handles the ASCII based communication via TCP between openHAB
29  * and NeoHub
30  *
31  * @author Sebastian Prehn - Initial contribution
32  * @author Andrew Fiddian-Green - Refactoring for openHAB v2.x
33  *
34  */
35 @NonNullByDefault
36 public class NeoHubSocket {
37
38     private final Logger logger = LoggerFactory.getLogger(NeoHubSocket.class);
39
40     /**
41      * Name of host or IP to connect to.
42      */
43     private final String hostname;
44
45     /**
46      * The port to connect to
47      */
48     private final int port;
49
50     /**
51      * The socket connect resp. read timeout value
52      */
53     private final int timeout;
54
55     public NeoHubSocket(final String hostname, final int portNumber, final int timeoutSeconds) {
56         this.hostname = hostname;
57         this.port = portNumber;
58         this.timeout = timeoutSeconds * 1000;
59     }
60
61     /**
62      * sends the message over the network to the NeoHub and returns its response
63      *
64      * @param requestJson the message to be sent to the NeoHub
65      * @return responseJson received from NeoHub
66      * @throws NeoHubException, IOException
67      *
68      */
69     public String sendMessage(final String requestJson) throws IOException, NeoHubException {
70         IOException caughtException = null;
71         StringBuilder builder = new StringBuilder();
72
73         try (Socket socket = new Socket()) {
74             socket.connect(new InetSocketAddress(hostname, port), timeout);
75             socket.setSoTimeout(timeout);
76
77             try (InputStreamReader reader = new InputStreamReader(socket.getInputStream(), US_ASCII);
78                     OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream(), US_ASCII)) {
79                 if (logger.isDebugEnabled()) {
80                     logger.debug("sending {} characters..", requestJson.length());
81                     logger.debug(">> {}", requestJson);
82                 }
83
84                 writer.write(requestJson);
85                 writer.write(0); // NULL terminate the command string
86                 writer.flush();
87                 socket.shutdownOutput();
88
89                 if (logger.isTraceEnabled()) {
90                     logger.trace("sent {} characters..", requestJson.length());
91                 }
92
93                 int inChar;
94                 boolean done = false;
95                 // read until end of stream
96                 while ((inChar = reader.read()) != -1) {
97                     // a JSON block is terminated by a newline or NULL
98                     if (!(done |= (inChar == '\n') || (inChar == 0))) {
99                         builder.append((char) inChar);
100                     }
101                 }
102             }
103         } catch (IOException e) {
104             // catch IOExceptions here, and save them to be re-thrown later
105             caughtException = e;
106         }
107
108         String responseJson = builder.toString();
109
110         if (logger.isTraceEnabled()) {
111             logger.trace("received {} characters..", responseJson.length());
112             logger.trace("<< {}", responseJson);
113         } else
114
115         if (logger.isDebugEnabled()) {
116             logger.debug("received {} characters (set log level to TRACE to see full string)..", responseJson.length());
117             logger.debug("<< {} ...", responseJson.substring(0, Math.min(responseJson.length(), 30)));
118         }
119
120         // if any type of Exception was caught above, re-throw it again to the caller
121         if (caughtException != null) {
122             throw caughtException;
123         }
124
125         if (responseJson.isEmpty()) {
126             throw new NeoHubException("empty response string");
127         }
128
129         return responseJson;
130     }
131 }