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.knx.internal.client;
15 import java.util.Enumeration;
16 import java.util.concurrent.ScheduledExecutorService;
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.openhab.core.thing.ThingUID;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
23 import gnu.io.CommPortIdentifier;
24 import gnu.io.RXTXVersion;
25 import tuwien.auto.calimero.KNXException;
26 import tuwien.auto.calimero.link.KNXNetworkLink;
27 import tuwien.auto.calimero.link.KNXNetworkLinkFT12;
28 import tuwien.auto.calimero.link.medium.TPSettings;
31 * Serial specific {@link AbstractKNXClient} implementation.
33 * @author Simon Kaufmann - initial contribution and API.
37 public class SerialClient extends AbstractKNXClient {
39 private static final String CALIMERO_ERROR_CANNOT_OPEN_PORT = "failed to open serial port";
41 private final Logger logger = LoggerFactory.getLogger(SerialClient.class);
43 private final String serialPort;
44 private final boolean useCemi;
46 public SerialClient(int autoReconnectPeriod, ThingUID thingUID, int responseTimeout, int readingPause,
47 int readRetriesLimit, ScheduledExecutorService knxScheduler, String serialPort, boolean useCemi,
48 StatusUpdateCallback statusUpdateCallback) {
49 super(autoReconnectPeriod, thingUID, responseTimeout, readingPause, readRetriesLimit, knxScheduler,
50 statusUpdateCallback);
51 this.serialPort = serialPort;
52 this.useCemi = useCemi;
56 protected KNXNetworkLink establishConnection() throws KNXException, InterruptedException {
58 RXTXVersion.getVersion();
59 logger.debug("Establishing connection to KNX bus through FT1.2 on serial port {}{}.", serialPort,
60 (useCemi ? " using CEMI" : ""));
61 // CEMI support by Calimero library, userful for newer serial devices like KNX RF sticks, kBerry,
62 // etc.; default is still old EMI frame format
64 return KNXNetworkLinkFT12.newCemiLink(serialPort, new TPSettings());
66 return new KNXNetworkLinkFT12(serialPort, new TPSettings());
68 } catch (NoClassDefFoundError e) {
69 throw new KNXException(
70 "The serial FT1.2 KNX connection requires the RXTX libraries to be available, but they could not be found!",
72 } catch (KNXException e) {
73 final String msg = e.getMessage();
74 // TODO add a test for this string match; error message might change in later version of Calimero library
75 if ((msg != null) && (msg.startsWith(CALIMERO_ERROR_CANNOT_OPEN_PORT))) {
76 StringBuilder sb = new StringBuilder("Available ports are:\n");
77 Enumeration<?> portList = CommPortIdentifier.getPortIdentifiers();
78 while (portList.hasMoreElements()) {
79 CommPortIdentifier id = (CommPortIdentifier) portList.nextElement();
80 if ((id != null) && (id.getPortType() == CommPortIdentifier.PORT_SERIAL)) {
81 sb.append(id.getName());
85 sb.deleteCharAt(sb.length() - 1);
86 throw new KNXException("Serial port '" + serialPort + "' could not be opened. " + sb.toString());