2 * Copyright (c) 2010-2024 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.io.UnsupportedEncodingException;
20 import java.nio.charset.StandardCharsets;
21 import java.util.TooManyListenersException;
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;
38 * The bridge handler for the DSC IT100 RS232 Serial interface.
40 * @author Russell Stephens - Initial Contribution
43 public class IT100BridgeHandler extends DSCAlarmBaseBridgeHandler implements SerialPortEventListener {
45 private final Logger logger = LoggerFactory.getLogger(IT100BridgeHandler.class);
46 private final SerialPortManager serialPortManager;
48 private String serialPortName = "";
50 private SerialPort serialPort = null;
51 private OutputStreamWriter serialOutput = null;
52 private BufferedReader serialInput = null;
54 public IT100BridgeHandler(Bridge bridge, SerialPortManager serialPortManager) {
55 super(bridge, DSCAlarmBridgeType.IT100, DSCAlarmProtocol.IT100_API);
56 this.serialPortManager = serialPortManager;
60 public void initialize() {
61 logger.debug("Initializing the DSC IT100 Bridge handler.");
63 IT100BridgeConfiguration configuration = getConfigAs(IT100BridgeConfiguration.class);
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.");
69 serialPortName = configuration.serialPort.trim();
70 baudRate = configuration.baud.intValue();
71 pollPeriod = configuration.pollPeriod.intValue();
75 logger.debug("IT100 Bridge Handler Initialized.");
76 logger.debug(" Serial Port: {},", serialPortName);
77 logger.debug(" Baud: {},", baudRate);
78 logger.debug(" PollPeriod: {},", pollPeriod);
83 public void openConnection() {
84 logger.debug("openConnection(): Connecting to IT-100");
86 SerialPortIdentifier portIdentifier = serialPortManager.getIdentifier(serialPortName);
87 if (portIdentifier == null) {
88 logger.error("openConnection(): No Such Port: {}", serialPort);
94 SerialPort commPort = portIdentifier.open(this.getClass().getName(), 2000);
96 serialPort = commPort;
97 serialPort.setSerialPortParams(baudRate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
98 SerialPort.PARITY_NONE);
99 serialPort.enableReceiveThreshold(1);
100 serialPort.disableReceiveTimeout();
102 serialOutput = new OutputStreamWriter(serialPort.getOutputStream(), StandardCharsets.US_ASCII);
103 serialInput = new BufferedReader(new InputStreamReader(serialPort.getInputStream()));
105 setSerialEventHandler(this);
108 } catch (PortInUseException portInUseException) {
109 logger.error("openConnection(): Port in Use Exception: {}", portInUseException.getMessage());
111 } catch (UnsupportedCommOperationException unsupportedCommOperationException) {
112 logger.error("openConnection(): Unsupported Comm Operation Exception: {}",
113 unsupportedCommOperationException.getMessage());
115 } catch (UnsupportedEncodingException unsupportedEncodingException) {
116 logger.error("openConnection(): Unsupported Encoding Exception: {}",
117 unsupportedEncodingException.getMessage());
119 } catch (IOException ioException) {
120 logger.error("openConnection(): IO Exception: {}", ioException.getMessage());
126 public void write(String writeString, boolean doNotLog) {
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());
134 } catch (Exception exception) {
135 logger.error("write(): Unable to write to serial port: {} ", exception.getMessage(), exception);
141 public String read() {
145 message = readLine();
146 logger.debug("read(): Message Received: {}", message);
147 } catch (IOException ioException) {
148 logger.error("read(): IO Exception: {} ", ioException.getMessage());
150 } catch (Exception exception) {
151 logger.error("read(): Exception: {} ", exception.getMessage(), exception);
159 * Read a line from the Input Stream.
162 * @throws IOException
164 private String readLine() throws IOException {
165 return serialInput.readLine();
169 public void closeConnection() {
170 logger.debug("closeConnection(): Closing Serial Connection!");
172 if (serialPort == null) {
177 serialPort.removeEventListener();
179 if (serialInput != null) {
182 } catch (IOException e) {
183 logger.debug("Error while closing the input stream: {}", e.getMessage());
188 if (serialOutput != null) {
190 serialOutput.close();
191 } catch (IOException e) {
192 logger.debug("Error while closing the output stream: {}", e.getMessage());
201 logger.debug("close(): Serial Connection Closed!");
205 * Gets the Serial Port Name of the IT-100
207 * @return serialPortName
209 public String getSerialPortName() {
210 return serialPortName;
214 * Receives Serial Port Events and reads Serial Port Data.
216 * @param serialPortEvent
219 public synchronized void serialEvent(SerialPortEvent serialPortEvent) {
220 if (serialPortEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
222 String messageLine = serialInput.readLine();
223 handleIncomingMessage(messageLine);
224 } catch (IOException ioException) {
225 logger.error("serialEvent(): IO Exception: {}", ioException.getMessage());
231 * Set the serial event handler.
233 * @param serialPortEventListenser
235 private void setSerialEventHandler(SerialPortEventListener serialPortEventListenser) {
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());