]> git.basschouten.com Git - openhab-addons.git/blob
cf128dfa394301b2f71a3ed819c74eea6bd6b06d
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.intesis.internal.api;
14
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;
24
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;
31
32 /**
33  * Class handling the Socket connections.
34  *
35  * @author Cody Cutrer - Initial contribution
36  * @author Hans-Jörg Merk - Moved Socket to it's own class
37  */
38 @NonNullByDefault
39 public class IntesisBoxSocketApi {
40
41     private final Logger logger = LoggerFactory.getLogger(IntesisBoxSocketApi.class);
42
43     private final String ipAddress;
44     private final int port;
45     private final String readerThreadName;
46
47     private @Nullable IntesisSocket tcpSocket = null;
48     private @Nullable OutputStreamWriter tcpOutput = null;
49     private @Nullable BufferedReader tcpInput = null;
50
51     private @Nullable IntesisBoxChangeListener changeListener;
52
53     private boolean connected = false;
54
55     public IntesisBoxSocketApi(final String ipAddress, final int port, final String readerThreadName) {
56         this.ipAddress = ipAddress;
57         this.port = port;
58         this.readerThreadName = readerThreadName;
59     }
60
61     private class IntesisSocket {
62         final Socket socket;
63
64         public IntesisSocket() throws UnknownHostException, IOException {
65             socket = new Socket();
66             SocketAddress tcpSocketAddress = new InetSocketAddress(ipAddress, port);
67             socket.connect(tcpSocketAddress);
68         }
69
70         public void close() throws IOException {
71             socket.close();
72         }
73     }
74
75     public void openConnection() throws IOException {
76         closeConnection();
77
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));
83
84         Thread tcpListener = new Thread(new TCPListener());
85         tcpListener.setName(readerThreadName);
86         tcpListener.setDaemon(true);
87         tcpListener.start();
88
89         setConnected(true);
90         if (listener != null) {
91             listener.connectionStatusChanged(ThingStatus.ONLINE, null);
92         }
93     }
94
95     public void closeConnection() {
96         try {
97             IntesisSocket localSocket = tcpSocket;
98             OutputStreamWriter localOutput = tcpOutput;
99             BufferedReader localInput = tcpInput;
100
101             if (localSocket != null) {
102                 localSocket.close();
103                 localSocket = null;
104             }
105             if (localInput != null) {
106                 localInput.close();
107                 localInput = null;
108             }
109             if (localOutput != null) {
110                 localOutput.close();
111                 localOutput = null;
112             }
113             setConnected(false);
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());
118         }
119     }
120
121     private class TCPListener implements Runnable {
122
123         /**
124          * Run method. Runs the MessageListener thread
125          */
126         @Override
127         public void run() {
128             while (isConnected()) {
129                 String message = read();
130                 readMessage(message);
131             }
132         }
133     }
134
135     public void addIntesisBoxChangeListener(IntesisBoxChangeListener listener) {
136         if (this.changeListener == null) {
137             this.changeListener = listener;
138         }
139     }
140
141     private void write(String data) {
142         IntesisBoxChangeListener listener = this.changeListener;
143         try {
144             OutputStreamWriter localOutput = tcpOutput;
145
146             if (localOutput != null) {
147                 localOutput.write(data);
148                 localOutput.flush();
149             }
150         } catch (IOException ioException) {
151             setConnected(false);
152             if (listener != null) {
153                 listener.connectionStatusChanged(ThingStatus.OFFLINE, ioException.getMessage());
154             }
155         }
156     }
157
158     public String read() {
159         String message = "";
160         try {
161             BufferedReader localInput = tcpInput;
162             if (localInput != null) {
163                 message = localInput.readLine();
164             }
165         } catch (IOException ioException) {
166             setConnected(false);
167         }
168         return message;
169     }
170
171     public void readMessage(String message) {
172         IntesisBoxChangeListener listener = this.changeListener;
173
174         if (listener != null && !message.isEmpty()) {
175             listener.messageReceived(message);
176         }
177     }
178
179     public void sendAlive() {
180         write("GET,1:*\r\n");
181     }
182
183     public void sendId() {
184         write("ID\r\n");
185     }
186
187     public void sendLimitsQuery() {
188         write("LIMITS:*\r\n");
189     }
190
191     public void sendCommand(String function, String value) {
192         String data = String.format("SET,1:%s,%s\r\n", function, value);
193         write(data);
194     }
195
196     public void sendQuery(String function) {
197         String data = String.format("GET,1:%s\r\n", function);
198         write(data);
199     }
200
201     public boolean isConnected() {
202         return this.connected;
203     }
204
205     public void setConnected(boolean connected) {
206         this.connected = connected;
207     }
208
209     public void removeIntesisBoxChangeListener(IntesisBoxHandler intesisBoxHandler) {
210         if (this.changeListener != null) {
211             this.changeListener = null;
212         }
213     }
214 }