From 0edb45ba5281087b909166b7d84c2ef7c6df5e0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Dywicki?= Date: Mon, 18 Mar 2024 10:39:35 +0100 Subject: [PATCH] Update CAN bus interactions to match new plc4x 0.13 API behavior. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Ɓukasz Dywicki --- .../canbus/internal/DefaultCanConnection.java | 8 +-- .../CANInterfaceDiscoveryDelegate.java | 2 +- .../handler/protocol/TAOperations.java | 41 +++++++------ .../binding/canopen/ta/tapi/dev/TADevice.java | 61 ++++++++++--------- .../dev/publisher/PublishingRunnable.java | 6 +- .../handler/CoPdoTransmitHandler.java | 12 +--- .../handler/CoSocketCANBridgeHandler.java | 29 ++++++++- .../internal/plc4x/CoRecordReader.java | 10 ++- .../DBusCanNetworkInterfaceProvider.java | 2 +- parent/pom.xml | 4 +- 10 files changed, 92 insertions(+), 83 deletions(-) diff --git a/bundles/org.connectorio.addons.binding.canbus/src/main/java/org/connectorio/addons/binding/canbus/internal/DefaultCanConnection.java b/bundles/org.connectorio.addons.binding.canbus/src/main/java/org/connectorio/addons/binding/canbus/internal/DefaultCanConnection.java index caae01ec..c52e89b3 100644 --- a/bundles/org.connectorio.addons.binding.canbus/src/main/java/org/connectorio/addons/binding/canbus/internal/DefaultCanConnection.java +++ b/bundles/org.connectorio.addons.binding.canbus/src/main/java/org/connectorio/addons/binding/canbus/internal/DefaultCanConnection.java @@ -13,6 +13,7 @@ import org.apache.plc4x.java.api.value.PlcValue; import org.apache.plc4x.java.can.generic.tag.GenericCANTag; import org.apache.plc4x.java.genericcan.readwrite.GenericCANDataType; +import org.apache.plc4x.java.spi.values.PlcRawByteArray; import org.apache.plc4x.java.spi.values.PlcUSINT; import org.apache.plc4x.java.spi.values.PlcValues; import org.connectorio.addons.binding.canbus.CanConnection; @@ -35,12 +36,7 @@ public CompletableFuture write(int cob, byte[] data) { } private PlcValue encode(byte[] data) { - List values = new ArrayList<>(); - for (byte b : data) { - values.add(new PlcUSINT(b)); - } - - return PlcValues.of(values); + return new PlcRawByteArray(data); } @Override diff --git a/bundles/org.connectorio.addons.binding.canbus/src/main/java/org/connectorio/addons/binding/canbus/internal/discovery/CANInterfaceDiscoveryDelegate.java b/bundles/org.connectorio.addons.binding.canbus/src/main/java/org/connectorio/addons/binding/canbus/internal/discovery/CANInterfaceDiscoveryDelegate.java index 6113fd90..93ba825d 100644 --- a/bundles/org.connectorio.addons.binding.canbus/src/main/java/org/connectorio/addons/binding/canbus/internal/discovery/CANInterfaceDiscoveryDelegate.java +++ b/bundles/org.connectorio.addons.binding.canbus/src/main/java/org/connectorio/addons/binding/canbus/internal/discovery/CANInterfaceDiscoveryDelegate.java @@ -41,7 +41,7 @@ /** * Basic discovery service which rely on network API to discover CAN interface. */ -@Component(service = {DiscoveryService.class, NetworkInterfaceStateCallback.class}) +@Component(service = {DiscoveryService.class, NetworkInterfaceStateCallback.class}, immediate = true) public class CANInterfaceDiscoveryDelegate extends AbstractDiscoveryService implements DiscoveryService, NetworkInterfaceStateCallback { diff --git a/bundles/org.connectorio.addons.binding.canopen.ta/src/main/java/org/connectorio/addons/binding/canopen/ta/internal/handler/protocol/TAOperations.java b/bundles/org.connectorio.addons.binding.canopen.ta/src/main/java/org/connectorio/addons/binding/canopen/ta/internal/handler/protocol/TAOperations.java index 986e88fa..48d71ed0 100644 --- a/bundles/org.connectorio.addons.binding.canopen.ta/src/main/java/org/connectorio/addons/binding/canopen/ta/internal/handler/protocol/TAOperations.java +++ b/bundles/org.connectorio.addons.binding.canopen.ta/src/main/java/org/connectorio/addons/binding/canopen/ta/internal/handler/protocol/TAOperations.java @@ -48,6 +48,7 @@ import org.apache.plc4x.java.spi.generation.ParseException; import org.apache.plc4x.java.spi.generation.ReadBuffer; import org.apache.plc4x.java.spi.generation.ReadBufferByteBased; +import org.apache.plc4x.java.spi.values.PlcRawByteArray; import org.apache.plc4x.java.spi.values.PlcUSINT; import org.apache.plc4x.java.spi.values.PlcValues; import org.connectorio.addons.binding.canopen.ta.internal.type.TAString; @@ -144,31 +145,31 @@ public CompletableFuture reload(int nodeId) { } public CompletableFuture login(int nodeId, int clientId) { - return connection.writeRequestBuilder().addTag("mpdo", new CANOpenPDOTag(clientId, CANOpenService.RECEIVE_PDO_3, CANOpenDataType.RECORD), PlcValues.of( - new PlcUSINT((0x80 + nodeId)), - new PlcUSINT(0x00), - new PlcUSINT(0x1F), - new PlcUSINT(0x00), - new PlcUSINT(nodeId), - new PlcUSINT(clientId), - new PlcUSINT(0x80), - new PlcUSINT(0x12) - )).build().execute().whenComplete((response, error) -> { + return connection.writeRequestBuilder().addTag("mpdo", new CANOpenPDOTag(clientId, CANOpenService.RECEIVE_PDO_3, CANOpenDataType.RECORD), new PlcRawByteArray(new byte[] { + (byte) (0x80 + nodeId), + (byte) 0x00, + (byte) 0x1F, + (byte) 0x00, + (byte) nodeId, + (byte) clientId, + (byte) 0x80, + (byte) 0x12 + })).build().execute().whenComplete((response, error) -> { logger.debug("Dispatched login request to node {}", nodeId, error); }); } public CompletableFuture logout(int nodeId, int clientId) { - return connection.writeRequestBuilder().addTagAddress("mpdo", "RECEIVE_PDO_3:" + clientId + ":RECORD", PlcValues.of( - new PlcUSINT((0x80 + nodeId)), - new PlcUSINT(0x01), - new PlcUSINT(0x1F), - new PlcUSINT(0x00), - new PlcUSINT(nodeId), - new PlcUSINT(clientId), - new PlcUSINT(0x80), - new PlcUSINT(0x12) - )).build().execute().whenComplete((response, error) -> { + return connection.writeRequestBuilder().addTagAddress("mpdo", "RECEIVE_PDO_3:" + clientId + ":RECORD", new PlcRawByteArray(new byte[]{ + (byte) (0x80 + nodeId), + (byte) 0x01, + (byte) 0x1F, + (byte) 0x00, + (byte) nodeId, + (byte) clientId, + (byte) 0x80, + (byte) 0x12 + })).build().execute().whenComplete((response, error) -> { logger.debug("Dispatched logout request to node {}", nodeId, error); }); } diff --git a/bundles/org.connectorio.addons.binding.canopen.ta/src/main/java/org/connectorio/addons/binding/canopen/ta/tapi/dev/TADevice.java b/bundles/org.connectorio.addons.binding.canopen.ta/src/main/java/org/connectorio/addons/binding/canopen/ta/tapi/dev/TADevice.java index 86b3566a..7939174d 100644 --- a/bundles/org.connectorio.addons.binding.canopen.ta/src/main/java/org/connectorio/addons/binding/canopen/ta/tapi/dev/TADevice.java +++ b/bundles/org.connectorio.addons.binding.canopen.ta/src/main/java/org/connectorio/addons/binding/canopen/ta/tapi/dev/TADevice.java @@ -31,6 +31,7 @@ import java.util.function.Function; import org.apache.commons.codec.binary.Hex; import org.apache.plc4x.java.canopen.readwrite.CANOpenService; +import org.apache.plc4x.java.spi.values.PlcRawByteArray; import org.apache.plc4x.java.spi.values.PlcUSINT; import org.apache.plc4x.java.spi.values.PlcValues; import org.connectorio.addons.binding.canopen.api.CoNode; @@ -249,29 +250,29 @@ public void reload() { } public void login() { - node.getConnection().send(clientId, CANOpenService.RECEIVE_PDO_3, PlcValues.of( - new PlcUSINT(0x80 + node.getNodeId()), - new PlcUSINT(0x00), - new PlcUSINT(0x1F), - new PlcUSINT(0x00), - new PlcUSINT(node.getNodeId()), - new PlcUSINT(clientId), - new PlcUSINT(0x80), - new PlcUSINT(0x12) - )); + node.getConnection().send(clientId, CANOpenService.RECEIVE_PDO_3, new PlcRawByteArray(new byte[] { + (byte) (0x80 + node.getNodeId()), + (byte) 0x00, + (byte) 0x1F, + (byte) 0x00, + (byte) node.getNodeId(), + (byte) clientId, + (byte) 0x80, + (byte) 0x12 + })); } public void logout() { - node.getConnection().send(clientId, CANOpenService.RECEIVE_PDO_3, PlcValues.of( - new PlcUSINT(0x80 + node.getNodeId()), - new PlcUSINT(0x01), - new PlcUSINT(0x1F), - new PlcUSINT(0x00), - new PlcUSINT(node.getNodeId()), - new PlcUSINT(clientId), - new PlcUSINT(0x80), - new PlcUSINT(0x12) - )); + node.getConnection().send(clientId, CANOpenService.RECEIVE_PDO_3, new PlcRawByteArray(new byte[]{ + (byte) (0x80 + node.getNodeId()), + (byte) 0x01, + (byte) 0x1F, + (byte) 0x00, + (byte) node.getNodeId(), + (byte) clientId, + (byte) 0x80, + (byte) 0x12 + })); } public void close() { @@ -423,16 +424,16 @@ protected void subscribe(int nodeId, CANOpenService service, Consumer co private void reloadOutputs() { logger.info("Reload {} outputs.", node.getNodeId()); - node.getConnection().send(0, CANOpenService.TRANSMIT_PDO_4, PlcValues.of( - new PlcUSINT(0x80 + node.getNodeId()), - new PlcUSINT(0x01), - new PlcUSINT(0x4e), - new PlcUSINT(0x01), - new PlcUSINT(0x01), - new PlcUSINT(0x00), - new PlcUSINT(0x00), - new PlcUSINT(0x00) - )); + node.getConnection().send(0, CANOpenService.TRANSMIT_PDO_4, new PlcRawByteArray(new byte[]{ + (byte) (0x80 + node.getNodeId()), + (byte) 0x01, + (byte) 0x4e, + (byte) 0x01, + (byte) 0x01, + (byte) 0x00, + (byte) 0x00, + (byte) 0x00 + })); } private void scanFunctions() { diff --git a/bundles/org.connectorio.addons.binding.canopen.ta/src/main/java/org/connectorio/addons/binding/canopen/ta/tapi/dev/publisher/PublishingRunnable.java b/bundles/org.connectorio.addons.binding.canopen.ta/src/main/java/org/connectorio/addons/binding/canopen/ta/tapi/dev/publisher/PublishingRunnable.java index a51c8906..953f8b08 100644 --- a/bundles/org.connectorio.addons.binding.canopen.ta/src/main/java/org/connectorio/addons/binding/canopen/ta/tapi/dev/publisher/PublishingRunnable.java +++ b/bundles/org.connectorio.addons.binding.canopen.ta/src/main/java/org/connectorio/addons/binding/canopen/ta/tapi/dev/publisher/PublishingRunnable.java @@ -22,6 +22,7 @@ import org.apache.plc4x.java.canopen.readwrite.CANOpenService; import org.apache.plc4x.java.spi.generation.WriteBuffer; import org.apache.plc4x.java.spi.generation.WriteBufferByteBased; +import org.apache.plc4x.java.spi.values.PlcRawByteArray; import org.apache.plc4x.java.spi.values.PlcSINT; import org.apache.plc4x.java.spi.values.PlcValues; import org.connectorio.addons.binding.canopen.api.CoNode; @@ -40,10 +41,7 @@ protected PublishingRunnable(CoNode node) { protected final void send(int nodeId, CANOpenService service, WriteBufferByteBased buffer) { byte[] data = buffer.getBytes(); logger.trace("Send to node {} {} (cob {}) data: {}", nodeId, service, Integer.toHexString(service.getMin() + nodeId), Hex.encodeHexString(data)); - node.getConnection().send(nodeId, service, PlcValues.of( - new PlcSINT(data[0]), new PlcSINT(data[1]), new PlcSINT(data[2]), new PlcSINT(data[3]), - new PlcSINT(data[4]), new PlcSINT(data[5]), new PlcSINT(data[6]), new PlcSINT(data[7]) - )); + node.getConnection().send(nodeId, service, new PlcRawByteArray(data)); } protected boolean hasKeyInRange(Map elements, int start, int limit) { diff --git a/bundles/org.connectorio.addons.binding.canopen/src/main/java/org/connectorio/addons/binding/canopen/internal/handler/CoPdoTransmitHandler.java b/bundles/org.connectorio.addons.binding.canopen/src/main/java/org/connectorio/addons/binding/canopen/internal/handler/CoPdoTransmitHandler.java index 3a774a51..b54fa78e 100644 --- a/bundles/org.connectorio.addons.binding.canopen/src/main/java/org/connectorio/addons/binding/canopen/internal/handler/CoPdoTransmitHandler.java +++ b/bundles/org.connectorio.addons.binding.canopen/src/main/java/org/connectorio/addons/binding/canopen/internal/handler/CoPdoTransmitHandler.java @@ -29,6 +29,7 @@ import org.apache.plc4x.java.spi.generation.SerializationException; import org.apache.plc4x.java.spi.generation.WriteBuffer; import org.apache.plc4x.java.spi.generation.WriteBufferByteBased; +import org.apache.plc4x.java.spi.values.PlcRawByteArray; import org.apache.plc4x.java.spi.values.PlcSINT; import org.apache.plc4x.java.spi.values.PlcValues; import org.connectorio.addons.binding.canopen.api.CoNode; @@ -104,16 +105,7 @@ private void publish() { } private PlcValue toPlcValue(byte[] data) { - return PlcValues.of( - new PlcSINT(data.length > 0 ? data[0] : 0), - new PlcSINT(data.length > 1 ? data[1] : 0), - new PlcSINT(data.length > 2 ? data[2] : 0), - new PlcSINT(data.length > 3 ? data[3] : 0), - new PlcSINT(data.length > 4 ? data[4] : 0), - new PlcSINT(data.length > 5 ? data[5] : 0), - new PlcSINT(data.length > 6 ? data[6] : 0), - new PlcSINT(data.length > 7 ? data[7] : 0) - ); + return new PlcRawByteArray(data); } private void writeState(WriteBuffer buffer, CANOpenDataType type, Command command) throws SerializationException { diff --git a/bundles/org.connectorio.addons.binding.canopen/src/main/java/org/connectorio/addons/binding/canopen/internal/handler/CoSocketCANBridgeHandler.java b/bundles/org.connectorio.addons.binding.canopen/src/main/java/org/connectorio/addons/binding/canopen/internal/handler/CoSocketCANBridgeHandler.java index 1d0ecf6f..920fc3b8 100644 --- a/bundles/org.connectorio.addons.binding.canopen/src/main/java/org/connectorio/addons/binding/canopen/internal/handler/CoSocketCANBridgeHandler.java +++ b/bundles/org.connectorio.addons.binding.canopen/src/main/java/org/connectorio/addons/binding/canopen/internal/handler/CoSocketCANBridgeHandler.java @@ -76,10 +76,24 @@ public void run() { config = getBridgeConfig().get(); String nodeId = "nodeId=" + config.nodeId; String heartbeat = "&heartbeat=" + config.heartbeat; - AbstractPlcConnection connection = (AbstractPlcConnection) driverManager - .getConnectionManager().getConnection("canopen:socketcan://" + config.name + "?" + nodeId + heartbeat); - if (connection.isConnected()) { + AbstractPlcConnection connection = null; + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); +// List> transports = ServiceLoader.load(Transport.class, getClass().getClassLoader()).stream().collect(Collectors.toList()); +// transports = ServiceLoader.load(Transport.class, SocketCANTransport.class.getClassLoader()).stream().collect(Collectors.toList()); + connection = (AbstractPlcConnection) driverManager.getConnectionManager().getConnection("canopen:socketcan://" + config.name + "?" + nodeId + heartbeat); + } finally { + Thread.currentThread().setContextClassLoader(tccl); + } + + if (connection != null && !connection.isConnected()) { + // force connection attempt + connection.connect(); + } + + if (connection != null && connection.isConnected()) { updateStatus(ThingStatus.ONLINE); initializer.complete(connection); } else { @@ -105,6 +119,15 @@ public void dispose() { if (statisticPoller != null) { statisticPoller.cancel(true); } + initializer.thenAccept(connection -> { + if (connection.isConnected()) { + try { + connection.close(); + } catch (Exception e) { + logger.warn("Failure while closing connection", e); + } + } + }); } @Override diff --git a/bundles/org.connectorio.addons.binding.canopen/src/main/java/org/connectorio/addons/binding/canopen/internal/plc4x/CoRecordReader.java b/bundles/org.connectorio.addons.binding.canopen/src/main/java/org/connectorio/addons/binding/canopen/internal/plc4x/CoRecordReader.java index 3db5854d..ca9ad3c7 100644 --- a/bundles/org.connectorio.addons.binding.canopen/src/main/java/org/connectorio/addons/binding/canopen/internal/plc4x/CoRecordReader.java +++ b/bundles/org.connectorio.addons.binding.canopen/src/main/java/org/connectorio/addons/binding/canopen/internal/plc4x/CoRecordReader.java @@ -33,13 +33,11 @@ public CoRecordReader(String field) { @Override protected byte[] extract(PlcReadResponse response, String field) { - List bytes = new ArrayList<>(response.getAllBytes(field)); - byte[] value = new byte[bytes.size()]; - for (int index = 0; index < bytes.size(); index++) { - value[index] = bytes.get(index); + Object bytes = response.getObject(field); + if (bytes instanceof byte[]) { + return (byte[]) bytes; } - - return value; + throw new IllegalArgumentException("Unexpected value, expected byte[] got " + (bytes != null ? bytes.getClass().getName() : "NULL")); } } diff --git a/bundles/org.connectorio.addons.network.can.dbus/src/main/java/org/connectorio/addons/network/can/dbus/internal/DBusCanNetworkInterfaceProvider.java b/bundles/org.connectorio.addons.network.can.dbus/src/main/java/org/connectorio/addons/network/can/dbus/internal/DBusCanNetworkInterfaceProvider.java index ca8e4a88..c152b87c 100644 --- a/bundles/org.connectorio.addons.network.can.dbus/src/main/java/org/connectorio/addons/network/can/dbus/internal/DBusCanNetworkInterfaceProvider.java +++ b/bundles/org.connectorio.addons.network.can.dbus/src/main/java/org/connectorio/addons/network/can/dbus/internal/DBusCanNetworkInterfaceProvider.java @@ -55,7 +55,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Component(service = NetworkInterfaceProvider.class) +@Component(service = NetworkInterfaceProvider.class, immediate = true) public class DBusCanNetworkInterfaceProvider implements NetworkInterfaceProvider, DBusSigHandler { public static final String PROPERTIES_TYPE = "org.freedesktop.DBus.Properties"; diff --git a/parent/pom.xml b/parent/pom.xml index 83eb3c02..b6047130 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -37,8 +37,8 @@ 11 11 - 0.12.0 - 1.3.0-beta1 + 0.13.0-connectorio-1 + 1.3.0-beta3 3.0.4 3.0.0-alpha-4