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.intesis.internal.api;
15 import java.io.BufferedReader;
16 import java.io.IOException;
17 import java.io.InputStreamReader;
18 import java.io.OutputStreamWriter;
19 import java.net.InetSocketAddress;
20 import java.net.Socket;
21 import java.net.SocketAddress;
22 import java.net.UnknownHostException;
23 import java.nio.charset.StandardCharsets;
25 import org.eclipse.jdt.annotation.NonNullByDefault;
26 import org.eclipse.jdt.annotation.Nullable;
27 import org.openhab.binding.intesis.internal.handler.IntesisBoxHandler;
28 import org.openhab.core.thing.ThingStatus;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
33 * Class handling the Socket connections.
35 * @author Cody Cutrer - Initial contribution
36 * @author Hans-Jörg Merk - Moved Socket to it's own class
39 public class IntesisBoxSocketApi {
41 private final Logger logger = LoggerFactory.getLogger(IntesisBoxSocketApi.class);
43 private final String ipAddress;
44 private final int port;
45 private final String readerThreadName;
47 private @Nullable IntesisSocket tcpSocket = null;
48 private @Nullable OutputStreamWriter tcpOutput = null;
49 private @Nullable BufferedReader tcpInput = null;
51 private @Nullable IntesisBoxChangeListener changeListener;
53 private boolean connected = false;
55 public IntesisBoxSocketApi(final String ipAddress, final int port, final String readerThreadName) {
56 this.ipAddress = ipAddress;
58 this.readerThreadName = readerThreadName;
61 private class IntesisSocket {
64 public IntesisSocket() throws UnknownHostException, IOException {
65 socket = new Socket();
66 SocketAddress tcpSocketAddress = new InetSocketAddress(ipAddress, port);
67 socket.connect(tcpSocketAddress);
70 public void close() throws IOException {
75 public void openConnection() throws IOException {
78 IntesisBoxChangeListener listener = this.changeListener;
79 IntesisSocket localSocket = tcpSocket = new IntesisSocket();
80 tcpOutput = new OutputStreamWriter(localSocket.socket.getOutputStream(), StandardCharsets.US_ASCII);
81 tcpInput = new BufferedReader(
82 new InputStreamReader(localSocket.socket.getInputStream(), StandardCharsets.US_ASCII));
84 Thread tcpListener = new Thread(new TCPListener());
85 tcpListener.setName(readerThreadName);
86 tcpListener.setDaemon(true);
90 if (listener != null) {
91 listener.connectionStatusChanged(ThingStatus.ONLINE, null);
95 public void closeConnection() {
97 IntesisSocket localSocket = tcpSocket;
98 OutputStreamWriter localOutput = tcpOutput;
99 BufferedReader localInput = tcpInput;
101 if (localSocket != null) {
105 if (localInput != null) {
109 if (localOutput != null) {
114 } catch (IOException ioException) {
115 logger.debug("closeConnection(): Unable to close connection - {}", ioException.getMessage());
116 } catch (Exception exception) {
117 logger.debug("closeConnection(): Error closing connection - {}", exception.getMessage());
121 private class TCPListener implements Runnable {
124 * Run method. Runs the MessageListener thread
128 while (isConnected()) {
129 String message = read();
130 readMessage(message);
135 public void addIntesisBoxChangeListener(IntesisBoxChangeListener listener) {
136 if (this.changeListener == null) {
137 this.changeListener = listener;
141 private void write(String data) {
142 IntesisBoxChangeListener listener = this.changeListener;
144 OutputStreamWriter localOutput = tcpOutput;
146 if (localOutput != null) {
147 localOutput.write(data);
150 } catch (IOException ioException) {
152 if (listener != null) {
153 listener.connectionStatusChanged(ThingStatus.OFFLINE, ioException.getMessage());
158 public String read() {
161 BufferedReader localInput = tcpInput;
162 if (localInput != null) {
163 message = localInput.readLine();
165 } catch (IOException ioException) {
171 public void readMessage(String message) {
172 IntesisBoxChangeListener listener = this.changeListener;
174 if (listener != null && !message.isEmpty()) {
175 listener.messageReceived(message);
179 public void sendAlive() {
180 write("GET,1:*\r\n");
183 public void sendId() {
187 public void sendLimitsQuery() {
188 write("LIMITS:*\r\n");
191 public void sendCommand(String function, String value) {
192 String data = String.format("SET,1:%s,%s\r\n", function, value);
196 public void sendQuery(String function) {
197 String data = String.format("GET,1:%s\r\n", function);
201 public boolean isConnected() {
202 return this.connected;
205 public void setConnected(boolean connected) {
206 this.connected = connected;
209 public void removeIntesisBoxChangeListener(IntesisBoxHandler intesisBoxHandler) {
210 if (this.changeListener != null) {
211 this.changeListener = null;