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.dscalarm.internal.handler;
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;
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;
33 * The bridge handler for a TCP Server to connect to a DSC IT100 RS232 Serial interface over a network.
35 * @author Russell Stephens - Initial Contribution
38 public class TCPServerBridgeHandler extends DSCAlarmBaseBridgeHandler {
40 private final Logger logger = LoggerFactory.getLogger(TCPServerBridgeHandler.class);
47 public TCPServerBridgeHandler(Bridge bridge) {
48 super(bridge, DSCAlarmBridgeType.TCPServer, DSCAlarmProtocol.IT100_API);
51 // Variables for TCP connection.
52 private String ipAddress;
54 private int connectionTimeout;
56 private Socket tcpSocket = null;
57 private OutputStreamWriter tcpOutput = null;
58 private BufferedReader tcpInput = null;
61 public void initialize() {
62 logger.debug("Initializing the TCP Server Bridge handler.");
64 TCPServerBridgeConfiguration configuration = getConfigAs(TCPServerBridgeConfiguration.class);
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.");
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();
79 if (this.protocol == 2) {
80 setProtocol(DSCAlarmProtocol.ENVISALINK_TPI);
82 setProtocol(DSCAlarmProtocol.IT100_API);
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);
96 public void openConnection() {
100 logger.debug("openConnection(): Connecting to Envisalink ");
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()));
108 Thread tcpListener = new Thread(new TCPListener(), "OH-binding-" + getThing().getUID() + "-tcplistener");
109 tcpListener.setDaemon(true);
113 } catch (UnknownHostException unknownHostException) {
114 logger.error("openConnection(): Unknown Host Exception: {}", unknownHostException.getMessage());
116 } catch (SocketException socketException) {
117 logger.error("openConnection(): Socket Exception: {}", socketException.getMessage());
119 } catch (IOException ioException) {
120 logger.error("openConnection(): IO Exception: {}", ioException.getMessage());
122 } catch (Exception exception) {
123 logger.error("openConnection(): Unable to open a connection: {} ", exception.getMessage(), exception);
129 public void write(String writeString, boolean doNotLog) {
131 tcpOutput.write(writeString);
133 logger.debug("write(): Message Sent: {}", doNotLog ? "***" : writeString);
134 } catch (IOException ioException) {
135 logger.error("write(): {}", ioException.getMessage());
137 } catch (Exception exception) {
138 logger.error("write(): Unable to write to socket: {} ", exception.getMessage(), exception);
144 public String read() {
148 message = tcpInput.readLine();
149 logger.debug("read(): Message Received: {}", message);
150 } catch (IOException ioException) {
151 logger.error("read(): IO Exception: {}", ioException.getMessage());
153 } catch (Exception exception) {
154 logger.error("read(): Exception: {} ", exception.getMessage(), exception);
162 public void closeConnection() {
164 if (tcpSocket != null) {
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());
180 * TCPMessageListener: Receives messages from the DSC Alarm Panel API.
182 private class TCPListener implements Runnable {
183 private final Logger logger = LoggerFactory.getLogger(TCPListener.class);
186 * Run method. Runs the MessageListener thread
193 while (isConnected()) {
194 if ((messageLine = read()) != null) {
196 handleIncomingMessage(messageLine);
197 } catch (Exception e) {
198 logger.error("TCPListener(): Message not handled by bridge: {}", e.getMessage());
204 } catch (Exception e) {
205 logger.error("TCPListener(): Unable to read message: {} ", e.getMessage(), e);