diff --git a/bundles/org.openhab.binding.urtsi/pom.xml b/bundles/org.openhab.binding.urtsi/pom.xml
index 2343bcd5f1816..fef64c0153387 100644
--- a/bundles/org.openhab.binding.urtsi/pom.xml
+++ b/bundles/org.openhab.binding.urtsi/pom.xml
@@ -14,8 +14,4 @@
openHAB Add-ons :: Bundles :: Somfy URTSI II binding
-
- gnu.io;version="[3.12,6)"
-
-
diff --git a/bundles/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/UrtsiHandlerFactory.java b/bundles/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/UrtsiHandlerFactory.java
index a95399a2c087c..81148ce3dbb26 100644
--- a/bundles/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/UrtsiHandlerFactory.java
+++ b/bundles/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/UrtsiHandlerFactory.java
@@ -17,15 +17,20 @@
import java.util.Arrays;
import java.util.List;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.core.thing.Bridge;
import org.eclipse.smarthome.core.thing.Thing;
import org.eclipse.smarthome.core.thing.ThingTypeUID;
import org.eclipse.smarthome.core.thing.binding.BaseThingHandlerFactory;
import org.eclipse.smarthome.core.thing.binding.ThingHandler;
import org.eclipse.smarthome.core.thing.binding.ThingHandlerFactory;
+import org.eclipse.smarthome.io.transport.serial.SerialPortManager;
import org.openhab.binding.urtsi.internal.handler.RtsDeviceHandler;
import org.openhab.binding.urtsi.internal.handler.UrtsiDeviceHandler;
+import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
/**
* The {@link UrtsiHandlerFactory} is responsible for creating things and thing
@@ -33,23 +38,31 @@
*
* @author Oliver Libutzki - Initial contribution
*/
+@NonNullByDefault
@Component(service = ThingHandlerFactory.class, configurationPid = "binding.urtsi")
public class UrtsiHandlerFactory extends BaseThingHandlerFactory {
private static final List SUPPORTED_THING_TYPES_UIDS = Arrays.asList(URTSI_DEVICE_THING_TYPE,
RTS_DEVICE_THING_TYPE);
+ private final SerialPortManager serialPortManager;
+
+ @Activate
+ public UrtsiHandlerFactory(final @Reference SerialPortManager serialPortManager) {
+ this.serialPortManager = serialPortManager;
+ }
+
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID);
}
@Override
- protected ThingHandler createHandler(Thing thing) {
+ protected @Nullable ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (thingTypeUID.equals(URTSI_DEVICE_THING_TYPE) && thing instanceof Bridge) {
- return new UrtsiDeviceHandler((Bridge) thing);
+ return new UrtsiDeviceHandler((Bridge) thing, serialPortManager);
} else if (thingTypeUID.equals(RTS_DEVICE_THING_TYPE)) {
return new RtsDeviceHandler(thing);
}
diff --git a/bundles/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/handler/UrtsiDeviceHandler.java b/bundles/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/handler/UrtsiDeviceHandler.java
index 3c2b3f339fd9e..1cecc019a4219 100644
--- a/bundles/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/handler/UrtsiDeviceHandler.java
+++ b/bundles/org.openhab.binding.urtsi/src/main/java/org/openhab/binding/urtsi/internal/handler/UrtsiDeviceHandler.java
@@ -16,12 +16,9 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
+import java.util.TooManyListenersException;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
import org.apache.commons.io.IOUtils;
import org.eclipse.smarthome.core.thing.Bridge;
@@ -31,18 +28,19 @@
import org.eclipse.smarthome.core.thing.ThingStatusDetail;
import org.eclipse.smarthome.core.thing.binding.BaseBridgeHandler;
import org.eclipse.smarthome.core.types.Command;
+import org.eclipse.smarthome.io.transport.serial.PortInUseException;
+import org.eclipse.smarthome.io.transport.serial.SerialPort;
+import org.eclipse.smarthome.io.transport.serial.SerialPortEvent;
+import org.eclipse.smarthome.io.transport.serial.SerialPortEventListener;
+import org.eclipse.smarthome.io.transport.serial.SerialPortIdentifier;
+import org.eclipse.smarthome.io.transport.serial.SerialPortManager;
+import org.eclipse.smarthome.io.transport.serial.UnsupportedCommOperationException;
import org.openhab.binding.urtsi.internal.config.RtsDeviceConfig;
import org.openhab.binding.urtsi.internal.config.UrtsiDeviceConfig;
import org.openhab.binding.urtsi.internal.mapping.UrtsiChannelMapping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import gnu.io.CommPortIdentifier;
-import gnu.io.NoSuchPortException;
-import gnu.io.SerialPort;
-import gnu.io.SerialPortEvent;
-import gnu.io.SerialPortEventListener;
-
/**
* The {@link UrtsiDeviceHandler} is responsible for handling commands, which are
* sent to one of the channels.
@@ -53,8 +51,6 @@ public class UrtsiDeviceHandler extends BaseBridgeHandler {
private final Logger logger = LoggerFactory.getLogger(UrtsiDeviceHandler.class);
- private static final String GNU_IO_RXTX_SERIAL_PORTS = "gnu.io.rxtx.SerialPorts";
-
private static final int BAUD = 9600;
private static final int DATABITS = SerialPort.DATABITS_8;
private static final int STOPBIT = SerialPort.STOPBITS_1;
@@ -65,13 +61,15 @@ public class UrtsiDeviceHandler extends BaseBridgeHandler {
private long lastCommandTime;
- private CommPortIdentifier portId;
+ private SerialPortIdentifier portId;
private SerialPort serialPort;
+ private final SerialPortManager serialPortManager;
private OutputStream outputStream;
private InputStream inputStream;
- public UrtsiDeviceHandler(Bridge bridge) {
+ public UrtsiDeviceHandler(Bridge bridge, SerialPortManager serialPortManager) {
super(bridge);
+ this.serialPortManager = serialPortManager;
}
@Override
@@ -162,7 +160,7 @@ public void serialEvent(SerialPortEvent event) {
Thread.sleep(100);
}
return !listenerResult.isEmpty();
- } catch (Exception e) {
+ } catch (IOException | TooManyListenersException | InterruptedException e) {
logger.error("Error writing '{}' to serial port {}: {}", msg, portId.getName(), e.getMessage());
} finally {
serialPort.removeEventListener();
@@ -170,62 +168,37 @@ public void serialEvent(SerialPortEvent event) {
return false;
}
- /**
- * Registers the given port as system property {@value #GNU_IO_RXTX_SERIAL_PORTS}. The method is capable of
- * extending the system property, if any other ports are already registered.
- *
- * @param port the port to be registered
- */
- private void initSerialPort(String port) {
- String serialPortsProperty = System.getProperty(GNU_IO_RXTX_SERIAL_PORTS);
- Set serialPorts = null;
-
- if (serialPortsProperty != null) {
- serialPorts = Stream.of(serialPortsProperty.split(":")).collect(Collectors.toSet());
- } else {
- serialPorts = new HashSet<>();
- }
- if (serialPorts.add(port)) {
- logger.debug("Added {} to the {} system property.", port, GNU_IO_RXTX_SERIAL_PORTS);
- System.setProperty(GNU_IO_RXTX_SERIAL_PORTS, serialPorts.stream().collect(Collectors.joining(":")));
- }
- }
-
@Override
public void initialize() {
address = getThing().getProperties().get("address");
UrtsiDeviceConfig urtsiDeviceConfig = getConfigAs(UrtsiDeviceConfig.class);
commandInterval = urtsiDeviceConfig.commandInterval;
String port = urtsiDeviceConfig.port;
- initSerialPort(port);
+
+ portId = serialPortManager.getIdentifier(port);
+
+ if (portId == null) {
+ String availablePorts = serialPortManager.getIdentifiers().map(id -> id.getName())
+ .collect(Collectors.joining(System.lineSeparator()));
+ String description = String.format("Serial port '%s' could not be found. Available ports are:%n%s", port,
+ availablePorts);
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, description);
+ return;
+ }
+
try {
- portId = CommPortIdentifier.getPortIdentifier(port);
- // initialize serial port
serialPort = portId.open("openHAB", 2000);
- // set port parameters
serialPort.setSerialPortParams(BAUD, DATABITS, STOPBIT, PARITY);
inputStream = serialPort.getInputStream();
outputStream = serialPort.getOutputStream();
updateStatus(ThingStatus.ONLINE);
- } catch (NoSuchPortException e) {
- // enumerate the port identifiers in the exception to be helpful
- final StringBuilder sb = new StringBuilder();
- @SuppressWarnings("unchecked")
- Enumeration portList = CommPortIdentifier.getPortIdentifiers();
- while (portList.hasMoreElements()) {
- final CommPortIdentifier id = portList.nextElement();
- if (id.getPortType() == CommPortIdentifier.PORT_SERIAL) {
- sb.append(id.getName() + "\n");
- }
- }
- updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
- "Serial port '" + port + "' could not be found. Available ports are:\n" + sb.toString());
- } catch (Exception e) {
- if (logger.isErrorEnabled()) {
- logger.error("An error occurred while initializing the Urtsi II connection.", e);
- }
+ } catch (IOException e) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Error: " + e.getMessage());
+ } catch (PortInUseException e) {
+ updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "Port already used: " + port);
+ } catch (UnsupportedCommOperationException e) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
- "An error occurred while initializing the Urtsi II connection: " + e.getMessage());
+ "Unsupported operation on port '" + port + "': " + e.getMessage());
}
}