]> git.basschouten.com Git - openhab-addons.git/blob
55636d3f20c5b3bb2b605072ac2c606e6bc19e69
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.dscalarm.internal.handler;
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.SocketException;
23 import java.net.UnknownHostException;
24
25 import org.openhab.binding.dscalarm.internal.config.TCPServerBridgeConfiguration;
26 import org.openhab.core.thing.Bridge;
27 import org.openhab.core.thing.ThingStatus;
28 import org.openhab.core.thing.ThingStatusDetail;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 /**
33  * The bridge handler for a TCP Server to connect to a DSC IT100 RS232 Serial interface over a network.
34  *
35  * @author Russell Stephens - Initial Contribution
36  */
37
38 public class TCPServerBridgeHandler extends DSCAlarmBaseBridgeHandler {
39
40     private final Logger logger = LoggerFactory.getLogger(TCPServerBridgeHandler.class);
41
42     /**
43      * Constructor.
44      *
45      * @param bridge
46      */
47     public TCPServerBridgeHandler(Bridge bridge) {
48         super(bridge, DSCAlarmBridgeType.TCPServer, DSCAlarmProtocol.IT100_API);
49     }
50
51     // Variables for TCP connection.
52     private String ipAddress;
53     private int tcpPort;
54     private int connectionTimeout;
55     private int protocol;
56     private Socket tcpSocket = null;
57     private OutputStreamWriter tcpOutput = null;
58     private BufferedReader tcpInput = null;
59
60     @Override
61     public void initialize() {
62         logger.debug("Initializing the TCP Server Bridge handler.");
63
64         TCPServerBridgeConfiguration configuration = getConfigAs(TCPServerBridgeConfiguration.class);
65
66         if (configuration.ipAddress == null || configuration.ipAddress.trim().isEmpty()) {
67             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
68                     "Set an IP address in the thing configuration.");
69         } else if (configuration.port == null) {
70             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
71                     "Set a TCP port in the thing configuration.");
72         } else {
73             ipAddress = configuration.ipAddress.trim();
74             tcpPort = configuration.port.intValue();
75             connectionTimeout = configuration.connectionTimeout.intValue();
76             pollPeriod = configuration.pollPeriod.intValue();
77             protocol = configuration.protocol.intValue();
78
79             if (this.protocol == 2) {
80                 setProtocol(DSCAlarmProtocol.ENVISALINK_TPI);
81             } else {
82                 setProtocol(DSCAlarmProtocol.IT100_API);
83             }
84
85             super.initialize();
86
87             logger.debug("TCP Server Bridge Handler Initialized");
88             logger.debug("   IP Address:         {},", ipAddress);
89             logger.debug("   Port:               {},", tcpPort);
90             logger.debug("   PollPeriod:         {},", pollPeriod);
91             logger.debug("   Connection Timeout: {}.", connectionTimeout);
92         }
93     }
94
95     @Override
96     public void openConnection() {
97         try {
98             closeConnection();
99
100             logger.debug("openConnection(): Connecting to Envisalink ");
101
102             tcpSocket = new Socket();
103             SocketAddress tpiSocketAddress = new InetSocketAddress(ipAddress, tcpPort);
104             tcpSocket.connect(tpiSocketAddress, connectionTimeout);
105             tcpOutput = new OutputStreamWriter(tcpSocket.getOutputStream(), "US-ASCII");
106             tcpInput = new BufferedReader(new InputStreamReader(tcpSocket.getInputStream()));
107
108             Thread tcpListener = new Thread(new TCPListener(), "OH-binding-" + getThing().getUID() + "-tcplistener");
109             tcpListener.setDaemon(true);
110             tcpListener.start();
111
112             setConnected(true);
113         } catch (UnknownHostException unknownHostException) {
114             logger.error("openConnection(): Unknown Host Exception: {}", unknownHostException.getMessage());
115             setConnected(false);
116         } catch (SocketException socketException) {
117             logger.error("openConnection(): Socket Exception: {}", socketException.getMessage());
118             setConnected(false);
119         } catch (IOException ioException) {
120             logger.error("openConnection(): IO Exception: {}", ioException.getMessage());
121             setConnected(false);
122         } catch (Exception exception) {
123             logger.error("openConnection(): Unable to open a connection: {} ", exception.getMessage(), exception);
124             setConnected(false);
125         }
126     }
127
128     @Override
129     public void write(String writeString, boolean doNotLog) {
130         try {
131             tcpOutput.write(writeString);
132             tcpOutput.flush();
133             logger.debug("write(): Message Sent: {}", doNotLog ? "***" : writeString);
134         } catch (IOException ioException) {
135             logger.error("write(): {}", ioException.getMessage());
136             setConnected(false);
137         } catch (Exception exception) {
138             logger.error("write(): Unable to write to socket: {} ", exception.getMessage(), exception);
139             setConnected(false);
140         }
141     }
142
143     @Override
144     public String read() {
145         String message = "";
146
147         try {
148             message = tcpInput.readLine();
149             logger.debug("read(): Message Received: {}", message);
150         } catch (IOException ioException) {
151             logger.error("read(): IO Exception: {}", ioException.getMessage());
152             setConnected(false);
153         } catch (Exception exception) {
154             logger.error("read(): Exception: {} ", exception.getMessage(), exception);
155             setConnected(false);
156         }
157
158         return message;
159     }
160
161     @Override
162     public void closeConnection() {
163         try {
164             if (tcpSocket != null) {
165                 tcpSocket.close();
166                 tcpSocket = null;
167                 tcpInput = null;
168                 tcpOutput = null;
169             }
170             setConnected(false);
171             logger.debug("closeConnection(): Closed TCP Connection!");
172         } catch (IOException ioException) {
173             logger.error("closeConnection(): Unable to close connection - {}", ioException.getMessage());
174         } catch (Exception exception) {
175             logger.error("closeConnection(): Error closing connection - {}", exception.getMessage());
176         }
177     }
178
179     /**
180      * TCPMessageListener: Receives messages from the DSC Alarm Panel API.
181      */
182     private class TCPListener implements Runnable {
183         private final Logger logger = LoggerFactory.getLogger(TCPListener.class);
184
185         /**
186          * Run method. Runs the MessageListener thread
187          */
188         @Override
189         public void run() {
190             String messageLine;
191
192             try {
193                 while (isConnected()) {
194                     if ((messageLine = read()) != null) {
195                         try {
196                             handleIncomingMessage(messageLine);
197                         } catch (Exception e) {
198                             logger.error("TCPListener(): Message not handled by bridge: {}", e.getMessage());
199                         }
200                     } else {
201                         setConnected(false);
202                     }
203                 }
204             } catch (Exception e) {
205                 logger.error("TCPListener(): Unable to read message: {} ", e.getMessage(), e);
206                 closeConnection();
207             }
208         }
209     }
210 }