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 2020/01/19 20:35:05 UTC
[plc4x] branch develop updated: - Continued working on the Modbus
driver
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 e22a83c - Continued working on the Modbus driver
e22a83c is described below
commit e22a83cb95b3028e1f0e7402b4fc674f6d24d5a3
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Sun Jan 19 21:34:57 2020 +0100
- Continued working on the Modbus driver
---
.../main/resources/protocols/modbus/modbus.mspec | 98 +++++++++++-----------
.../java/modbus/config/ModbusConfiguration.java | 26 ++++++
...teInputs.java => ModbusFieldDiscreteInput.java} | 9 +-
.../java/modbus/field/ModbusFieldHandler.java | 20 ++---
...isters.java => ModbusFieldHoldingRegister.java} | 9 +-
...egisters.java => ModbusFieldInputRegister.java} | 8 +-
.../modbus/field/ModbusFieldMaskWriteRegister.java | 9 +-
.../java/modbus/field/ModbusFieldRegister.java | 1 +
.../java/modbus/protocol/ModbusProtocolLogic.java | 83 ++++++++++++++++--
.../test/resources/testsuite/ModbusTestsuite.xml | 11 +--
10 files changed, 186 insertions(+), 88 deletions(-)
diff --git a/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec b/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
index cb3d44c..6347dda 100644
--- a/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
+++ b/protocols/modbus/src/main/resources/protocols/modbus/modbus.mspec
@@ -33,13 +33,13 @@
// The length field is a byte count of the following fields, including the Unit Identifier and
// data fields.
- [simple uint 16 'length']
+ [implicit uint 16 'length' 'pdu.lengthInBytes + 1']
// This field is used for intra-system routing purpose. It is typically used to communicate to
// a MODBUS+ or a MODBUS serial line slave through a gateway between an Ethernet TCP-IP network
// and a MODBUS serial line. This field is set by the MODBUS Client in the request and must be
// returned with the same value in the response by the server.
- [simple uint 8 'unitItendifier']
+ [simple uint 8 'unitIdentifier']
// The actual modbus payload
[simple ModbusPDU 'pdu' ['response']]
@@ -59,89 +59,89 @@
[implicit uint 7 'function' 'DISCRIMINATOR_VALUES[1]']
[implicit bit 'error' 'DISCRIMINATOR_VALUES[0]']
[typeSwitch 'error','function','response'
- ['true' ModbusPduError
+ ['true' ModbusPDUError
[simple uint 8 'exceptionCode']
]
// Bit Access
- ['false','0x02','false' ModbusPduReadDiscreteInputsRequest
+ ['false','0x02','false' ModbusPDUReadDiscreteInputsRequest
[simple uint 16 'startingAddress']
[simple uint 16 'quantity']
]
- ['false','0x02','true' ModbusPduReadDiscreteInputsResponse
+ ['false','0x02','true' ModbusPDUReadDiscreteInputsResponse
[implicit uint 8 'byteCount' 'COUNT(value)']
[array int 8 'value' count 'byteCount']
]
- ['false','0x01','false' ModbusPduReadCoilsRequest
+ ['false','0x01','false' ModbusPDUReadCoilsRequest
[simple uint 16 'startingAddress']
[simple uint 16 'quantity']
]
- ['false','0x01','true' ModbusPduReadCoilsResponse
+ ['false','0x01','true' ModbusPDUReadCoilsResponse
[implicit uint 8 'byteCount' 'COUNT(value)']
[array int 8 'value' count 'byteCount']
]
- ['false','0x05','false' ModbusPduWriteSingleCoilRequest
+ ['false','0x05','false' ModbusPDUWriteSingleCoilRequest
[simple uint 16 'address']
[simple uint 16 'value']
]
- ['false','0x05','true' ModbusPduWriteSingleCoilResponse
+ ['false','0x05','true' ModbusPDUWriteSingleCoilResponse
[simple uint 16 'address']
[simple uint 16 'value']
]
- ['false','0x0F','false' ModbusPduWriteMultipleCoilsRequest
+ ['false','0x0F','false' ModbusPDUWriteMultipleCoilsRequest
[simple uint 16 'startingAddress']
[simple uint 16 'quantity']
[implicit uint 8 'byteCount' 'COUNT(value)']
[array int 8 'value' count 'byteCount']
]
- ['false','0x0F','true' ModbusPduWriteMultipleCoilsResponse
+ ['false','0x0F','true' ModbusPDUWriteMultipleCoilsResponse
[simple uint 16 'startingAddress']
[simple uint 16 'quantity']
]
// Uint 16 Access (short)
- ['false','0x04','false' ModbusPduReadInputRegistersRequest
+ ['false','0x04','false' ModbusPDUReadInputRegistersRequest
[simple uint 16 'startingAddress']
[simple uint 16 'quantity']
]
- ['false','0x04','true' ModbusPduReadInputRegistersResponse
+ ['false','0x04','true' ModbusPDUReadInputRegistersResponse
[implicit uint 8 'byteCount' 'COUNT(value)']
[array int 8 'value' count 'byteCount']
]
- ['false','0x03','false' ModbusPduReadHoldingRegistersRequest
+ ['false','0x03','false' ModbusPDUReadHoldingRegistersRequest
[simple uint 16 'startingAddress']
[simple uint 16 'quantity']
]
- ['false','0x03','true' ModbusPduReadHoldingRegistersResponse
+ ['false','0x03','true' ModbusPDUReadHoldingRegistersResponse
[implicit uint 8 'byteCount' 'COUNT(value)']
[array int 8 'value' count 'byteCount']
]
- ['false','0x06','false' ModbusPduWriteSingleRegisterRequest
+ ['false','0x06','false' ModbusPDUWriteSingleRegisterRequest
[simple uint 16 'address']
[simple uint 16 'value']
]
- ['false','0x06','true' ModbusPduWriteSingleRegisterResponse
+ ['false','0x06','true' ModbusPDUWriteSingleRegisterResponse
[simple uint 16 'address']
[simple uint 16 'value']
]
- ['false','0x10','false' ModbusPduWriteMultipleRegistersRequest
+ ['false','0x10','false' ModbusPDUWriteMultipleRegistersRequest
[simple uint 16 'startingAddress']
[simple uint 16 'quantity']
[implicit uint 8 'byteCount' 'COUNT(value)']
[array int 8 'value' count 'byteCount']
]
- ['false','0x10','true' ModbusPduWriteMultipleRegistersResponse
+ ['false','0x10','true' ModbusPDUWriteMultipleRegistersResponse
[simple uint 16 'startingAddress']
[simple uint 16 'quantity']
]
- ['false','0x17','false' ModbusPduReadWriteMultipleRegistersRequest
+ ['false','0x17','false' ModbusPDUReadWriteMultipleRegistersRequest
[simple uint 16 'readStartingAddress']
[simple uint 16 'readQuantity']
[simple uint 16 'writeStartingAddress']
@@ -149,74 +149,74 @@
[implicit uint 8 'byteCount' 'COUNT(value)']
[array int 8 'value' count 'byteCount']
]
- ['false','0x17','true' ModbusPduReadWriteMultipleRegistersResponse
+ ['false','0x17','true' ModbusPDUReadWriteMultipleRegistersResponse
[implicit uint 8 'byteCount' 'COUNT(value)']
[array int 8 'value' count 'byteCount']
]
- ['false','0x16','false' ModbusPduMaskWriteRegisterRequest
+ ['false','0x16','false' ModbusPDUMaskWriteRegisterRequest
[simple uint 16 'referenceAddress']
[simple uint 16 'andMask']
[simple uint 16 'orMask']
]
- ['false','0x16','true' ModbusPduMaskWriteRegisterResponse
+ ['false','0x16','true' ModbusPDUMaskWriteRegisterResponse
[simple uint 16 'referenceAddress']
[simple uint 16 'andMask']
[simple uint 16 'orMask']
]
- ['false','0x18','false' ModbusPduReadFifoQueueRequest
+ ['false','0x18','false' ModbusPDUReadFifoQueueRequest
[simple uint 16 'fifoPointerAddress']
]
- ['false','0x18','true' ModbusPduReadFifoQueueResponse
+ ['false','0x18','true' ModbusPDUReadFifoQueueResponse
[implicit uint 16 'byteCount' '(COUNT(fifoValue) * 2) + 2']
[implicit uint 16 'fifoCount' '(COUNT(fifoValue) * 2) / 2']
[array uint 16 'fifoValue' count 'fifoCount']
]
// File Record Access
- ['false','0x14','false' ModbusPduReadFileRecordRequest
+ ['false','0x14','false' ModbusPDUReadFileRecordRequest
[implicit uint 8 'byteCount' 'ARRAY_SIZE_IN_BYTES(items)']
- [array ModbusPduReadFileRecordRequestItem 'items' length 'byteCount']
+ [array ModbusPDUReadFileRecordRequestItem 'items' length 'byteCount']
]
- ['false','0x14','true' ModbusPduReadFileRecordResponse
+ ['false','0x14','true' ModbusPDUReadFileRecordResponse
[implicit uint 8 'byteCount' 'ARRAY_SIZE_IN_BYTES(items)']
- [array ModbusPduReadFileRecordResponseItem 'items' length 'byteCount']
+ [array ModbusPDUReadFileRecordResponseItem 'items' length 'byteCount']
]
- ['false','0x15','false' ModbusPduWriteFileRecordRequest
+ ['false','0x15','false' ModbusPDUWriteFileRecordRequest
[implicit uint 8 'byteCount' 'ARRAY_SIZE_IN_BYTES(items)']
- [array ModbusPduWriteFileRecordRequestItem 'items' length 'byteCount']
+ [array ModbusPDUWriteFileRecordRequestItem 'items' length 'byteCount']
]
- ['false','0x15','true' ModbusPduWriteFileRecordResponse
+ ['false','0x15','true' ModbusPDUWriteFileRecordResponse
[implicit uint 8 'byteCount' 'ARRAY_SIZE_IN_BYTES(items)']
- [array ModbusPduWriteFileRecordResponseItem 'items' length 'byteCount']
+ [array ModbusPDUWriteFileRecordResponseItem 'items' length 'byteCount']
]
// Diagnostics (Serial Line Only)
- ['false','0x07','false' ModbusPduReadExceptionStatusRequest
+ ['false','0x07','false' ModbusPDUReadExceptionStatusRequest
]
- ['false','0x07','true' ModbusPduReadExceptionStatusResponse
+ ['false','0x07','true' ModbusPDUReadExceptionStatusResponse
[simple uint 8 'value']
]
- ['false','0x08','false' ModbusPduDiagnosticRequest
+ ['false','0x08','false' ModbusPDUDiagnosticRequest
// TODO: Implement the sub-request discriminated type [simple uint 8 'subfunction']
]
- ['false','0x08','true' ModbusPduDiagnosticResponse
+ ['false','0x08','true' ModbusPDUDiagnosticResponse
// TODO: Implement the sub-request discriminated type [simple uint 8 'subfunction']
]
- ['false','0x0B','false' ModbusPduGetComEventCounterRequest
+ ['false','0x0B','false' ModbusPDUGetComEventCounterRequest
]
- ['false','0x0B','true' ModbusPduGetComEventCounterResponse
+ ['false','0x0B','true' ModbusPDUGetComEventCounterResponse
[simple uint 16 'status']
[simple uint 16 'eventCount']
]
- ['false','0x0C','false' ModbusPduGetComEventLogRequest
+ ['false','0x0C','false' ModbusPDUGetComEventLogRequest
]
- ['false','0x0C','true' ModbusPduGetComEventLogResponse
+ ['false','0x0C','true' ModbusPDUGetComEventLogResponse
[implicit uint 8 'byteCount' 'COUNT(events) + 6']
[simple uint 16 'status']
[simple uint 16 'eventCount']
@@ -224,35 +224,35 @@
[array int 8 'events' count 'byteCount - 6']
]
- ['false','0x11','false' ModbusPduReportServerIdRequest
+ ['false','0x11','false' ModbusPDUReportServerIdRequest
]
- ['false','0x11','true' ModbusPduReportServerIdResponse
+ ['false','0x11','true' ModbusPDUReportServerIdResponse
// TODO: This is not specified very well in the spec ... investigate.
[implicit uint 8 'byteCount' 'COUNT(value)']
[array int 8 'value' count 'byteCount']
]
- ['false','0x2B','false' ModbusPduReadDeviceIdentificationRequest
+ ['false','0x2B','false' ModbusPDUReadDeviceIdentificationRequest
]
- ['false','0x2B','true' ModbusPduReadDeviceIdentificationResponse
+ ['false','0x2B','true' ModbusPDUReadDeviceIdentificationResponse
]
]
]
-[type 'ModbusPduReadFileRecordRequestItem'
+[type 'ModbusPDUReadFileRecordRequestItem'
[simple uint 8 'referenceType']
[simple uint 16 'fileNumber']
[simple uint 16 'recordNumber']
[simple uint 16 'recordLength']
]
-[type 'ModbusPduReadFileRecordResponseItem'
+[type 'ModbusPDUReadFileRecordResponseItem'
[implicit uint 8 'dataLength' '(COUNT(data) * 2) + 1']
[simple uint 8 'referenceType']
[array uint 16 'data' length 'dataLength - 1']
]
-[type 'ModbusPduWriteFileRecordRequestItem'
+[type 'ModbusPDUWriteFileRecordRequestItem'
[simple uint 8 'referenceType']
[simple uint 16 'fileNumber']
[simple uint 16 'recordNumber']
@@ -260,7 +260,7 @@
[array uint 16 'recordData' length 'recordLength * 2']
]
-[type 'ModbusPduWriteFileRecordResponseItem'
+[type 'ModbusPDUWriteFileRecordResponseItem'
[simple uint 8 'referenceType']
[simple uint 16 'fileNumber']
[simple uint 16 'recordNumber']
diff --git a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/config/ModbusConfiguration.java b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/config/ModbusConfiguration.java
index d8465ed..1cf97df 100644
--- a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/config/ModbusConfiguration.java
+++ b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/config/ModbusConfiguration.java
@@ -20,10 +20,36 @@ package org.apache.plc4x.java.modbus.config;
import org.apache.plc4x.java.modbus.readwrite.ModbusConstants;
import org.apache.plc4x.java.spi.configuration.Configuration;
+import org.apache.plc4x.java.spi.configuration.annotations.ConfigurationParameter;
+import org.apache.plc4x.java.spi.configuration.annotations.defaults.IntDefaultValue;
import org.apache.plc4x.java.transport.tcp.TcpTransportConfiguration;
public class ModbusConfiguration implements Configuration, TcpTransportConfiguration {
+ @ConfigurationParameter("request-timeout")
+ @IntDefaultValue(10_000)
+ private int requestTimeout;
+
+ @ConfigurationParameter("unit-identifier")
+ @IntDefaultValue(1)
+ private int unitIdentifier;
+
+ public int getRequestTimeout() {
+ return requestTimeout;
+ }
+
+ public void setRequestTimeout(int requestTimeout) {
+ this.requestTimeout = requestTimeout;
+ }
+
+ public int getUnitIdentifier() {
+ return unitIdentifier;
+ }
+
+ public void setUnitIdentifier(int unitIdentifier) {
+ this.unitIdentifier = unitIdentifier;
+ }
+
@Override
public int getDefaultPort() {
return ModbusConstants.MODBUSTCPDEFAULTPORT;
diff --git a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldReadDiscreteInputs.java b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldDiscreteInput.java
similarity index 83%
rename from sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldReadDiscreteInputs.java
rename to sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldDiscreteInput.java
index 49ffbe0..0ccdbf5 100644
--- a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldReadDiscreteInputs.java
+++ b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldDiscreteInput.java
@@ -23,15 +23,15 @@ import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-public class ModbusFieldReadDiscreteInputs extends ModbusField {
+public class ModbusFieldDiscreteInput extends ModbusField {
public static final Pattern ADDRESS_PATTERN = Pattern.compile("readdiscreteinputs:" + ModbusField.ADDRESS_PATTERN);
- public ModbusFieldReadDiscreteInputs(int address, Integer quantity) {
+ public ModbusFieldDiscreteInput(int address, Integer quantity) {
super(address, quantity);
}
- public static ModbusFieldReadDiscreteInputs of(String addressString) throws PlcInvalidFieldException {
+ public static ModbusFieldDiscreteInput of(String addressString) throws PlcInvalidFieldException {
Matcher matcher = ADDRESS_PATTERN.matcher(addressString);
if (!matcher.matches()) {
throw new PlcInvalidFieldException(addressString, ADDRESS_PATTERN);
@@ -40,6 +40,7 @@ public class ModbusFieldReadDiscreteInputs extends ModbusField {
String quantityString = matcher.group("quantity");
Integer quantity = quantityString != null ? Integer.valueOf(quantityString) : null;
- return new ModbusFieldReadDiscreteInputs(address, quantity);
+ return new ModbusFieldDiscreteInput(address, quantity);
}
+
}
diff --git a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldHandler.java b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldHandler.java
index 6f5b9d9..1ea13a1 100644
--- a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldHandler.java
+++ b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldHandler.java
@@ -19,18 +19,10 @@ under the License.
package org.apache.plc4x.java.modbus.field;
import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
-import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
import org.apache.plc4x.java.api.model.PlcField;
import org.apache.plc4x.java.api.value.*;
import org.apache.plc4x.java.spi.connection.DefaultPlcFieldHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.math.BigInteger;
-import java.nio.charset.StandardCharsets;
-import java.time.LocalDate;
-import java.time.LocalDateTime;
-import java.time.LocalTime;
-import java.util.Arrays;
import java.util.BitSet;
import java.util.LinkedList;
import java.util.List;
@@ -41,12 +33,12 @@ public class ModbusFieldHandler extends DefaultPlcFieldHandler {
public PlcField createField(String fieldQuery) throws PlcInvalidFieldException {
if (ModbusFieldMaskWriteRegister.ADDRESS_PATTERN.matcher(fieldQuery).matches()) {
return ModbusFieldMaskWriteRegister.of(fieldQuery);
- } else if (ModbusFieldReadDiscreteInputs.ADDRESS_PATTERN.matcher(fieldQuery).matches()) {
- return ModbusFieldReadDiscreteInputs.of(fieldQuery);
- } else if (ModbusFieldReadHoldingRegisters.ADDRESS_PATTERN.matcher(fieldQuery).matches()) {
- return ModbusFieldReadHoldingRegisters.of(fieldQuery);
- } else if (ModbusFieldReadInputRegisters.ADDRESS_PATTERN.matcher(fieldQuery).matches()) {
- return ModbusFieldReadInputRegisters.of(fieldQuery);
+ } else if (ModbusFieldDiscreteInput.ADDRESS_PATTERN.matcher(fieldQuery).matches()) {
+ return ModbusFieldDiscreteInput.of(fieldQuery);
+ } else if (ModbusFieldHoldingRegister.ADDRESS_PATTERN.matcher(fieldQuery).matches()) {
+ return ModbusFieldHoldingRegister.of(fieldQuery);
+ } else if (ModbusFieldInputRegister.ADDRESS_PATTERN.matcher(fieldQuery).matches()) {
+ return ModbusFieldInputRegister.of(fieldQuery);
} else if (ModbusFieldCoil.ADDRESS_PATTERN.matcher(fieldQuery).matches()) {
return ModbusFieldCoil.of(fieldQuery);
} else if (ModbusFieldRegister.ADDRESS_PATTERN.matcher(fieldQuery).matches()) {
diff --git a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldReadHoldingRegisters.java b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldHoldingRegister.java
similarity index 82%
rename from sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldReadHoldingRegisters.java
rename to sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldHoldingRegister.java
index f0fe335..7d2cba3 100644
--- a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldReadHoldingRegisters.java
+++ b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldHoldingRegister.java
@@ -23,15 +23,15 @@ import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-public class ModbusFieldReadHoldingRegisters extends ModbusField {
+public class ModbusFieldHoldingRegister extends ModbusField {
public static final Pattern ADDRESS_PATTERN = Pattern.compile("readholdingregisters:" + ModbusField.ADDRESS_PATTERN);
- protected ModbusFieldReadHoldingRegisters(int address, Integer quantity) {
+ protected ModbusFieldHoldingRegister(int address, Integer quantity) {
super(address, quantity);
}
- public static ModbusFieldReadHoldingRegisters of(String addressString) throws PlcInvalidFieldException {
+ public static ModbusFieldHoldingRegister of(String addressString) throws PlcInvalidFieldException {
Matcher matcher = ADDRESS_PATTERN.matcher(addressString);
if (!matcher.matches()) {
throw new PlcInvalidFieldException(addressString, ADDRESS_PATTERN);
@@ -40,6 +40,7 @@ public class ModbusFieldReadHoldingRegisters extends ModbusField {
String quantityString = matcher.group("quantity");
Integer quantity = quantityString != null ? Integer.valueOf(quantityString) : null;
- return new ModbusFieldReadHoldingRegisters(address, quantity);
+ return new ModbusFieldHoldingRegister(address, quantity);
}
+
}
diff --git a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldReadInputRegisters.java b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldInputRegister.java
similarity index 82%
rename from sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldReadInputRegisters.java
rename to sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldInputRegister.java
index b63685d..1185554 100644
--- a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldReadInputRegisters.java
+++ b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldInputRegister.java
@@ -23,15 +23,15 @@ import org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-public class ModbusFieldReadInputRegisters extends ModbusField {
+public class ModbusFieldInputRegister extends ModbusField {
public static final Pattern ADDRESS_PATTERN = Pattern.compile("readinputregisters:" + ModbusField.ADDRESS_PATTERN);
- protected ModbusFieldReadInputRegisters(int address, Integer quantity) {
+ protected ModbusFieldInputRegister(int address, Integer quantity) {
super(address, quantity);
}
- public static ModbusFieldReadInputRegisters of(String addressString) throws PlcInvalidFieldException {
+ public static ModbusFieldInputRegister of(String addressString) throws PlcInvalidFieldException {
Matcher matcher = ADDRESS_PATTERN.matcher(addressString);
if (!matcher.matches()) {
throw new PlcInvalidFieldException(addressString, ADDRESS_PATTERN);
@@ -40,6 +40,6 @@ public class ModbusFieldReadInputRegisters extends ModbusField {
String quantityString = matcher.group("quantity");
Integer quantity = quantityString != null ? Integer.valueOf(quantityString) : null;
- return new ModbusFieldReadInputRegisters(address, quantity);
+ return new ModbusFieldInputRegister(address, quantity);
}
}
diff --git a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldMaskWriteRegister.java b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldMaskWriteRegister.java
index 4f714e6..5ad9f09 100644
--- a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldMaskWriteRegister.java
+++ b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldMaskWriteRegister.java
@@ -24,6 +24,13 @@ import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+/**
+ * This is not really an address, but a different type of operation.
+ * Perhaps in the future we will use this in order to send optimized requests,
+ * but for now it shouldn't be used and is just implemented for the sake of
+ * completeness.
+ */
+@Deprecated
public class ModbusFieldMaskWriteRegister extends ModbusField {
public static final Pattern ADDRESS_PATTERN = Pattern.compile("maskwrite:" + ModbusField.ADDRESS_PATTERN + "/" + "(?<andMask>\\d+)/(?<orMask>\\d+)");
@@ -77,7 +84,6 @@ public class ModbusFieldMaskWriteRegister extends ModbusField {
@Override
public int hashCode() {
-
return Objects.hash(super.hashCode(), andMask, orMask);
}
@@ -88,4 +94,5 @@ public class ModbusFieldMaskWriteRegister extends ModbusField {
", orMask=" + orMask +
"} " + super.toString();
}
+
}
diff --git a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldRegister.java b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldRegister.java
index 6fe1bb4..10da1ee 100644
--- a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldRegister.java
+++ b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/field/ModbusFieldRegister.java
@@ -43,4 +43,5 @@ public class ModbusFieldRegister extends ModbusField {
Integer quantity = quantityString != null ? Integer.valueOf(quantityString) : null;
return new ModbusFieldRegister(address, quantity);
}
+
}
diff --git a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java
index 01b2575..796c542 100644
--- a/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java
+++ b/sandbox/test-java-modbus-driver/src/main/java/org/apache/plc4x/java/modbus/protocol/ModbusProtocolLogic.java
@@ -22,36 +22,109 @@ import org.apache.plc4x.java.api.messages.PlcReadRequest;
import org.apache.plc4x.java.api.messages.PlcReadResponse;
import org.apache.plc4x.java.api.messages.PlcWriteRequest;
import org.apache.plc4x.java.api.messages.PlcWriteResponse;
+import org.apache.plc4x.java.api.model.PlcField;
import org.apache.plc4x.java.modbus.config.ModbusConfiguration;
-import org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU;
+import org.apache.plc4x.java.modbus.field.ModbusFieldCoil;
+import org.apache.plc4x.java.modbus.field.ModbusFieldDiscreteInput;
+import org.apache.plc4x.java.modbus.field.ModbusFieldHoldingRegister;
+import org.apache.plc4x.java.modbus.field.ModbusFieldInputRegister;
+import org.apache.plc4x.java.modbus.readwrite.*;
import org.apache.plc4x.java.spi.ConversationContext;
import org.apache.plc4x.java.spi.Plc4xProtocolBase;
import org.apache.plc4x.java.spi.configuration.HasConfiguration;
+import org.apache.plc4x.java.spi.messages.DefaultPlcReadRequest;
+import org.apache.plc4x.java.spi.optimizer.RequestTransactionManager;
+import java.time.Duration;
import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.atomic.AtomicInteger;
public class ModbusProtocolLogic extends Plc4xProtocolBase<ModbusTcpADU> implements HasConfiguration<ModbusConfiguration> {
- private ModbusConfiguration configuration;
+ private Duration requestTimeout;
+ private short unitIdentifier;
+ private RequestTransactionManager tm;
+ private AtomicInteger transactionIdentifierGenerator = new AtomicInteger(10);
@Override
public void setConfiguration(ModbusConfiguration configuration) {
- this.configuration = configuration;
+ this.requestTimeout = Duration.ofMillis(configuration.getRequestTimeout());
+ this.unitIdentifier = (short) configuration.getUnitIdentifier();
+ this.tm = new RequestTransactionManager(1);
+ this.transactionIdentifierGenerator = new AtomicInteger(10);
}
@Override
public void close(ConversationContext<ModbusTcpADU> context) {
-
+ // Nothing to do here ...
}
@Override
public CompletableFuture<PlcReadResponse> read(PlcReadRequest readRequest) {
- return super.read(readRequest);
+ CompletableFuture<PlcReadResponse> future = new CompletableFuture<>();
+ DefaultPlcReadRequest request = (DefaultPlcReadRequest) readRequest;
+
+ // 1. Sort all items by type:
+ // - DiscreteInput (read-only) --> ModbusPduReadDiscreteInputsRequest
+ // - Coil (read-write) --> ModbusPduReadCoilsRequest
+ // - InputRegister (read-only) --> ModbusPduReadInputRegistersRequest
+ // - HoldingRegister (read-write) --> ModbusPduReadHoldingRegistersRequest
+ // - FifoQueue (read-only) --> ModbusPduReadFifoQueueRequest
+ // - FileRecord (read-write) --> ModbusPduReadFileRecordRequest
+ // 2. Split up into multiple sub-requests
+
+ // Example for sending a request ...
+ // TODO: Break down multiple items into sub-futures that are acknowledged at the end
+ for (PlcField field : request.getFields()) {
+ ModbusPDU requestPdu = getRequestPdu(field);
+ int transactionIdentifier = transactionIdentifierGenerator.getAndIncrement();
+ ModbusTcpADU modbusTcpADU = new ModbusTcpADU(transactionIdentifier, unitIdentifier, requestPdu);
+ RequestTransactionManager.RequestTransaction transaction = tm.startRequest();
+ transaction.submit(() -> context.sendRequest(modbusTcpADU)
+ .expectResponse(ModbusTcpADU.class, requestTimeout)
+ .onTimeout(future::completeExceptionally)
+ .onError((p, e) -> future.completeExceptionally(e))
+ .check(p -> p.getTransactionIdentifier() == transactionIdentifier)
+ .unwrap(ModbusTcpADU::getPdu)
+ .handle(p -> {
+ // TODO: Do something sensible with the response ...
+ //future.complete(p);
+ // Finish the request-transaction.
+ transaction.endRequest();
+ }));
+ }
+ // TODO: Merge all the sub-futures to one big response.
+ return future;
}
@Override
public CompletableFuture<PlcWriteResponse> write(PlcWriteRequest writeRequest) {
+ // 1. Sort all items by type:
+ // - DiscreteInput (read-only) --> Error
+ // - Coil (read-write) --> ModbusPduWriteSingleCoilRequest / ModbusPduWriteMultipleCoilsRequest
+ // - InputRegister (read-only) --> Error
+ // - HoldingRegister (read-write) --> ModbusPduWriteSingleRegisterRequest / ModbusPduWriteMultipleRegistersRequest
+ // - FifoQueue (read-only) --> Error
+ // - FileRecord (read-write) --> ModbusPduWriteFileRecordRequest
+ // 2. Split up into multiple sub-requests
return super.write(writeRequest);
}
+ private ModbusPDU getRequestPdu(PlcField field) {
+ if(field instanceof ModbusFieldDiscreteInput) {
+ ModbusFieldDiscreteInput discreteInput = (ModbusFieldDiscreteInput) field;
+ return new ModbusPDUReadDiscreteInputsRequest(discreteInput.getAddress(), discreteInput.getQuantity());
+ } else if(field instanceof ModbusFieldCoil) {
+ ModbusFieldCoil coil = (ModbusFieldCoil) field;
+ return new ModbusPDUReadCoilsRequest(coil.getAddress(), coil.getQuantity());
+ } else if(field instanceof ModbusFieldInputRegister) {
+ ModbusFieldInputRegister inputRegister = (ModbusFieldInputRegister) field;
+ return new ModbusPDUReadInputRegistersRequest(inputRegister.getAddress(), inputRegister.getQuantity());
+ } else if(field instanceof ModbusFieldHoldingRegister) {
+ ModbusFieldHoldingRegister holdingRegister = (ModbusFieldHoldingRegister) field;
+ return new ModbusPDUReadHoldingRegistersRequest(holdingRegister.getAddress(), holdingRegister.getQuantity());
+ }
+ throw new RuntimeException("Unsupported field type " + field.getClass().getName());
+ }
+
}
diff --git a/sandbox/test-java-modbus-driver/src/test/resources/testsuite/ModbusTestsuite.xml b/sandbox/test-java-modbus-driver/src/test/resources/testsuite/ModbusTestsuite.xml
index 9fccfc3..7befd30 100644
--- a/sandbox/test-java-modbus-driver/src/test/resources/testsuite/ModbusTestsuite.xml
+++ b/sandbox/test-java-modbus-driver/src/test/resources/testsuite/ModbusTestsuite.xml
@@ -31,9 +31,8 @@
<xml>
<ModbusTcpADU className="org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU">
<transactionIdentifier>0</transactionIdentifier>
- <length>6</length>
- <unitItendifier>255</unitItendifier>
- <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPduReadDiscreteInputsRequest">
+ <unitIdentifier>255</unitIdentifier>
+ <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadDiscreteInputsRequest">
<startingAddress>2258</startingAddress>
<quantity>2</quantity>
</pdu>
@@ -51,9 +50,8 @@
<xml>
<ModbusTcpADU className="org.apache.plc4x.java.modbus.readwrite.ModbusTcpADU">
<transactionIdentifier>31998</transactionIdentifier>
- <length>201</length>
- <unitItendifier>255</unitItendifier>
- <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPduReadDiscreteInputsResponse">
+ <unitIdentifier>255</unitIdentifier>
+ <pdu className="org.apache.plc4x.java.modbus.readwrite.ModbusPDUReadDiscreteInputsResponse">
<value>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABAAAAAAAAAAAAAAAAAAAAdsAAAHWAABKOAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGRhaW0AbgAAAAAAAAAAAAAAAAAAMDEAMAAAAAAAAAAAAAAA
@@ -63,5 +61,4 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</value>
</xml>
</testcase>
-
</test:testsuite>
\ No newline at end of file