2 * Copyright (c) 2010-2024 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.neohub.internal;
15 import static java.nio.charset.StandardCharsets.US_ASCII;
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;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
27 import com.google.gson.JsonParser;
30 * Handles the text based communication via TCP socket between openHAB and NeoHub
32 * @author Sebastian Prehn - Initial contribution
33 * @author Andrew Fiddian-Green - Refactoring for openHAB v2.x
37 public class NeoHubSocket extends NeoHubSocketBase {
39 private final Logger logger = LoggerFactory.getLogger(NeoHubSocket.class);
41 public NeoHubSocket(NeoHubConfiguration config, String hubId) {
46 public synchronized String sendMessage(final String requestJson) throws IOException, NeoHubException {
47 IOException caughtException = null;
48 StringBuilder builder = new StringBuilder();
51 try (Socket socket = new Socket()) {
52 int port = config.portNumber > 0 ? config.portNumber : NeoHubBindingConstants.PORT_TCP;
53 socket.connect(new InetSocketAddress(config.hostName, port), config.socketTimeout * 1000);
54 socket.setSoTimeout(config.socketTimeout * 1000);
56 try (InputStreamReader reader = new InputStreamReader(socket.getInputStream(), US_ASCII);
57 OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream(), US_ASCII)) {
59 logger.debug("hub '{}' sending characters:{}", hubId, requestJson.length());
60 writer.write(requestJson);
61 writer.write(0); // NULL terminate the command string
63 socket.shutdownOutput();
64 logger.trace("hub '{}' sent:{}", hubId, requestJson);
68 // read until end of stream
69 while ((inChar = reader.read()) != -1) {
70 // a JSON block is terminated by a newline or NULL
71 if (!(done |= (inChar == '\n') || (inChar == 0))) {
72 builder.append((char) inChar);
76 } catch (IOException e) {
77 // catch IOExceptions here, and save them to be re-thrown later
81 String responseJson = builder.toString().strip();
83 logger.debug("hub '{}' received characters:{}", hubId, responseJson.length());
84 logger.trace("hub '{}' received:{}", hubId, responseJson);
86 // if an IOException was caught above, re-throw it again
87 if (caughtException != null) {
88 throw caughtException;
91 if (JsonParser.parseString(responseJson).isJsonObject()) {
94 logger.debug("hub '{}' Response is not a JSON object; response:{}", hubId, responseJson);
95 throw new NeoHubException("Invalid response");