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 {