You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2024/02/15 08:50:56 UTC

(plc4x) branch develop updated: feat: Added a pingAddress config option to the modbus driver, which allows providing an address string, that can be used for ping-operations (Defaults to reading holding-register:1)

This is an automated email from the ASF dual-hosted git repository.

cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git


The following commit(s) were added to refs/heads/develop by this push:
     new fa615dc366 feat: Added a pingAddress config option to the modbus driver, which allows providing an address string, that can be used for ping-operations (Defaults to reading holding-register:1)
fa615dc366 is described below

commit fa615dc36617f02b9025194aeb6e44e3469d6e75
Author: Christofer Dutz <cd...@apache.org>
AuthorDate: Thu Feb 15 09:50:48 2024 +0100

    feat: Added a pingAddress config option to the modbus driver, which allows providing an address string, that can be used for ping-operations (Defaults to reading holding-register:1)
---
 plc4j/drivers/all/src/site/generated/modbus-tcp.adoc        |  1 +
 .../modbus/ascii/protocol/ModbusAsciiProtocolLogic.java     | 11 +++++------
 .../java/modbus/base/protocol/ModbusProtocolLogic.java      |  2 ++
 .../java/modbus/rtu/protocol/ModbusRtuProtocolLogic.java    | 11 +++++------
 .../java/modbus/tcp/config/ModbusTcpConfiguration.java      | 11 +++++++++++
 .../java/modbus/tcp/protocol/ModbusTcpProtocolLogic.java    | 13 +++++++------
 .../project/src/generated/plc4j-tools-ui-frontend.ts        |  2 +-
 7 files changed, 32 insertions(+), 19 deletions(-)

diff --git a/plc4j/drivers/all/src/site/generated/modbus-tcp.adoc b/plc4j/drivers/all/src/site/generated/modbus-tcp.adoc
index 071d0a83ea..82fa5ea284 100644
--- a/plc4j/drivers/all/src/site/generated/modbus-tcp.adoc
+++ b/plc4j/drivers/all/src/site/generated/modbus-tcp.adoc
@@ -38,6 +38,7 @@
 5+|Config options:
 |`request-timeout` |INT |5000| |Default timeout for all types of requests.
 |`unit-identifier` |INT |1| |Unit-identifier that identifies the target PLC (On RS485 multiple Modbus Devices can be listening). Defaults to 1.
