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 <sru...@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())) {