Skip to content

Commit 3c53e1f

Browse files
authored
[openwebnet] Replace gnu.io dependency with serial transport (openhab#16376)
Signed-off-by: Massimo Valla <[email protected]>
1 parent e3d5e5d commit 3c53e1f

File tree

7 files changed

+295
-19
lines changed

7 files changed

+295
-19
lines changed

bundles/org.openhab.binding.openwebnet/pom.xml

+1-5
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,12 @@
1414

1515
<name>openHAB Add-ons :: Bundles :: OpenWebNet (BTicino/Legrand) Binding</name>
1616

17-
<properties>
18-
<bnd.importpackage>gnu.io;version="[3.12,6)"</bnd.importpackage>
19-
</properties>
20-
2117
<dependencies>
2218

2319
<dependency>
2420
<groupId>io.github.openwebnet4j</groupId>
2521
<artifactId>openwebnet4j</artifactId>
26-
<version>0.10.1</version>
22+
<version>0.12.0</version>
2723
<scope>compile</scope>
2824
</dependency>
2925

bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/discovery/UsbGatewayDiscoveryService.java

+24-10
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
import java.util.concurrent.CountDownLatch;
1919
import java.util.concurrent.ScheduledFuture;
2020
import java.util.concurrent.TimeUnit;
21-
import java.util.stream.Stream;
2221

2322
import org.eclipse.jdt.annotation.NonNullByDefault;
2423
import org.eclipse.jdt.annotation.Nullable;
2524
import org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants;
25+
import org.openhab.binding.openwebnet.internal.serial.SerialPortProviderAdapter;
2626
import org.openhab.core.config.discovery.AbstractDiscoveryService;
2727
import org.openhab.core.config.discovery.DiscoveryResult;
2828
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
@@ -44,11 +44,14 @@
4444
import org.slf4j.LoggerFactory;
4545

4646
/**
47-
* The {@link UsbGatewayDiscoveryService} extends {@link AbstractDiscoveryService} to detect Zigbee USB gateways
48-
* connected via serial port. The service will iterate over the available serial ports and open each one to test if a
49-
* OpenWebNet Zigbee USB gateway is connected. On successful connection, a new DiscoveryResult is created.
47+
* The {@link UsbGatewayDiscoveryService} extends
48+
* {@link AbstractDiscoveryService} to detect Zigbee USB gateways connected via
49+
* serial port. The service will iterate over the available serial ports and
50+
* open each one to test if a OpenWebNet Zigbee USB gateway is connected. On
51+
* successful connection, a new DiscoveryResult is created.
5052
*
51-
* @author Massimo Valla - Initial contribution
53+
* @author Massimo Valla - Initial contribution. Inject SerialPortManager to
54+
* openwebnet4j lib.
5255
*/
5356
@NonNullByDefault
5457
@Component(service = DiscoveryService.class, configurationPid = "discovery.openwebnet")
@@ -64,6 +67,8 @@ public class UsbGatewayDiscoveryService extends AbstractDiscoveryService impleme
6467
private @Nullable ScheduledFuture<?> connectTimeout;
6568

6669
private final SerialPortManager serialPortManager;
70+
private final SerialPortProviderAdapter transportAdapter;
71+
6772
private @Nullable USBGateway zbGateway;
6873

6974
private String currentScannedPortName = "";
@@ -74,27 +79,35 @@ public class UsbGatewayDiscoveryService extends AbstractDiscoveryService impleme
7479
private boolean scanning;
7580

7681
/**
77-
* Constructs a new UsbGatewayDiscoveryService with the specified Zigbee USB Bridge ThingTypeUID
82+
* Constructs a new UsbGatewayDiscoveryService with the specified Zigbee USB
83+
* Bridge ThingTypeUID
7884
*/
7985
@Activate
8086
public UsbGatewayDiscoveryService(final @Reference SerialPortManager spm) {
8187
super(Set.of(OpenWebNetBindingConstants.THING_TYPE_ZB_GATEWAY), DISCOVERY_TIMEOUT_SECONDS, false);
82-
// Obtain the serial port manager service using an OSGi reference
88+
// Inject the SerialPortManager passed via @Reference into the adapter
8389
serialPortManager = spm;
90+
SerialPortProviderAdapter.setSerialPortManager(spm);
91+
this.transportAdapter = new SerialPortProviderAdapter();
92+
logger.debug("**** -SPI- **** Set SerialPortManager to: {}", SerialPortProviderAdapter.serialPortManager);
8493
}
8594

8695
/**
87-
* Starts a new discovery scan. All available Serial Ports are scanned.
96+
* Starts a new discovery scan. All available SerialPortsIdentifiers returned by
97+
* SerialPortManager are scanned.
8898
*/
8999
@Override
90100
protected void startScan() {
91101
logger.debug("Started OpenWebNet Zigbee USB Gateway discovery scan");
92102
removeOlderResults(getTimestampOfLastScan());
93103
scanning = true;
94-
Stream<SerialPortIdentifier> portEnum = serialPortManager.getIdentifiers();
104+
105+
SerialPortIdentifier[] foundSerialPortIds = serialPortManager.getIdentifiers()
106+
.toArray(SerialPortIdentifier[]::new);
107+
95108
// Check each available serial port
96109
try {
97-
for (SerialPortIdentifier portIdentifier : portEnum.toArray(SerialPortIdentifier[]::new)) {
110+
for (SerialPortIdentifier portIdentifier : foundSerialPortIds) {
98111
if (scanning) {
99112
currentScannedPortName = portIdentifier.getName();
100113
logger.debug("[{}] == checking serial port", currentScannedPortName);
@@ -104,6 +117,7 @@ protected void startScan() {
104117
} else {
105118
logger.debug("[{}] trying to connect to a Zigbee USB Gateway...", currentScannedPortName);
106119
USBGateway gw = new USBGateway(currentScannedPortName);
120+
gw.setSerialPortProvider(transportAdapter);
107121
zbGateway = gw;
108122
gw.subscribe(this);
109123
portCheckLatch = new CountDownLatch(1);

bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetBridgeHandler.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.openhab.binding.openwebnet.internal.discovery.OpenWebNetDeviceDiscoveryService;
3333
import org.openhab.binding.openwebnet.internal.handler.config.OpenWebNetBusBridgeConfig;
3434
import org.openhab.binding.openwebnet.internal.handler.config.OpenWebNetZigBeeBridgeConfig;
35+
import org.openhab.binding.openwebnet.internal.serial.SerialPortProviderAdapter;
3536
import org.openhab.core.config.core.status.ConfigStatusMessage;
3637
import org.openhab.core.thing.Bridge;
3738
import org.openhab.core.thing.ChannelUID;
@@ -179,7 +180,11 @@ public void initialize() {
179180
"@text/offline.conf-error-no-serial-port");
180181
return null;
181182
} else {
182-
return new USBGateway(serialPort);
183+
USBGateway tmpUSBGateway = new USBGateway(serialPort);
184+
tmpUSBGateway.setSerialPortProvider(new SerialPortProviderAdapter());
185+
logger.debug("**** -SPI- **** OpenWebNetBridgeHandler :: setSerialPortProvider to: {}",
186+
tmpUSBGateway.getSerialPortProvider());
187+
return tmpUSBGateway;
183188
}
184189
}
185190

bundles/org.openhab.binding.openwebnet/src/main/java/org/openhab/binding/openwebnet/internal/handler/OpenWebNetLightingHandler.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,7 @@ protected Where buildBusWhere(String wStr) throws IllegalArgumentException {
385385
*
386386
* @param channelId the channelId string
387387
**/
388-
@Nullable
389-
private String toWhere(String channelId) {
388+
private String toWhere(String channelId) throws OWNException {
390389
Where w = deviceWhere;
391390
if (w != null) {
392391
OpenWebNetBridgeHandler brH = bridgeHandler;
@@ -400,6 +399,6 @@ private String toWhere(String channelId) {
400399
}
401400
}
402401
}
403-
return null;
402+
throw new OWNException("Cannot select channel from WHERE " + w);
404403
}
405404
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/**
2+
* Copyright (c) 2010-2024 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
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
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.binding.openwebnet.internal.serial;
14+
15+
import java.io.IOException;
16+
import java.io.InputStream;
17+
import java.io.OutputStream;
18+
import java.util.TooManyListenersException;
19+
20+
import org.eclipse.jdt.annotation.NonNullByDefault;
21+
import org.eclipse.jdt.annotation.Nullable;
22+
import org.openhab.core.io.transport.serial.PortInUseException;
23+
import org.openhab.core.io.transport.serial.SerialPort;
24+
import org.openhab.core.io.transport.serial.SerialPortEvent;
25+
import org.openhab.core.io.transport.serial.SerialPortEventListener;
26+
import org.openhab.core.io.transport.serial.SerialPortIdentifier;
27+
import org.openhab.core.io.transport.serial.UnsupportedCommOperationException;
28+
import org.slf4j.Logger;
29+
import org.slf4j.LoggerFactory;
30+
31+
/**
32+
* openwebnet4j SerialPort implementation based on OH serial transport
33+
*
34+
* @author M. Valla - Initial contribution
35+
*/
36+
37+
@NonNullByDefault
38+
public class SerialPortAdapter implements org.openwebnet4j.communication.serial.spi.SerialPort {
39+
40+
private static final Logger logger = LoggerFactory.getLogger(SerialPortAdapter.class);
41+
42+
private static final int OPEN_TIMEOUT_MS = 200;
43+
44+
private final SerialPortIdentifier spid;
45+
46+
private @Nullable SerialPort sp = null;
47+
48+
public SerialPortAdapter(final SerialPortIdentifier spid) {
49+
this.spid = spid;
50+
}
51+
52+
@Override
53+
public boolean setSerialPortParams(int baudrate, int dataBits, int stopBits, int parity) {
54+
@Nullable
55+
SerialPort lsp = sp;
56+
if (lsp != null) {
57+
try {
58+
lsp.setSerialPortParams(baudrate, dataBits, stopBits, parity);
59+
return true;
60+
} catch (UnsupportedCommOperationException e) {
61+
logger.error("UnsupportedCommOperationException while setting port params in setSerialPortParams: {}",
62+
e.getMessage());
63+
return false;
64+
}
65+
}
66+
return false;
67+
}
68+
69+
@Override
70+
public boolean addEventListener(org.openwebnet4j.communication.serial.spi.SerialPortEventListener listener) {
71+
@Nullable
72+
SerialPort lsp = sp;
73+
if (lsp != null) {
74+
try {
75+
lsp.addEventListener(new SerialPortEventListener() {
76+
77+
@Override
78+
public void serialEvent(SerialPortEvent event) {
79+
if (event != null) {
80+
listener.serialEvent(new SerialPortEventAdapter(event));
81+
}
82+
}
83+
});
84+
lsp.notifyOnDataAvailable(true);
85+
return true;
86+
} catch (TooManyListenersException e) {
87+
logger.error("TooManyListenersException while adding event listener: {}", e.getMessage());
88+
}
89+
}
90+
return false;
91+
}
92+
93+
@Override
94+
public boolean open() {
95+
try {
96+
sp = spid.open(this.getClass().getName(), OPEN_TIMEOUT_MS);
97+
} catch (PortInUseException e) {
98+
logger.error("PortInUseException while opening serial port {}: {}", spid.getName(), e.getMessage());
99+
return false;
100+
}
101+
return true;
102+
}
103+
104+
@Override
105+
public @Nullable String getName() {
106+
@Nullable
107+
SerialPort lsp = sp;
108+
if (lsp != null) {
109+
return lsp.getName();
110+
} else {
111+
return null;
112+
}
113+
}
114+
115+
@Override
116+
public @Nullable InputStream getInputStream() throws IOException {
117+
@Nullable
118+
SerialPort lsp = sp;
119+
if (lsp != null) {
120+
return lsp.getInputStream();
121+
} else {
122+
return null;
123+
}
124+
}
125+
126+
@Override
127+
public @Nullable OutputStream getOutputStream() throws IOException {
128+
@Nullable
129+
SerialPort lsp = sp;
130+
if (lsp != null) {
131+
return lsp.getOutputStream();
132+
} else {
133+
return null;
134+
}
135+
}
136+
137+
@Override
138+
public void close() {
139+
@Nullable
140+
SerialPort lsp = sp;
141+
if (lsp != null) {
142+
lsp.close();
143+
}
144+
}
145+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Copyright (c) 2010-2024 Contributors to the openHAB project
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information.
6+
*
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
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.openhab.binding.openwebnet.internal.serial;
14+
15+
import org.eclipse.jdt.annotation.NonNullByDefault;
16+
import org.openwebnet4j.communication.serial.spi.SerialPortEvent;
17+
18+
/**
19+
* openwebnet4j SerialPortEvent implementation based on OH serial transport
20+
*
21+
* @author M. Valla - Initial contribution
22+
*/
23+
24+
@NonNullByDefault
25+
public class SerialPortEventAdapter implements SerialPortEvent {
26+
27+
private final org.openhab.core.io.transport.serial.SerialPortEvent event;
28+
29+
/**
30+
* Constructor.
31+
*
32+
* @param event the underlying event implementation
33+
*/
34+
public SerialPortEventAdapter(org.openhab.core.io.transport.serial.SerialPortEvent event) {
35+
this.event = event;
36+
}
37+
38+
@Override
39+
public int getEventType() {
40+
if (event.getEventType() == org.openhab.core.io.transport.serial.SerialPortEvent.PORT_DISCONNECTED) {
41+
return SerialPortEvent.EVENT_PORT_DISCONNECTED;
42+
} else if (event.getEventType() == org.openhab.core.io.transport.serial.SerialPortEvent.DATA_AVAILABLE) {
43+
return SerialPortEvent.EVENT_DATA_AVAILABLE;
44+
} else {
45+
return event.getEventType();
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)