diff --git a/bundles/org.openhab.binding.pioneeravr/src/main/java/org/openhab/binding/pioneeravr/internal/handler/AvrHandlerFactory.java b/bundles/org.openhab.binding.pioneeravr/src/main/java/org/openhab/binding/pioneeravr/internal/handler/AvrHandlerFactory.java index 463f95acfd088..634ae78e64589 100644 --- a/bundles/org.openhab.binding.pioneeravr/src/main/java/org/openhab/binding/pioneeravr/internal/handler/AvrHandlerFactory.java +++ b/bundles/org.openhab.binding.pioneeravr/src/main/java/org/openhab/binding/pioneeravr/internal/handler/AvrHandlerFactory.java @@ -13,25 +13,30 @@ package org.openhab.binding.pioneeravr.internal.handler; import java.util.Collections; -import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; 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.pioneeravr.internal.PioneerAvrBindingConstants; import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; /** * The {@link AvrHandlerFactory} is responsible for creating things and thing handlers. * * @author Antoine Besnard - Initial contribution */ +@NonNullByDefault @Component(service = ThingHandlerFactory.class, configurationPid = "binding.pioneeravr") public class AvrHandlerFactory extends BaseThingHandlerFactory { @@ -43,8 +48,12 @@ public class AvrHandlerFactory extends BaseThingHandlerFactory { PioneerAvrBindingConstants.IP_AVR_UNSUPPORTED_THING_TYPE, PioneerAvrBindingConstants.SERIAL_AVR_THING_TYPE).collect(Collectors.toSet())); - protected void activate(ComponentContext componentContext, Map configProps) { + private SerialPortManager serialPortManager; + + @Activate + public AvrHandlerFactory(ComponentContext componentContext, final @Reference SerialPortManager serialPortManager) { super.activate(componentContext); + this.serialPortManager = serialPortManager; } @Override @@ -53,7 +62,7 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) { } @Override - protected ThingHandler createHandler(Thing thing) { + protected @Nullable ThingHandler createHandler(Thing thing) { ThingTypeUID thingTypeUID = thing.getThingTypeUID(); if (thingTypeUID.equals(PioneerAvrBindingConstants.IP_AVR_THING_TYPE) @@ -67,7 +76,7 @@ protected ThingHandler createHandler(Thing thing) { || thingTypeUID.equals(PioneerAvrBindingConstants.IP_AVR_UNSUPPORTED_THING_TYPE)) { return new IpAvrHandler(thing); } else if (thingTypeUID.equals(PioneerAvrBindingConstants.SERIAL_AVR_THING_TYPE)) { - return new SerialAvrHandler(thing); + return new SerialAvrHandler(thing, serialPortManager); } return null; diff --git a/bundles/org.openhab.binding.pioneeravr/src/main/java/org/openhab/binding/pioneeravr/internal/handler/SerialAvrHandler.java b/bundles/org.openhab.binding.pioneeravr/src/main/java/org/openhab/binding/pioneeravr/internal/handler/SerialAvrHandler.java index 4f2437f3f86dd..173b98b99ac34 100644 --- a/bundles/org.openhab.binding.pioneeravr/src/main/java/org/openhab/binding/pioneeravr/internal/handler/SerialAvrHandler.java +++ b/bundles/org.openhab.binding.pioneeravr/src/main/java/org/openhab/binding/pioneeravr/internal/handler/SerialAvrHandler.java @@ -13,6 +13,7 @@ package org.openhab.binding.pioneeravr.internal.handler; import org.eclipse.smarthome.core.thing.Thing; +import org.eclipse.smarthome.io.transport.serial.SerialPortManager; import org.openhab.binding.pioneeravr.internal.PioneerAvrBindingConstants; import org.openhab.binding.pioneeravr.internal.protocol.avr.AvrConnection; import org.openhab.binding.pioneeravr.internal.protocol.serial.SerialAvrConnection; @@ -24,14 +25,17 @@ */ public class SerialAvrHandler extends AbstractAvrHandler { - public SerialAvrHandler(Thing thing) { + private SerialPortManager serialPortManager; + + public SerialAvrHandler(Thing thing, SerialPortManager serialPortManager) { super(thing); + this.serialPortManager = serialPortManager; } @Override protected AvrConnection createConnection() { String serialPort = (String) this.getConfig().get(PioneerAvrBindingConstants.SERIAL_PORT_PARAMETER); - return new SerialAvrConnection(serialPort); + return new SerialAvrConnection(serialPort, serialPortManager); } } diff --git a/bundles/org.openhab.binding.pioneeravr/src/main/java/org/openhab/binding/pioneeravr/internal/protocol/serial/SerialAvrConnection.java b/bundles/org.openhab.binding.pioneeravr/src/main/java/org/openhab/binding/pioneeravr/internal/protocol/serial/SerialAvrConnection.java index 779af0bf8d266..439d3f25c8f25 100644 --- a/bundles/org.openhab.binding.pioneeravr/src/main/java/org/openhab/binding/pioneeravr/internal/protocol/serial/SerialAvrConnection.java +++ b/bundles/org.openhab.binding.pioneeravr/src/main/java/org/openhab/binding/pioneeravr/internal/protocol/serial/SerialAvrConnection.java @@ -15,70 +15,76 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; - +import java.util.stream.Collectors; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.smarthome.io.transport.serial.PortInUseException; +import org.eclipse.smarthome.io.transport.serial.SerialPort; +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.pioneeravr.internal.protocol.StreamAvrConnection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import gnu.io.NRSerialPort; - /** * A class that wraps the communication to a Pioneer AVR devices through a serial port * * @author Antoine Besnard - Initial contribution */ +@NonNullByDefault public class SerialAvrConnection extends StreamAvrConnection { private final Logger logger = LoggerFactory.getLogger(SerialAvrConnection.class); private static final Integer LINK_SPEED = 9600; - private String portName; + private final String portName; + + private @Nullable SerialPort serialPort; - private NRSerialPort serialPort; + private final SerialPortManager serialPortManager; - public SerialAvrConnection(String portName) { + public SerialAvrConnection(String portName, SerialPortManager serialPortManager) { this.portName = portName; + this.serialPortManager = serialPortManager; } @Override protected void openConnection() throws IOException { - if (isPortNameExist(portName)) { - serialPort = new NRSerialPort(portName, LINK_SPEED); + SerialPortIdentifier serialPortIdentifier = serialPortManager.getIdentifier(portName); + if (serialPortIdentifier == null) { + String availablePorts = serialPortManager.getIdentifiers().map(id -> id.getName()) + .collect(Collectors.joining(", ")); + throw new IOException( + "Serial port with name " + portName + " does not exist. Available port names: " + availablePorts); - boolean isConnected = serialPort.connect(); - - if (!isConnected) { - throw new IOException("Failed to connect on port " + portName); - } + } - logger.debug("Connected to {}", getConnectionName()); - } else { - throw new IOException("Serial port with name " + portName + " does not exist. Available port names: " - + NRSerialPort.getAvailableSerialPorts()); + try { + SerialPort localSerialPort = serialPortIdentifier.open(SerialAvrConnection.class.getSimpleName(), 2000); + localSerialPort.setSerialPortParams(LINK_SPEED, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, + SerialPort.PARITY_NONE); + serialPort = localSerialPort; + } catch (PortInUseException | UnsupportedCommOperationException e) { + throw new IOException("Failed to connect on port " + portName); } - } - /** - * Check if the Serial with the given name exist. - * - * @param portName - * @return - */ - private boolean isPortNameExist(String portName) { - return NRSerialPort.getAvailableSerialPorts().contains(portName); + logger.debug("Connected to {}", getConnectionName()); } @Override public boolean isConnected() { - return serialPort != null && serialPort.isConnected(); + return serialPort != null; } @Override public void close() { super.close(); - if (serialPort != null) { - serialPort.disconnect(); + SerialPort localSerialPort = serialPort; + if (localSerialPort != null) { + localSerialPort.close(); serialPort = null; logger.debug("Closed port {}", portName); } @@ -90,12 +96,14 @@ public String getConnectionName() { } @Override - protected InputStream getInputStream() throws IOException { - return serialPort.getInputStream(); + protected @Nullable InputStream getInputStream() throws IOException { + SerialPort localSerialPort = serialPort; + return localSerialPort != null ? localSerialPort.getInputStream() : null; } @Override - protected OutputStream getOutputStream() throws IOException { - return serialPort.getOutputStream(); + protected @Nullable OutputStream getOutputStream() throws IOException { + SerialPort localSerialPort = serialPort; + return localSerialPort != null ? localSerialPort.getOutputStream() : null; } }