]> git.basschouten.com Git - openhab-addons.git/blob
903080265c02f48631d00ffa414de219e528e199
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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());
109             tcpListener.start();
110
111             setConnected(true);
112         } catch (UnknownHostException unknownHostException) {
113             logger.error("openConnection(): Unknown Host Exception: {}", unknownHostException.getMessage());
114             setConnected(false);
115         } catch (SocketException socketException) {
116             logger.error("openConnection(): Socket Exception: {}", socketException.getMessage());
117             setConnected(false);
118         } catch (IOException ioException) {
119             logger.error("openConnection(): IO Exception: {}", ioException.getMessage());
120             setConnected(false);
121         } catch (Exception exception) {
122             logger.error("openConnection(): Unable to open a connection: {} ", exception.getMessage(), exception);
123             setConnected(false);
124         }
125     }
126
127     @Override
128     public void write(String writeString, boolean doNotLog) {
129         try {
130             tcpOutput.write(writeString);
131             tcpOutput.flush();
132             logger.debug("write(): Message Sent: {}", doNotLog ? "***" : writeString);
133         } catch (IOException ioException) {
134             logger.error("write(): {}", ioException.getMessage());
135             setConnected(false);
136         } catch (Exception exception) {
137             logger.error("write(): Unable to write to socket: {} ", exception.getMessage(), exception);
138             setConnected(false);
139         }
140     }
141
142     @Override
143     public String read() {
144         String message = "";
145
146         try {
147             message = tcpInput.readLine();
148             logger.debug("read(): Message Received: {}", message);
149         } catch (IOException ioException) {
150             logger.error("read(): IO Exception: {}", ioException.getMessage());
151             setConnected(false);
152         } catch (Exception exception) {
153             logger.error("read(): Exception: {} ", exception.getMessage(), exception);
154             setConnected(false);
155         }
156
157         return message;
158     }
159
160     @Override
161     public void closeConnection() {
162         try {
163             if (tcpSocket != null) {
164                 tcpSocket.close();
165                 tcpSocket = null;
166                 tcpInput = null;
167                 tcpOutput = null;
168             }
169             setConnected(false);
170             logger.debug("closeConnection(): Closed TCP Connection!");
171         } catch (IOException ioException) {
172             logger.error("closeConnection(): Unable to close connection - {}", ioException.getMessage());
173         } catch (Exception exception) {
174             logger.error("closeConnection(): Error closing connection - {}", exception.getMessage());
175         }
176     }
177
178     /**
179      * TCPMessageListener: Receives messages from the DSC Alarm Panel API.
180      */
181     private class TCPListener implements Runnable {
182         private final Logger logger = LoggerFactory.getLogger(TCPListener.class);
183
184         /**
185          * Run method. Runs the MessageListener thread
186          */
187         @Override
188         public void run() {
189             String messageLine;
190
191             try {
192                 while (isConnected()) {
193                     if ((messageLine = read()) != null) {
194                         try {
195                             handleIncomingMessage(messageLine);
196                         } catch (Exception e) {
197                             logger.error("TCPListener(): Message not handled by bridge: {}", e.getMessage());
198                         }
199                     } else {
200                         setConnected(false);
201                     }
202                 }
203             } catch (Exception e) {
204                 logger.error("TCPListener(): Unable to read message: {} ", e.getMessage(), e);
205                 closeConnection();
206             }
207         }
208     }
209 }