2 * Copyright (c) 2010-2020 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.satel.internal.protocol;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.io.OutputStream;
18 import java.util.TooManyListenersException;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.openhab.core.io.transport.serial.PortInUseException;
22 import org.openhab.core.io.transport.serial.SerialPort;
23 import org.openhab.core.io.transport.serial.SerialPortEvent;
24 import org.openhab.core.io.transport.serial.SerialPortEventListener;
25 import org.openhab.core.io.transport.serial.SerialPortIdentifier;
26 import org.openhab.core.io.transport.serial.SerialPortManager;
27 import org.openhab.core.io.transport.serial.UnsupportedCommOperationException;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
32 * Represents Satel INT-RS module. Implements methods required to connect and
33 * communicate with that module over serial protocol.
35 * @author Krzysztof Goworek - Initial contribution
38 public class IntRSModule extends SatelModule {
40 private final Logger logger = LoggerFactory.getLogger(IntRSModule.class);
42 private final String port;
44 private final SerialPortManager serialPortManager;
47 * Creates new instance with port and timeout set to specified values.
49 * @param port serial port the module is connected to
50 * @param serialPortManager serial port manager object
51 * @param timeout timeout value in milliseconds for connect/read/write operations
52 * @param extPayloadSupport if <code>true</code>, the module supports extended command payload for reading
55 public IntRSModule(String port, SerialPortManager serialPortManager, int timeout, boolean extPayloadSupport) {
56 super(timeout, extPayloadSupport);
59 this.serialPortManager = serialPortManager;
63 protected CommunicationChannel connect() throws ConnectionFailureException {
64 logger.info("Connecting to INT-RS module at {}", this.port);
67 SerialPortIdentifier portIdentifier = serialPortManager.getIdentifier(this.port);
68 if (portIdentifier == null) {
69 throw new ConnectionFailureException(String.format("Port %s does not exist", this.port));
71 SerialPort serialPort = portIdentifier.open("org.openhab.binding.satel", 2000);
72 serialPort.setSerialPortParams(19200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
73 serialPort.enableReceiveTimeout(this.getTimeout());
74 // RXTX serial port library causes high CPU load
75 // Start event listener, which will just sleep and slow down event
77 serialPort.addEventListener(new SerialPortEventListener() {
79 public void serialEvent(SerialPortEvent ev) {
81 logger.trace("RXTX library CPU load workaround, sleep forever");
82 Thread.sleep(Long.MAX_VALUE);
83 } catch (InterruptedException e) {
87 serialPort.notifyOnDataAvailable(true);
89 logger.info("INT-RS module connected successfuly");
90 return new SerialCommunicationChannel(serialPort);
91 } catch (PortInUseException e) {
92 throw new ConnectionFailureException(String.format("Port %s in use", this.port), e);
93 } catch (UnsupportedCommOperationException e) {
94 throw new ConnectionFailureException(String.format("Unsupported comm operation on port %s", this.port), e);
95 } catch (TooManyListenersException e) {
96 throw new ConnectionFailureException(String.format("Too many listeners on port %s", this.port), e);
100 private class SerialCommunicationChannel implements CommunicationChannel {
102 private SerialPort serialPort;
104 public SerialCommunicationChannel(SerialPort serialPort) {
105 this.serialPort = serialPort;
109 public InputStream getInputStream() throws IOException {
110 final InputStream stream = this.serialPort.getInputStream();
111 if (stream != null) {
114 throw new IOException("Selected port doesn't support receiving data: " + this.serialPort.getName());
118 public OutputStream getOutputStream() throws IOException {
119 final OutputStream stream = this.serialPort.getOutputStream();
120 if (stream != null) {
123 throw new IOException("Selected port doesn't support sending data: " + this.serialPort.getName());
127 public void disconnect() {
128 logger.debug("Closing connection to INT-RS module");
130 this.serialPort.close();
131 logger.info("Connection to INT-RS module has been closed");
132 } catch (Exception e) {
133 logger.error("An error occurred during closing serial port", e);