You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2018/07/26 13:48:05 UTC
[incubator-plc4x] branch master updated: added support for float
and double in modbus
This is an automated email from the ASF dual-hosted git repository.
sruehl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-plc4x.git
The following commit(s) were added to refs/heads/master by this push:
new 947579f added support for float and double in modbus
947579f is described below
commit 947579fe4c654df0a68d044bc85d84428c23f5b3
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Thu Jul 26 15:48:02 2018 +0200
added support for float and double in modbus
---
.../base/protocol/Plc4XSupportedDataTypes.java | 2 +-
.../java/modbus/netty/Plc4XModbusProtocol.java | 58 ++++++++++++++++++++--
.../java/modbus/netty/Plc4XModbusProtocolTest.java | 17 ++++++-
3 files changed, 71 insertions(+), 6 deletions(-)
diff --git a/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/protocol/Plc4XSupportedDataTypes.java b/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/protocol/Plc4XSupportedDataTypes.java
index f0c966c..f3ee07b 100644
--- a/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/protocol/Plc4XSupportedDataTypes.java
+++ b/plc4j/protocols/driver-bases/test/src/main/java/org/apache/plc4x/java/base/protocol/Plc4XSupportedDataTypes.java
@@ -171,7 +171,7 @@ public class Plc4XSupportedDataTypes {
this.dataTypePair = dataTypePair;
}
- private static <T extends Serializable> DataTypePair<T> of(T value, byte[] bytes) {
+ public static <T extends Serializable> DataTypePair<T> of(T value, byte[] bytes) {
return new DataTypePair<>(ImmutablePair.of(value, bytes));
}
diff --git a/plc4j/protocols/modbus/src/main/java/org/apache/plc4x/java/modbus/netty/Plc4XModbusProtocol.java b/plc4j/protocols/modbus/src/main/java/org/apache/plc4x/java/modbus/netty/Plc4XModbusProtocol.java
index 769d17d..cc9655f 100644
--- a/plc4j/protocols/modbus/src/main/java/org/apache/plc4x/java/modbus/netty/Plc4XModbusProtocol.java
+++ b/plc4j/protocols/modbus/src/main/java/org/apache/plc4x/java/modbus/netty/Plc4XModbusProtocol.java
@@ -262,6 +262,8 @@ public class Plc4XModbusProtocol extends MessageToMessageCodec<ModbusTcpPayload,
&& !(value instanceof Short)
&& !(value instanceof Integer)
&& !(value instanceof BigInteger)
+ && !(value instanceof Float)
+ && !(value instanceof Double)
) {
throw new PlcRuntimeException("Unsupported datatype detected " + value.getClass());
}
@@ -315,6 +317,12 @@ public class Plc4XModbusProtocol extends MessageToMessageCodec<ModbusTcpPayload,
coilSet = (int) value == 1;
} else if (value.getClass() == BigInteger.class) {
coilSet = value.equals(BigInteger.ONE);
+ } else if (value.getClass() == Float.class) {
+ coilSet = value.equals(1.0f);
+ } else if (value.getClass() == Double.class) {
+ coilSet = value.equals(1.0d);
+ } else {
+ throw new PlcRuntimeException("Unsupported datatype detected " + value.getClass());
}
byte coilToSet = (coilSet ? (byte) 1 : (byte) 0);
actualCoil = (byte) (actualCoil | coilToSet << i);
@@ -354,7 +362,7 @@ public class Plc4XModbusProtocol extends MessageToMessageCodec<ModbusTcpPayload,
buffer.writeShort((short) value);
} else if (value.getClass() == Integer.class) {
if ((int) value > Integer.MAX_VALUE) {
- throw new PlcProtocolException("Value to high to fit into register: " + value);
+ throw new PlcProtocolException("Value to high to fit into register for Integer: " + value);
}
if ((int) value < 0) {
throw new PlcProtocolException("Only positive values are supported for Integer: " + value);
@@ -365,11 +373,11 @@ public class Plc4XModbusProtocol extends MessageToMessageCodec<ModbusTcpPayload,
throw new PlcProtocolException("Only positive values are supported for BigInteger: " + value);
}
if (((BigInteger) value).compareTo(BigInteger.valueOf(0XFFFF_FFFFL)) > 0) {
- throw new PlcProtocolException("Value to high to fit into register: " + value);
+ throw new PlcProtocolException("Value to high to fit into register for BigInteger: " + value);
}
// TODO: for now we can't support big values as we only write one register at once
if (((BigInteger) value).compareTo(BigInteger.valueOf(0XFFFFL)) > 0) {
- throw new PlcProtocolException("Value to high to fit into register: " + value);
+ throw new PlcProtocolException("Value to high to fit into register for BigInteger: " + value);
}
// TODO: Register has 2 bytes so we trim to 2 instead of 4 like the second if above
int maxBytes = 2;
@@ -383,6 +391,24 @@ public class Plc4XModbusProtocol extends MessageToMessageCodec<ModbusTcpPayload,
// TODO: check if this is a good representation.
// TODO: can a big integer span multiple registers?
buffer.writeBytes(bytes);
+ } else if (value.getClass() == Float.class) {
+ if (((float) value) < 0) {
+ throw new PlcProtocolException("Only positive values are supported for Float: " + value);
+ }
+ if (((float) value) > Integer.MAX_VALUE) {
+ throw new PlcProtocolException("Value to high to fit into register for Float: " + value);
+ }
+ buffer.writeShort(Math.round((float) value));
+ } else if (value.getClass() == Double.class) {
+ if (((double) value) < 0) {
+ throw new PlcProtocolException("Only positive values are supported for Double: " + value);
+ }
+ if (((double) value) > Integer.MAX_VALUE) {
+ throw new PlcProtocolException("Value to high to fit into register for Double: " + value);
+ }
+ buffer.writeShort((int) Math.round((double) value));
+ } else {
+ throw new PlcRuntimeException("Unsupported datatype detected " + value.getClass());
}
}
byte[] result = new byte[buffer.writerIndex()];
@@ -431,6 +457,16 @@ public class Plc4XModbusProtocol extends MessageToMessageCodec<ModbusTcpPayload,
@SuppressWarnings("unchecked")
T itemToBeAdded = (T) BigInteger.valueOf(coilFlag);
data.add(itemToBeAdded);
+ } else if (dataType == Float.class) {
+ @SuppressWarnings("unchecked")
+ T itemToBeAdded = (T) Float.valueOf(coilFlag);
+ data.add(itemToBeAdded);
+ } else if (dataType == Double.class) {
+ @SuppressWarnings("unchecked")
+ T itemToBeAdded = (T) Double.valueOf(coilFlag);
+ data.add(itemToBeAdded);
+ } else {
+ throw new PlcRuntimeException("Unsupported datatype detected " + dataType);
}
}
return data;
@@ -483,6 +519,22 @@ public class Plc4XModbusProtocol extends MessageToMessageCodec<ModbusTcpPayload,
@SuppressWarnings("unchecked")
T itemToBeAdded = (T) new BigInteger(register);
data.add(itemToBeAdded);
+ } else if (dataType == Float.class) {
+ if (intValue < 0) {
+ throw new PlcProtocolException("BigInteger underflow: " + intValue);
+ }
+ @SuppressWarnings("unchecked")
+ T itemToBeAdded = (T) new Float(intValue);
+ data.add(itemToBeAdded);
+ } else if (dataType == Double.class) {
+ if (intValue < 0) {
+ throw new PlcProtocolException("BigInteger underflow: " + intValue);
+ }
+ @SuppressWarnings("unchecked")
+ T itemToBeAdded = (T) new Double(intValue);
+ data.add(itemToBeAdded);
+ } else {
+ throw new PlcRuntimeException("Unsupported datatype detected " + dataType);
}
}
return data;
diff --git a/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/netty/Plc4XModbusProtocolTest.java b/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/netty/Plc4XModbusProtocolTest.java
index 12944e3..5adea46 100644
--- a/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/netty/Plc4XModbusProtocolTest.java
+++ b/plc4j/protocols/modbus/src/test/java/org/apache/plc4x/java/modbus/netty/Plc4XModbusProtocolTest.java
@@ -31,6 +31,7 @@ import org.apache.plc4x.java.api.messages.items.ResponseItem;
import org.apache.plc4x.java.api.messages.items.WriteResponseItem;
import org.apache.plc4x.java.api.model.Address;
import org.apache.plc4x.java.api.types.ResponseCode;
+import org.apache.plc4x.java.base.protocol.Plc4XSupportedDataTypes;
import org.apache.plc4x.java.modbus.model.*;
import org.junit.Before;
import org.junit.Rule;
@@ -70,8 +71,6 @@ public class Plc4XModbusProtocolTest {
// TODO: implement these types
private List<String> notYetSupportedDataType = Stream.of(
GregorianCalendar.class,
- Float.class,
- Double.class,
String.class,
byte[].class,
Byte[].class
@@ -98,6 +97,16 @@ public class Plc4XModbusProtocolTest {
@Parameterized.Parameters(name = "{index} Type:{0} {3} {5}")
public static Collection<Object[]> data() {
return streamOfBigEndianDataTypePairs()
+ // Float and Double getting truncated in modbus.
+ .map(dataTypePair -> {
+ if (dataTypePair.getDataTypeClass() == Float.class) {
+ return Plc4XSupportedDataTypes.DataTypePair.of(1f, new byte[]{0x0, 0x1});
+ } else if (dataTypePair.getDataTypeClass() == Double.class) {
+ return Plc4XSupportedDataTypes.DataTypePair.of(1d, new byte[]{0x0, 0x1});
+ } else {
+ return dataTypePair;
+ }
+ })
.map(dataTypePair -> Stream.of(
producePair(dataTypePair.getDataTypeClass(), CoilModbusAddress.of("coil:1"), new ReadCoilsResponse(Unpooled.wrappedBuffer(new byte[]{(byte) 0x1}))),
producePair(CoilModbusAddress.of("coil:1"), new WriteSingleCoilResponse(1, 1), dataTypePair.getValue()),
@@ -290,6 +299,8 @@ public class Plc4XModbusProtocolTest {
assertThat(coilValue, equalTo(true));
} else if (payloadClazzName.equals(Float.class.getSimpleName())) {
assertThat(coilValue, equalTo(true));
+ } else if (payloadClazzName.equals(Double.class.getSimpleName())) {
+ assertThat(coilValue, equalTo(true));
} else if (payloadClazzName.equals(Integer.class.getSimpleName())) {
assertThat(coilValue, equalTo(true));
} else if (payloadClazzName.equals(BigInteger.class.getSimpleName())) {
@@ -312,6 +323,8 @@ public class Plc4XModbusProtocolTest {
assertThat(value, equalTo(1));
} else if (payloadClazzName.equals(Float.class.getSimpleName())) {
assertThat(value, equalTo(1));
+ } else if (payloadClazzName.equals(Double.class.getSimpleName())) {
+ assertThat(value, equalTo(1));
} else if (payloadClazzName.equals(Integer.class.getSimpleName())) {
assertThat(value, equalTo(1));
} else if (payloadClazzName.equals(BigInteger.class.getSimpleName())) {