2 * Copyright (c) 2010-2022 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.alarmdecoder.internal.handler;
15 import java.io.BufferedReader;
16 import java.io.BufferedWriter;
17 import java.io.IOException;
18 import java.io.InputStreamReader;
19 import java.io.OutputStreamWriter;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.alarmdecoder.internal.config.SerialBridgeConfig;
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.SerialPortIdentifier;
27 import org.openhab.core.io.transport.serial.SerialPortManager;
28 import org.openhab.core.io.transport.serial.UnsupportedCommOperationException;
29 import org.openhab.core.thing.Bridge;
30 import org.openhab.core.thing.ThingStatus;
31 import org.openhab.core.thing.ThingStatusDetail;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
36 * Handler responsible for communicating via a serial port with the Nu Tech Alarm Decoder device.
37 * Based on code from the original OH1 alarmdecoder binding. Some OHC serial transport code taken from the Zigbee
40 * @author Bernd Pfrommer - Initial contribution (OH1 version)
41 * @author Bob Adair - Re-factored into OH2 binding and rewrote to use OHC serial transport.
44 public class SerialBridgeHandler extends ADBridgeHandler {
46 private final Logger logger = LoggerFactory.getLogger(SerialBridgeHandler.class);
48 private SerialBridgeConfig config = new SerialBridgeConfig();
49 private final SerialPortManager serialPortManager;
50 private @NonNullByDefault({}) SerialPortIdentifier portIdentifier;
51 private @Nullable SerialPort serialPort;
52 private int serialPortSpeed = 115200;
54 public SerialBridgeHandler(Bridge bridge, SerialPortManager serialPortManager) {
56 this.serialPortManager = serialPortManager;
60 public void initialize() {
61 logger.debug("Initializing serial bridge handler");
62 config = getConfigAs(SerialBridgeConfig.class);
63 discovery = config.discovery;
65 if (config.serialPort.isEmpty()) {
66 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "no serial port configured");
70 if (config.bitrate > 0) {
71 serialPortSpeed = config.bitrate;
74 portIdentifier = serialPortManager.getIdentifier(config.serialPort);
75 if (portIdentifier == null) {
76 logger.debug("Serial Error: Port {} does not exist.", config.serialPort);
77 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
78 "Configured serial port does not exist");
84 logger.trace("Finished initializing serial bridge handler");
88 protected synchronized void connect() {
89 disconnect(); // make sure we are disconnected
91 SerialPort serialPort = portIdentifier.open("org.openhab.binding.alarmdecoder", 100);
92 serialPort.setSerialPortParams(serialPortSpeed, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
93 SerialPort.PARITY_NONE);
94 serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_RTSCTS_IN | SerialPort.FLOWCONTROL_RTSCTS_OUT);
95 // Note: The V1 code called disableReceiveFraming() and disableReceiveThreshold() here
97 this.serialPort = serialPort;
98 reader = new BufferedReader(new InputStreamReader(serialPort.getInputStream(), AD_CHARSET));
99 writer = new BufferedWriter(new OutputStreamWriter(serialPort.getOutputStream(), AD_CHARSET));
101 logger.debug("connected to serial port: {}", config.serialPort);
102 panelReadyReceived = false;
104 updateStatus(ThingStatus.ONLINE);
105 } catch (PortInUseException e) {
106 logger.debug("Cannot open serial port: {}, it is already in use", config.serialPort);
107 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Serial port already in use");
108 } catch (UnsupportedCommOperationException | IOException | IllegalStateException e) {
109 logger.debug("Error connecting to serial port: {}", e.getMessage());
110 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
115 protected synchronized void disconnect() {
116 logger.trace("Disconnecting");
117 SerialPort sp = serialPort;
119 logger.trace("Closing serial port");
126 BufferedReader br = reader;
128 logger.trace("Closing reader");
131 } catch (IOException e) {
132 logger.info("IO Exception closing reader: {}", e.getMessage());
138 BufferedWriter bw = writer;
140 logger.trace("Closing writer");
143 } catch (IOException e) {
144 logger.info("IO Exception closing writer: {}", e.getMessage());