2 * Copyright (c) 2010-2023 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.nikobus.internal.protocol;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.io.OutputStream;
18 import java.util.TooManyListenersException;
19 import java.util.function.Consumer;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.core.io.transport.serial.PortInUseException;
24 import org.openhab.core.io.transport.serial.SerialPort;
25 import org.openhab.core.io.transport.serial.SerialPortEvent;
26 import org.openhab.core.io.transport.serial.SerialPortEventListener;
27 import org.openhab.core.io.transport.serial.SerialPortIdentifier;
28 import org.openhab.core.io.transport.serial.SerialPortManager;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
33 * The {@link NikobusConnection } is responsible for creating connections to clients.
35 * @author Boris Krivonog - Initial contribution
38 public class NikobusConnection implements SerialPortEventListener {
39 private final Logger logger = LoggerFactory.getLogger(NikobusConnection.class);
40 private final SerialPortManager serialPortManager;
41 private final String portName;
42 private final Consumer<Byte> processData;
43 private @Nullable SerialPort serialPort;
45 public NikobusConnection(SerialPortManager serialPortManager, String portName, Consumer<Byte> processData) {
46 this.serialPortManager = serialPortManager;
47 this.portName = portName;
48 this.processData = processData;
52 * Return true if this manager is connected.
56 public boolean isConnected() {
57 return serialPort != null;
61 * Connect to the receiver.
64 public void connect() throws IOException {
69 SerialPortIdentifier portId = serialPortManager.getIdentifier(portName);
71 throw new IOException(String.format("Port '%s' is not known!", portName));
74 logger.info("Connecting to {}", portName);
77 SerialPort serialPort = portId.open("org.openhab.binding.nikobus.pc-link", 2000);
78 serialPort.addEventListener(this);
79 serialPort.notifyOnDataAvailable(true);
80 this.serialPort = serialPort;
81 logger.info("Connected to {}", portName);
82 } catch (PortInUseException e) {
83 throw new IOException(String.format("Port '%s' is in use!", portName), e);
84 } catch (TooManyListenersException e) {
85 throw new IOException(String.format("Cannot attach listener to port '%s'!", portName), e);
90 * Closes the connection.
93 SerialPort serialPort = this.serialPort;
94 this.serialPort = null;
96 if (serialPort != null) {
98 serialPort.removeEventListener();
99 OutputStream outputStream = serialPort.getOutputStream();
100 if (outputStream != null) {
101 outputStream.close();
103 InputStream inputStream = serialPort.getInputStream();
104 if (inputStream != null) {
107 } catch (IOException e) {
108 logger.debug("Error closing serial port.", e);
111 logger.debug("Closed serial port.");
117 * Returns an output stream for this connection.
119 public @Nullable OutputStream getOutputStream() throws IOException {
120 SerialPort serialPort = this.serialPort;
121 if (serialPort == null) {
124 return serialPort.getOutputStream();
128 public void serialEvent(SerialPortEvent event) {
129 if (event.getEventType() != SerialPortEvent.DATA_AVAILABLE) {
132 SerialPort serialPort = this.serialPort;
133 if (serialPort == null) {
137 InputStream inputStream = serialPort.getInputStream();
138 if (inputStream == null) {
141 byte[] readBuffer = new byte[64];
142 while (inputStream.available() > 0) {
143 int length = inputStream.read(readBuffer);
144 for (int i = 0; i < length; ++i) {
145 processData.accept(readBuffer[i]);
148 } catch (IOException e) {
149 logger.debug("Error reading from serial port: {}", e.getMessage(), e);