]> git.basschouten.com Git - openhab-addons.git/blob
7ccd858f251d516b98fa2581298a7e29bb98e9bb
[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.io.UnsupportedEncodingException;
20 import java.nio.charset.StandardCharsets;
21 import java.util.TooManyListenersException;
22
23 import org.openhab.binding.dscalarm.internal.config.IT100BridgeConfiguration;
24 import org.openhab.core.io.transport.serial.PortInUseException;
25 import org.openhab.core.io.transport.serial.SerialPort;
26 import org.openhab.core.io.transport.serial.SerialPortEvent;
27 import org.openhab.core.io.transport.serial.SerialPortEventListener;
28 import org.openhab.core.io.transport.serial.SerialPortIdentifier;
29 import org.openhab.core.io.transport.serial.SerialPortManager;
30 import org.openhab.core.io.transport.serial.UnsupportedCommOperationException;
31 import org.openhab.core.thing.Bridge;
32 import org.openhab.core.thing.ThingStatus;
33 import org.openhab.core.thing.ThingStatusDetail;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 /**
38  * The bridge handler for the DSC IT100 RS232 Serial interface.
39  *
40  * @author Russell Stephens - Initial Contribution
41  */
42
43 public class IT100BridgeHandler extends DSCAlarmBaseBridgeHandler implements SerialPortEventListener {
44
45     private final Logger logger = LoggerFactory.getLogger(IT100BridgeHandler.class);
46     private final SerialPortManager serialPortManager;
47
48     private String serialPortName = "";
49     private int baudRate;
50     private SerialPort serialPort = null;
51     private OutputStreamWriter serialOutput = null;
52     private BufferedReader serialInput = null;
53
54     public IT100BridgeHandler(Bridge bridge, SerialPortManager serialPortManager) {
55         super(bridge, DSCAlarmBridgeType.IT100, DSCAlarmProtocol.IT100_API);
56         this.serialPortManager = serialPortManager;
57     }
58
59     @Override
60     public void initialize() {
61         logger.debug("Initializing the DSC IT100 Bridge handler.");
62
63         IT100BridgeConfiguration configuration = getConfigAs(IT100BridgeConfiguration.class);
64
65         if (configuration.serialPort == null || configuration.serialPort.trim().isEmpty()) {
66             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
67                     "Set a serial port in the thing configuration.");
68         } else {
69             serialPortName = configuration.serialPort.trim();
70             baudRate = configuration.baud.intValue();
71             pollPeriod = configuration.pollPeriod.intValue();
72
73             super.initialize();
74
75             logger.debug("IT100 Bridge Handler Initialized.");
76             logger.debug("   Serial Port: {},", serialPortName);
77             logger.debug("   Baud:        {},", baudRate);
78             logger.debug("   PollPeriod:  {},", pollPeriod);
79         }
80     }
81
82     @Override
83     public void openConnection() {
84         logger.debug("openConnection(): Connecting to IT-100");
85
86         SerialPortIdentifier portIdentifier = serialPortManager.getIdentifier(serialPortName);
87         if (portIdentifier == null) {
88             logger.error("openConnection(): No Such Port: {}", serialPort);
89             setConnected(false);
90             return;
91         }
92
93         try {
94             SerialPort commPort = portIdentifier.open(this.getClass().getName(), 2000);
95
96             serialPort = commPort;
97             serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
98                     SerialPort.PARITY_NONE);
99             serialPort.enableReceiveThreshold(1);
100             serialPort.disableReceiveTimeout();
101
102             serialOutput = new OutputStreamWriter(serialPort.getOutputStream(), StandardCharsets.US_ASCII);
103             serialInput = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
104
105             setSerialEventHandler(this);
106
107             setConnected(true);
108         } catch (PortInUseException portInUseException) {
109             logger.error("openConnection(): Port in Use Exception: {}", portInUseException.getMessage());
110             setConnected(false);
111         } catch (UnsupportedCommOperationException unsupportedCommOperationException) {
112             logger.error("openConnection(): Unsupported Comm Operation Exception: {}",
113                     unsupportedCommOperationException.getMessage());
114             setConnected(false);
115         } catch (UnsupportedEncodingException unsupportedEncodingException) {
116             logger.error("openConnection(): Unsupported Encoding Exception: {}",
117                     unsupportedEncodingException.getMessage());
118             setConnected(false);
119         } catch (IOException ioException) {
120             logger.error("openConnection(): IO Exception: {}", ioException.getMessage());
121             setConnected(false);
122         }
123     }
124
125     @Override
126     public void write(String writeString, boolean doNotLog) {
127         try {
128             serialOutput.write(writeString);
129             serialOutput.flush();
130             logger.debug("write(): Message Sent: {}", doNotLog ? "***" : writeString);
131         } catch (IOException ioException) {
132             logger.error("write(): {}", ioException.getMessage());
133             setConnected(false);
134         } catch (Exception exception) {
135             logger.error("write(): Unable to write to serial port: {} ", exception.getMessage(), exception);
136             setConnected(false);
137         }
138     }
139
140     @Override
141     public String read() {
142         String message = "";
143
144         try {
145             message = readLine();
146             logger.debug("read(): Message Received: {}", message);
147         } catch (IOException ioException) {
148             logger.error("read(): IO Exception: {} ", ioException.getMessage());
149             setConnected(false);
150         } catch (Exception exception) {
151             logger.error("read(): Exception: {} ", exception.getMessage(), exception);
152             setConnected(false);
153         }
154
155         return message;
156     }
157
158     /**
159      * Read a line from the Input Stream.
160      *
161      * @return
162      * @throws IOException
163      */
164     private String readLine() throws IOException {
165         return serialInput.readLine();
166     }
167
168     @Override
169     public void closeConnection() {
170         logger.debug("closeConnection(): Closing Serial Connection!");
171
172         if (serialPort == null) {
173             setConnected(false);
174             return;
175         }
176
177         serialPort.removeEventListener();
178
179         if (serialInput != null) {
180             try {
181                 serialInput.close();
182             } catch (IOException e) {
183                 logger.debug("Error while closing the input stream: {}", e.getMessage());
184             }
185             serialInput = null;
186         }
187
188         if (serialOutput != null) {
189             try {
190                 serialOutput.close();
191             } catch (IOException e) {
192                 logger.debug("Error while closing the output stream: {}", e.getMessage());
193             }
194             serialOutput = null;
195         }
196
197         serialPort.close();
198         serialPort = null;
199
200         setConnected(false);
201         logger.debug("close(): Serial Connection Closed!");
202     }
203
204     /**
205      * Gets the Serial Port Name of the IT-100
206      *
207      * @return serialPortName
208      */
209     public String getSerialPortName() {
210         return serialPortName;
211     }
212
213     /**
214      * Receives Serial Port Events and reads Serial Port Data.
215      *
216      * @param serialPortEvent
217      */
218     @Override
219     public synchronized void serialEvent(SerialPortEvent serialPortEvent) {
220         if (serialPortEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
221             try {
222                 String messageLine = serialInput.readLine();
223                 handleIncomingMessage(messageLine);
224             } catch (IOException ioException) {
225                 logger.error("serialEvent(): IO Exception: {}", ioException.getMessage());
226             }
227         }
228     }
229
230     /**
231      * Set the serial event handler.
232      *
233      * @param serialPortEventListenser
234      */
235     private void setSerialEventHandler(SerialPortEventListener serialPortEventListenser) {
236         try {
237             // Add the serial port event listener
238             serialPort.addEventListener(serialPortEventListenser);
239             serialPort.notifyOnDataAvailable(true);
240         } catch (TooManyListenersException tooManyListenersException) {
241             logger.error("setSerialEventHandler(): Too Many Listeners Exception: {}",
242                     tooManyListenersException.getMessage());
243         }
244     }
245 }