+|`ping-address` |STRING |4x00001:BOOL| |Simple address, that the driver will use to check, if the connection to a given device is active (Defaults to reading holding-register 1).
 5+|Transport config options:
 5+|
 +++
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/protocol/ModbusAsciiProtocolLogic.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/protocol/ModbusAsciiProtocolLogic.java
index a2f6ef669f..f00970f2be 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/protocol/ModbusAsciiProtocolLogic.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/ascii/protocol/ModbusAsciiProtocolLogic.java
@@ -60,12 +60,11 @@ public class ModbusAsciiProtocolLogic extends ModbusProtocolLogic<ModbusAsciiADU
     public CompletableFuture<PlcPingResponse> ping(PlcPingRequest pingRequest) {
         CompletableFuture<PlcPingResponse> future = new CompletableFuture<>();
 
-        // 0x00 should be the "vendor-id" and is part of the basic level
-        // This is theoretically required, however have I never come across
-        // an implementation that actually provides it.
-        final ModbusPDU identificationRequestPdu = new ModbusPDUReadDeviceIdentificationRequest(
-            ModbusDeviceInformationLevel.BASIC, (short) 0x00);
-        ModbusAsciiADU modbusTcpADU = new ModbusAsciiADU(unitIdentifier, identificationRequestPdu);
+        // As it seems that even, if Modbus defines a DeviceIdentificationRequest, no device actually implements this.
+        // So we fall back to a request, that most certainly is implemented by any device. Even if the device doesn't
+        // have any holding-register:1, it should still gracefully respond.
+        ModbusPDU readRequestPdu = getReadRequestPdu(pingAddress);
+        ModbusAsciiADU modbusTcpADU = new ModbusAsciiADU(unitIdentifier, readRequestPdu);
 
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
         transaction.submit(() -> context.sendRequest(modbusTcpADU)
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/protocol/ModbusProtocolLogic.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/protocol/ModbusProtocolLogic.java
index c246896d03..7b62f03b8e 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/protocol/ModbusProtocolLogic.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/base/protocol/ModbusProtocolLogic.java
@@ -48,6 +48,8 @@ public abstract class ModbusProtocolLogic<T extends ModbusADU> extends Plc4xProt
     protected final DriverType driverType;
     protected Duration requestTimeout;
     protected short unitIdentifier;
+    protected PlcTag pingAddress;
+
     protected RequestTransactionManager tm;
     protected final AtomicInteger transactionIdentifierGenerator = new AtomicInteger(1);
     protected final static int FC_EXTENDED_REGISTERS_GROUP_HEADER_LENGTH = 2;
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/protocol/ModbusRtuProtocolLogic.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/protocol/ModbusRtuProtocolLogic.java
index 7c7f4b6939..e6812527ac 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/protocol/ModbusRtuProtocolLogic.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/rtu/protocol/ModbusRtuProtocolLogic.java
@@ -60,12 +60,11 @@ public class ModbusRtuProtocolLogic extends ModbusProtocolLogic<ModbusRtuADU> im
     public CompletableFuture<PlcPingResponse> ping(PlcPingRequest pingRequest) {
         CompletableFuture<PlcPingResponse> future = new CompletableFuture<>();
 
-        // 0x00 should be the "vendor-id" and is part of the basic level
-        // This is theoretically required, however have I never come across
-        // an implementation that actually provides it.
-        final ModbusPDU identificationRequestPdu = new ModbusPDUReadDeviceIdentificationRequest(
-            ModbusDeviceInformationLevel.BASIC, (short) 0x00);
-        ModbusRtuADU modbusRtuADU = new ModbusRtuADU(unitIdentifier, identificationRequestPdu);
+        // As it seems that even, if Modbus defines a DeviceIdentificationRequest, no device actually implements this.
+        // So we fall back to a request, that most certainly is implemented by any device. Even if the device doesn't
+        // have any holding-register:1, it should still gracefully respond.
+        ModbusPDU readRequestPdu = getReadRequestPdu(pingAddress);
+        ModbusRtuADU modbusRtuADU = new ModbusRtuADU(unitIdentifier, readRequestPdu);
 
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
         transaction.submit(() -> context.sendRequest(modbusRtuADU)
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/config/ModbusTcpConfiguration.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/config/ModbusTcpConfiguration.java
index 0d6e980d2d..6a26fbf932 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/config/ModbusTcpConfiguration.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/config/ModbusTcpConfiguration.java
@@ -22,6 +22,7 @@ import org.apache.plc4x.java.spi.configuration.PlcConnectionConfiguration;
 import org.apache.plc4x.java.spi.configuration.annotations.ConfigurationParameter;
 import org.apache.plc4x.java.spi.configuration.annotations.Description;
 import org.apache.plc4x.java.spi.configuration.annotations.defaults.IntDefaultValue;
+import org.apache.plc4x.java.spi.configuration.annotations.defaults.StringDefaultValue;
 
 public class ModbusTcpConfiguration implements PlcConnectionConfiguration {
 
@@ -35,6 +36,11 @@ public class ModbusTcpConfiguration implements PlcConnectionConfiguration {
     @Description("Unit-identifier that identifies the target PLC (On RS485 multiple Modbus Devices can be listening). Defaults to 1.")
     private int unitIdentifier;
 
+    @ConfigurationParameter("ping-address")
+    @StringDefaultValue("4x00001:BOOL")
+    @Description("Simple address, that the driver will use to check, if the connection to a given device is active (Defaults to reading holding-register 1).")
+    private String pingAddress;
+
     public int getRequestTimeout() {
         return requestTimeout;
     }
@@ -51,11 +57,16 @@ public class ModbusTcpConfiguration implements PlcConnectionConfiguration {
         this.unitIdentifier = unitIdentifier;
     }
 
+    public String getPingAddress() {
+        return pingAddress;
+    }
+
     @Override
     public String toString() {
         return "ModbusTcpConfiguration{" +
             "requestTimeout=" + requestTimeout +
             ", unitIdentifier=" + unitIdentifier +
+            ", pingAddress=" + pingAddress +
             '}';
     }
 
diff --git a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/protocol/ModbusTcpProtocolLogic.java b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/protocol/ModbusTcpProtocolLogic.java
index 4de44b2728..53710f5177 100644
--- a/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/protocol/ModbusTcpProtocolLogic.java
+++ b/plc4j/drivers/modbus/src/main/java/org/apache/plc4x/java/modbus/tcp/protocol/ModbusTcpProtocolLogic.java
@@ -25,6 +25,7 @@ import org.apache.plc4x.java.api.types.PlcResponseCode;
 import org.apache.plc4x.java.api.value.PlcValue;
 import org.apache.plc4x.java.modbus.base.tag.ModbusTag;
 import org.apache.plc4x.java.modbus.base.protocol.ModbusProtocolLogic;
+import org.apache.plc4x.java.modbus.base.tag.ModbusTagHandler;
 import org.apache.plc4x.java.modbus.readwrite.*;
 import org.apache.plc4x.java.modbus.tcp.config.ModbusTcpConfiguration;
 import org.apache.plc4x.java.spi.ConversationContext;
@@ -48,6 +49,7 @@ public class ModbusTcpProtocolLogic extends ModbusProtocolLogic<ModbusTcpADU> im
     public void setConfiguration(ModbusTcpConfiguration configuration) {
         this.requestTimeout = Duration.ofMillis(configuration.getRequestTimeout());
         this.unitIdentifier = (short) configuration.getUnitIdentifier();
+        this.pingAddress = new ModbusTagHandler().parseTag(configuration.getPingAddress());
         this.tm = new RequestTransactionManager(1);
     }
 
@@ -60,17 +62,16 @@ public class ModbusTcpProtocolLogic extends ModbusProtocolLogic<ModbusTcpADU> im
     public CompletableFuture<PlcPingResponse> ping(PlcPingRequest pingRequest) {
         CompletableFuture<PlcPingResponse> future = new CompletableFuture<>();
 
-        // 0x00 should be the "vendor-id" and is part of the basic level
-        // This is theoretically required, however have I never come across
-        // an implementation that actually provides it.
-        final ModbusPDU identificationRequestPdu = new ModbusPDUReadDeviceIdentificationRequest(
-            ModbusDeviceInformationLevel.BASIC, (short) 0x00);
+        // As it seems that even, if Modbus defines a DeviceIdentificationRequest, no device actually implements this.
+        // So we fall back to a request, that most certainly is implemented by any device. Even if the device doesn't
+        // have any holding-register:1, it should still gracefully respond.
+        ModbusPDU readRequestPdu = getReadRequestPdu(pingAddress);
         int transactionIdentifier = transactionIdentifierGenerator.getAndIncrement();
         // If we've reached the max value for a 16 bit transaction identifier, reset back to 1
         if (transactionIdentifierGenerator.get() == 0xFFFF) {
             transactionIdentifierGenerator.set(1);
         }
-        ModbusTcpADU modbusTcpADU = new ModbusTcpADU(transactionIdentifier, unitIdentifier, identificationRequestPdu);
+        ModbusTcpADU modbusTcpADU = new ModbusTcpADU(transactionIdentifier, unitIdentifier, readRequestPdu);
 
         RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
         transaction.submit(() -> context.sendRequest(modbusTcpADU)
diff --git a/plc4j/tools/ui/frontend/project/src/generated/plc4j-tools-ui-frontend.ts b/plc4j/tools/ui/frontend/project/src/generated/plc4j-tools-ui-frontend.ts
index 7338daea03..8a6bf67a28 100644
--- a/plc4j/tools/ui/frontend/project/src/generated/plc4j-tools-ui-frontend.ts
+++ b/plc4j/tools/ui/frontend/project/src/generated/plc4j-tools-ui-frontend.ts
@@ -57,8 +57,8 @@ export interface ApplicationEvent extends EventObject {
 }
 
 export interface OptionMetadata {
-    options: Option[];
     requiredOptions: Option[];
+    options: Option[];
 }
 
 export interface EventObject extends Serializable {