]> git.basschouten.com Git - openhab-addons.git/commitdiff
[openwebnet] Replace gnu.io dependency with serial transport (#16376)
authorM Valla <12682715+mvalla@users.noreply.github.com>
Mon, 5 Feb 2024 17:16:03 +0000 (18:16 +0100)
committerGitHub <noreply@github.com>
Mon, 5 Feb 2024 17:16:03 +0000 (18:16 +0100)
Signed-off-by: Massimo Valla <mvcode00@gmail.com>
bundles/org.openhab.binding.openwebnet/pom.xml
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/discovery/UsbGatewayDiscoveryService.java
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetBridgeHandler.java
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetLightingHandler.java
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/serial/SerialPortAdapter.java [new file with mode: 0644]
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/serial/SerialPortEventAdapter.java [new file with mode: 0644]
bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/serial/SerialPortProviderAdapter.java [new file with mode: 0644]

index 151d57dbcb4d7840eeb67d1f2091c1d30e227d95..392345816ea683ec7b01e3b0bd8d888bcc1443c1 100644 (file)
 
   <name>openHAB Add-ons :: Bundles :: OpenWebNet (BTicino/Legrand) Binding</name>
 
-  <properties>
-    <bnd.importpackage>gnu.io;version="[3.12,6)"</bnd.importpackage>
-  </properties>
-
   <dependencies>
 
     <dependency>
       <groupId>io.github.openwebnet4j</groupId>
       <artifactId>openwebnet4j</artifactId>
-      <version>0.10.1</version>
+      <version>0.12.0</version>
       <scope>compile</scope>
     </dependency>
 
index 6e6662879f4bf1c0d7dbce8fe464f49915185dac..baf841c03ac9c06d491bc53fb9e133478ab34db3 100644 (file)
@@ -18,11 +18,11 @@ import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
-import java.util.stream.Stream;
 
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants;
+import org.openhab.binding.openwebnet.internal.serial.SerialPortProviderAdapter;
 import org.openhab.core.config.discovery.AbstractDiscoveryService;
 import org.openhab.core.config.discovery.DiscoveryResult;
 import org.openhab.core.config.discovery.DiscoveryResultBuilder;
@@ -44,11 +44,14 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * The {@link UsbGatewayDiscoveryService} extends {@link AbstractDiscoveryService} to detect Zigbee USB gateways
- * connected via serial port. The service will iterate over the available serial ports and open each one to test if a
- * OpenWebNet Zigbee USB gateway is connected. On successful connection, a new DiscoveryResult is created.
+ * The {@link UsbGatewayDiscoveryService} extends
+ * {@link AbstractDiscoveryService} to detect Zigbee USB gateways connected via
+ * serial port. The service will iterate over the available serial ports and
+ * open each one to test if a OpenWebNet Zigbee USB gateway is connected. On
+ * successful connection, a new DiscoveryResult is created.
  *
- * @author Massimo Valla - Initial contribution
+ * @author Massimo Valla - Initial contribution. Inject SerialPortManager to
+ *         openwebnet4j lib.
  */
 @NonNullByDefault
 @Component(service = DiscoveryService.class, configurationPid = "discovery.openwebnet")
@@ -64,6 +67,8 @@ public class UsbGatewayDiscoveryService extends AbstractDiscoveryService impleme
     private @Nullable ScheduledFuture<?> connectTimeout;
 
     private final SerialPortManager serialPortManager;
+    private final SerialPortProviderAdapter transportAdapter;
+
     private @Nullable USBGateway zbGateway;
 
     private String currentScannedPortName = "";
@@ -74,27 +79,35 @@ public class UsbGatewayDiscoveryService extends AbstractDiscoveryService impleme
     private boolean scanning;
 
     /**
-     * Constructs a new UsbGatewayDiscoveryService with the specified Zigbee USB Bridge ThingTypeUID
+     * Constructs a new UsbGatewayDiscoveryService with the specified Zigbee USB
+     * Bridge ThingTypeUID
      */
     @Activate
     public UsbGatewayDiscoveryService(final @Reference SerialPortManager spm) {
         super(Set.of(OpenWebNetBindingConstants.THING_TYPE_ZB_GATEWAY), DISCOVERY_TIMEOUT_SECONDS, false);
-        // Obtain the serial port manager service using an OSGi reference
+        // Inject the SerialPortManager passed via @Reference into the adapter
         serialPortManager = spm;
+        SerialPortProviderAdapter.setSerialPortManager(spm);
+        this.transportAdapter = new SerialPortProviderAdapter();
+        logger.debug("**** -SPI- **** Set SerialPortManager to: {}", SerialPortProviderAdapter.serialPortManager);
     }
 
     /**
-     * Starts a new discovery scan. All available Serial Ports are scanned.
+     * Starts a new discovery scan. All available SerialPortsIdentifiers returned by
+     * SerialPortManager are scanned.
      */
     @Override
     protected void startScan() {
         logger.debug("Started OpenWebNet Zigbee USB Gateway discovery scan");
         removeOlderResults(getTimestampOfLastScan());
         scanning = true;
-        Stream<SerialPortIdentifier> portEnum = serialPortManager.getIdentifiers();
+
+        SerialPortIdentifier[] foundSerialPortIds = serialPortManager.getIdentifiers()
+                .toArray(SerialPortIdentifier[]::new);
+
         // Check each available serial port
         try {
-            for (SerialPortIdentifier portIdentifier : portEnum.toArray(SerialPortIdentifier[]::new)) {
+            for (SerialPortIdentifier portIdentifier : foundSerialPortIds) {
                 if (scanning) {
                     currentScannedPortName = portIdentifier.getName();
                     logger.debug("[{}] == checking serial port", currentScannedPortName);
@@ -104,6 +117,7 @@ public class UsbGatewayDiscoveryService extends AbstractDiscoveryService impleme
                     } else {
                         logger.debug("[{}] trying to connect to a Zigbee USB Gateway...", currentScannedPortName);
                         USBGateway gw = new USBGateway(currentScannedPortName);
+                        gw.setSerialPortProvider(transportAdapter);
                         zbGateway = gw;
                         gw.subscribe(this);
                         portCheckLatch = new CountDownLatch(1);
index 1e18259abe1c340cea43653fc8d3ad038e065366..7bf064e163bc133e2898d171ed2b5bca107ceaa9 100644 (file)
@@ -32,6 +32,7 @@ import org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants;
 import org.openhab.binding.openwebnet.internal.discovery.OpenWebNetDeviceDiscoveryService;
 import org.openhab.binding.openwebnet.internal.handler.config.OpenWebNetBusBridgeConfig;
 import org.openhab.binding.openwebnet.internal.handler.config.OpenWebNetZigBeeBridgeConfig;
+import org.openhab.binding.openwebnet.internal.serial.SerialPortProviderAdapter;
 import org.openhab.core.config.core.status.ConfigStatusMessage;
 import org.openhab.core.thing.Bridge;
 import org.openhab.core.thing.ChannelUID;
@@ -179,7 +180,11 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
                     "@text/offline.conf-error-no-serial-port");
             return null;
         } else {
-            return new USBGateway(serialPort);
+            USBGateway tmpUSBGateway = new USBGateway(serialPort);
+            tmpUSBGateway.setSerialPortProvider(new SerialPortProviderAdapter());
+            logger.debug("**** -SPI- ****  OpenWebNetBridgeHandler :: setSerialPortProvider to: {}",
+                    tmpUSBGateway.getSerialPortProvider());
+            return tmpUSBGateway;
         }
     }
 
index bb3df121fb7cac059c4b022a4a09116eca690912..97e3374e788be7350954ce86bc442de6b2e9723d 100644 (file)
@@ -385,8 +385,7 @@ public class OpenWebNetLightingHandler extends OpenWebNetThingHandler {
      *
      * @param channelId the channelId string
      **/
-    @Nullable
-    private String toWhere(String channelId) {
+    private String toWhere(String channelId) throws OWNException {
         Where w = deviceWhere;
         if (w != null) {
             OpenWebNetBridgeHandler brH = bridgeHandler;
@@ -400,6 +399,6 @@ public class OpenWebNetLightingHandler extends OpenWebNetThingHandler {
                 }
             }
         }
-        return null;
+        throw new OWNException("Cannot select channel from WHERE " + w);
     }
 }
diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/serial/SerialPortAdapter.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/serial/SerialPortAdapter.java
new file mode 100644 (file)
index 0000000..46bd490
--- /dev/null
@@ -0,0 +1,145 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.openwebnet.internal.serial;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.TooManyListenersException;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.io.transport.serial.PortInUseException;
+import org.openhab.core.io.transport.serial.SerialPort;
+import org.openhab.core.io.transport.serial.SerialPortEvent;
+import org.openhab.core.io.transport.serial.SerialPortEventListener;
+import org.openhab.core.io.transport.serial.SerialPortIdentifier;
+import org.openhab.core.io.transport.serial.UnsupportedCommOperationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * openwebnet4j SerialPort implementation based on OH serial transport
+ *
+ * @author M. Valla - Initial contribution
+ */
+
+@NonNullByDefault
+public class SerialPortAdapter implements org.openwebnet4j.communication.serial.spi.SerialPort {
+
+    private static final Logger logger = LoggerFactory.getLogger(SerialPortAdapter.class);
+
+    private static final int OPEN_TIMEOUT_MS = 200;
+
+    private final SerialPortIdentifier spid;
+
+    private @Nullable SerialPort sp = null;
+
+    public SerialPortAdapter(final SerialPortIdentifier spid) {
+        this.spid = spid;
+    }
+
+    @Override
+    public boolean setSerialPortParams(int baudrate, int dataBits, int stopBits, int parity) {
+        @Nullable
+        SerialPort lsp = sp;
+        if (lsp != null) {
+            try {
+                lsp.setSerialPortParams(baudrate, dataBits, stopBits, parity);
+                return true;
+            } catch (UnsupportedCommOperationException e) {
+                logger.error("UnsupportedCommOperationException while setting port params in setSerialPortParams: {}",
+                        e.getMessage());
+                return false;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean addEventListener(org.openwebnet4j.communication.serial.spi.SerialPortEventListener listener) {
+        @Nullable
+        SerialPort lsp = sp;
+        if (lsp != null) {
+            try {
+                lsp.addEventListener(new SerialPortEventListener() {
+
+                    @Override
+                    public void serialEvent(SerialPortEvent event) {
+                        if (event != null) {
+                            listener.serialEvent(new SerialPortEventAdapter(event));
+                        }
+                    }
+                });
+                lsp.notifyOnDataAvailable(true);
+                return true;
+            } catch (TooManyListenersException e) {
+                logger.error("TooManyListenersException while adding event listener: {}", e.getMessage());
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean open() {
+        try {
+            sp = spid.open(this.getClass().getName(), OPEN_TIMEOUT_MS);
+        } catch (PortInUseException e) {
+            logger.error("PortInUseException while opening serial port {}: {}", spid.getName(), e.getMessage());
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public @Nullable String getName() {
+        @Nullable
+        SerialPort lsp = sp;
+        if (lsp != null) {
+            return lsp.getName();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public @Nullable InputStream getInputStream() throws IOException {
+        @Nullable
+        SerialPort lsp = sp;
+        if (lsp != null) {
+            return lsp.getInputStream();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public @Nullable OutputStream getOutputStream() throws IOException {
+        @Nullable
+        SerialPort lsp = sp;
+        if (lsp != null) {
+            return lsp.getOutputStream();
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public void close() {
+        @Nullable
+        SerialPort lsp = sp;
+        if (lsp != null) {
+            lsp.close();
+        }
+    }
+}
diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/serial/SerialPortEventAdapter.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/serial/SerialPortEventAdapter.java
new file mode 100644 (file)
index 0000000..4d5646d
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+package org.openhab.binding.openwebnet.internal.serial;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.openwebnet4j.communication.serial.spi.SerialPortEvent;
+
+/**
+ * openwebnet4j SerialPortEvent implementation based on OH serial transport
+ *
+ * @author M. Valla - Initial contribution
+ */
+
+@NonNullByDefault
+public class SerialPortEventAdapter implements SerialPortEvent {
+
+    private final org.openhab.core.io.transport.serial.SerialPortEvent event;
+
+    /**
+     * Constructor.
+     *
+     * @param event the underlying event implementation
+     */
+    public SerialPortEventAdapter(org.openhab.core.io.transport.serial.SerialPortEvent event) {
+        this.event = event;
+    }
+
+    @Override
+    public int getEventType() {
+        if (event.getEventType() == org.openhab.core.io.transport.serial.SerialPortEvent.PORT_DISCONNECTED) {
+            return SerialPortEvent.EVENT_PORT_DISCONNECTED;
+        } else if (event.getEventType() == org.openhab.core.io.transport.serial.SerialPortEvent.DATA_AVAILABLE) {
+            return SerialPortEvent.EVENT_DATA_AVAILABLE;
+        } else {
+            return event.getEventType();
+        }
+    }
+}
diff --git a/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/serial/SerialPortProviderAdapter.java b/bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/serial/SerialPortProviderAdapter.java
new file mode 100644 (file)
index 0000000..e7db89f
--- /dev/null
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2010-2024 Contributors to the openHAB project
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ */
+
+package org.openhab.binding.openwebnet.internal.serial;
+
+import java.util.stream.Stream;
+
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
+import org.openhab.core.io.transport.serial.SerialPortIdentifier;
+import org.openhab.core.io.transport.serial.SerialPortManager;
+import org.openwebnet4j.communication.serial.spi.SerialPort;
+import org.openwebnet4j.communication.serial.spi.SerialPortProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import aQute.bnd.annotation.spi.ServiceProvider;
+
+/**
+ * openwebnet4j SerialPortProvider implementation based on OH serial transport
+ *
+ * @author M. Valla - Initial contribution
+ */
+@ServiceProvider(value = SerialPortProvider.class)
+@NonNullByDefault
+public class SerialPortProviderAdapter implements SerialPortProvider {
+
+    private Logger logger = LoggerFactory.getLogger(SerialPortProviderAdapter.class);
+    @Nullable
+    public static SerialPortManager serialPortManager = null;
+
+    public static void setSerialPortManager(SerialPortManager serialPortManager) {
+        SerialPortProviderAdapter.serialPortManager = serialPortManager;
+    }
+
+    @Override
+    public @Nullable SerialPort getSerialPort(String portName) {
+        final @Nullable SerialPortManager spm = serialPortManager;
+        if (spm == null) {
+            return null;
+        }
+        SerialPortIdentifier spid = spm.getIdentifier(portName);
+        if (spid == null) {
+            logger.debug("No SerialPort {} found", portName);
+            return null;
+        } else {
+            return new SerialPortAdapter(spid);
+        }
+    }
+
+    @Override
+    public Stream<SerialPort> getSerialPorts() {
+        final @Nullable SerialPortManager spm = serialPortManager;
+        if (spm == null) {
+            return Stream.empty();
+        }
+        return spm.getIdentifiers().map(sid -> new SerialPortAdapter(sid));
+    }
+}