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
commit c0b3745bf6941f16a248cd16dc2a12d1fa280b7a Author: Sebastian Rühl <sru...@apache.org> AuthorDate: Thu Jul 26 16:30:02 2018 +0200 added double support to S7 --- .../plc4x/java/s7/netty/Plc4XS7Protocol.java | 16 ++++++++------ .../plc4x/java/s7/netty/util/S7TypeDecoder.java | 25 ++++++++++++++++++---- .../plc4x/java/s7/netty/Plc4XS7ProtocolTest.java | 8 +++++-- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java index 7ef1f2d..1aa4c5f 100644 --- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java +++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/Plc4XS7Protocol.java @@ -89,17 +89,17 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ * correlates needs to be notified about the problem. If a container is found, we can relay the * exception to that by calling completeExceptionally and passing in the exception. * - * @param ctx the current protocol layers context + * @param ctx the current protocol layers context * @param cause the exception that was caught * @throws Exception throws an exception if something goes wrong internally */ @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - if(cause instanceof PlcProtocolPayloadTooBigException) { + if (cause instanceof PlcProtocolPayloadTooBigException) { PlcProtocolPayloadTooBigException pptbe = (PlcProtocolPayloadTooBigException) cause; - if(pptbe.getPayload() instanceof S7RequestMessage) { + if (pptbe.getPayload() instanceof S7RequestMessage) { S7RequestMessage request = (S7RequestMessage) pptbe.getPayload(); - if(request.getParent() instanceof PlcRequestContainer) { + if (request.getParent() instanceof PlcRequestContainer) { PlcRequestContainer requestContainer = (PlcRequestContainer) request.getParent(); // Remove the current request from the unconfirmed requests list. @@ -108,8 +108,8 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ requestContainer.getResponseFuture().completeExceptionally(cause); } } - } else if((cause instanceof IOException) && (cause.getMessage().contains("Connection reset by peer") || - cause.getMessage().contains("Operation timed out"))) { + } else if ((cause instanceof IOException) && (cause.getMessage().contains("Connection reset by peer") || + cause.getMessage().contains("Operation timed out"))) { String reason = cause.getMessage().contains("Connection reset by peer") ? "Connection terminated unexpectedly" : "Remote host not responding"; if (!requests.isEmpty()) { @@ -249,6 +249,8 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ return TransportSize.DATE_AND_TIME; } else if (datatype == Float.class) { return TransportSize.REAL; + } else if (datatype == Double.class) { + return TransportSize.REAL; } else if (datatype == Integer.class) { return TransportSize.DWORD; } else if (datatype == String.class) { @@ -269,6 +271,8 @@ public class Plc4XS7Protocol extends PlcMessageToMessageCodec<S7Message, PlcRequ return null; } else if (datatype == Float.class) { return DataTransportSize.REAL; + } else if (datatype == Double.class) { + return DataTransportSize.REAL; } else if (datatype == Integer.class) { return DataTransportSize.BYTE_WORD_DWORD; } else if (datatype == String.class) { diff --git a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/util/S7TypeDecoder.java b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/util/S7TypeDecoder.java index bd0ef97..08b5c91 100644 --- a/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/util/S7TypeDecoder.java +++ b/plc4j/protocols/s7/src/main/java/org/apache/plc4x/java/s7/netty/util/S7TypeDecoder.java @@ -54,18 +54,35 @@ public class S7TypeDecoder { // Description of the Real number format: // https://www.sps-lehrgang.de/zahlenformate-step7/#c144 // https://de.wikipedia.org/wiki/IEEE_754 - int intValue = ((s7Data[i] & 0xff) << 24) | ((s7Data[i + 1] & 0xff) << 16) | - ((s7Data[i + 2] & 0xff) << 8) | (s7Data[i + 3] & 0xff); + int intValue = ((s7Data[i] & 0xff) << 24) + | ((s7Data[i + 1] & 0xff) << 16) + | ((s7Data[i + 2] & 0xff) << 8) + | (s7Data[i + 3] & 0xff); result.add(Float.intBitsToFloat(intValue)); i += 4; + } else if (datatype == Double.class) { + // Description of the Real number format: + // https://www.sps-lehrgang.de/zahlenformate-step7/#c144 + // https://de.wikipedia.org/wiki/IEEE_754 + long longValue = (((long) (s7Data[i] & 0xff)) << 56) + | (((long) (s7Data[i] & 0xff)) << 48) + | (((long) (s7Data[i + 1] & 0xff)) << 40) + | (((long) (s7Data[i + 2] & 0xff)) << 32) + + | (((long) (s7Data[i + 3] & 0xff)) << 24) + | (((long) (s7Data[i + 4] & 0xff)) << 16) + | (((long) (s7Data[i + 5] & 0xff)) << 8) + | (((long) s7Data[i + 6] & 0xff)); + result.add(Double.longBitsToDouble(longValue)); + i += 8; } else if (datatype == String.class) { // Every string value had a prefix of two bytes for which I have no idea, what the meaning is. // This code assumes the string values doesn't contain UTF-8 values with a code of 0x00 as it // uses this as termination char. try { int j = 0; - for(; j < s7Data.length; j++) { - if(s7Data[j] == 0) { + for (; j < s7Data.length; j++) { + if (s7Data[j] == 0) { break; } } diff --git a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolTest.java b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolTest.java index b2eb489..f1e5eb7 100644 --- a/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolTest.java +++ b/plc4j/protocols/s7/src/test/java/org/apache/plc4x/java/s7/netty/Plc4XS7ProtocolTest.java @@ -73,7 +73,6 @@ public class Plc4XS7ProtocolTest extends NettyTestBase { private List<String> notYetSupportedDataType = Stream.of( Calendar.class, GregorianCalendar.class, - Double.class, BigInteger.class, byte[].class, Byte[].class @@ -187,6 +186,8 @@ public class Plc4XS7ProtocolTest extends NettyTestBase { return (T) Calendar.getInstance(); } else if (type == Float.class) { return (T) Float.valueOf(123f); + } else if (type == Double.class) { + return (T) Double.valueOf(123f); } else if (type == Integer.class) { return (T) Integer.valueOf(123); } else if (type == String.class) { @@ -214,8 +215,11 @@ public class Plc4XS7ProtocolTest extends NettyTestBase { // TODO: what size is calender? data = new byte[]{(byte) 0b0000_0000}; } else if (type == Float.class) { - size = DataTransportSize.BYTE_WORD_DWORD; + size = DataTransportSize.REAL; data = new byte[]{(byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000}; + } else if (type == Double.class) { + size = DataTransportSize.REAL; + data = new byte[]{(byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000}; } else if (type == Integer.class) { size = DataTransportSize.INTEGER; data = new byte[]{(byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000, (byte) 0b0000_0000};