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