mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[openwebnet] Replace gnu.io dependency with serial transport (#16376)
Signed-off-by: Massimo Valla <mvcode00@gmail.com> Signed-off-by: Ciprian Pascu <contact@ciprianpascu.ro>
This commit is contained in:
parent
b2737becd6
commit
17f5a069a7
@ -14,16 +14,12 @@
|
||||
|
||||
<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>
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user