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 4750820  [General/MODBUS/ADS] Fixed date/time support
4750820 is described below

commit 4750820b85638df4f2104159ed02fc4f6f1c3a97
Author: Sebastian Rühl <sru...@apache.org>
AuthorDate: Thu Sep 27 16:38:10 2018 +0200

    [General/MODBUS/ADS] Fixed date/time support
---
 .../apache/plc4x/java/ads/model/AdsDataType.java   |  9 ++--
 .../plc4x/java/ads/model/AdsPlcFieldHandler.java   | 58 ++++++++++++++++++--
 .../ads/protocol/util/LittleEndianDecoder.java     |  8 ++-
 .../ads/protocol/util/LittleEndianEncoder.java     | 62 +++++++++++++++++-----
 .../java/ads/protocol/Plc4x2AdsProtocolTest.java   | 45 +++++++++++-----
 .../java/base/messages/DefaultPlcWriteRequest.java |  2 +-
 .../base/protocol/Plc4XSupportedDataTypes.java     | 32 +++++++----
 .../java/modbus/netty/Plc4XModbusProtocolTest.java |  1 -
 8 files changed, 168 insertions(+), 49 deletions(-)

diff --git 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/AdsDataType.java
 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/AdsDataType.java
index b9859f5..e6cf4c2 100644
--- 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/AdsDataType.java
+++ 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/AdsDataType.java
@@ -19,6 +19,9 @@
 package org.apache.plc4x.java.ads.model;
 
 import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.temporal.ChronoUnit;
 
 /**
  * Documentation can be found here:
@@ -191,15 +194,15 @@ public enum AdsDataType {
      * <p>
      * TOD#00:00       TOD#1193:02:47.295      32 Bit
      *///TODO: strange maximum
-    TIME_OF_DAY(0, 
Duration.ofHours(23).plusMinutes(59).plusSeconds(59).plusMillis(999).toMillis(),
 32),
+    TIME_OF_DAY(0, ChronoUnit.MILLIS.between(LocalTime.of(0, 0), 
LocalTime.of(23, 59, 59)), 32),
     /**
      * DATE
      * Date. The most significant digit is one second. The data type is 
handled internally like DWORD.
      * <p>
      * Type    Lower bound     Upper bound     Memory use
      * DATE    D#1970-01-01    D#2106-02-06    32 Bit
-     *///TODO: calculate max
-    DATE(0, -1, 32),
+     */
+    DATE(0, ChronoUnit.SECONDS.between(LocalDateTime.of(1970, 1, 1, 0, 0), 
LocalDateTime.of(2106, 2, 6, 0, 0)), 32),
     /**
      * DATE_AND_TIME
      * DT
diff --git 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/AdsPlcFieldHandler.java
 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/AdsPlcFieldHandler.java
index df751cb..bb9be24 100644
--- 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/AdsPlcFieldHandler.java
+++ 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/model/AdsPlcFieldHandler.java
@@ -27,10 +27,14 @@ import org.apache.plc4x.java.base.messages.items.*;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.nio.charset.Charset;
+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;
+import java.util.stream.Collectors;
 
 // TODO: implement me acording to ads. currently copy pasta from S7
 // Use endian decoders.
@@ -551,7 +555,7 @@ public class AdsPlcFieldHandler extends 
DefaultPlcFieldHandler {
             case STRUCT:
             case ALIAS:
             case SUB_RANGE_DATA_TYPE:
-                return internalEncodeTemporal(field, values);
+                return internalTimeTemporal(field, values);
             case UNKNOWN:
             default:
                 throw new PlcRuntimeException("Invalid encoder for type " + 
adsField.getAdsDataType().name());
@@ -602,7 +606,7 @@ public class AdsPlcFieldHandler extends 
DefaultPlcFieldHandler {
             case STRUCT:
             case ALIAS:
             case SUB_RANGE_DATA_TYPE:
-                return internalEncodeTemporal(field, values);
+                return internalDateTemporal(field, values);
             case UNKNOWN:
             default:
                 throw new PlcRuntimeException("Invalid encoder for type " + 
adsField.getAdsDataType().name());
@@ -653,7 +657,7 @@ public class AdsPlcFieldHandler extends 
DefaultPlcFieldHandler {
             case STRUCT:
             case ALIAS:
             case SUB_RANGE_DATA_TYPE:
-                return internalEncodeTemporal(field, values);
+                return internalDateTimeTemporal(field, values);
             case UNKNOWN:
             default:
                 throw new PlcRuntimeException("Invalid encoder for type " + 
adsField.getAdsDataType().name());
@@ -930,16 +934,60 @@ public class AdsPlcFieldHandler extends 
DefaultPlcFieldHandler {
         return new DefaultStringFieldItem(stringValues.toArray(new String[0]));
     }
 
-    private FieldItem internalEncodeTemporal(PlcField field, Object[] values) {
+    private FieldItem internalTimeTemporal(PlcField field, Object[] values) {
         AdsField adsField = (AdsField) field;
         switch (adsField.getAdsDataType()) {
             case TIME:
             case DATE:
             case DATE_AND_TIME:
-                return new DefaultLocalDateTimeFieldItem((LocalDateTime[]) 
values);
+                break;
+            default:
+                throw new IllegalArgumentException(
+                    "Cannot assign temporal values to " + 
adsField.getAdsDataType().name() + " fields.");
+        }
+        // TODO: support other types
+        List<LocalTime> localTimeValues = Arrays.stream(values)
+            .filter(LocalTime.class::isInstance)
+            .map(LocalTime.class::cast)
+            .collect(Collectors.toList());
+        return new DefaultLocalTimeFieldItem(localTimeValues.toArray(new 
LocalTime[0]));
+    }
+
+    private FieldItem internalDateTemporal(PlcField field, Object[] values) {
+        AdsField adsField = (AdsField) field;
+        switch (adsField.getAdsDataType()) {
+            case TIME:
+            case DATE:
+            case DATE_AND_TIME:
+                break;
+            default:
+                throw new IllegalArgumentException(
+                    "Cannot assign temporal values to " + 
adsField.getAdsDataType().name() + " fields.");
+        }
+        // TODO: support other types
+        List<LocalDate> localDateValues = Arrays.stream(values)
+            .filter(LocalDate.class::isInstance)
+            .map(LocalDate.class::cast)
+            .collect(Collectors.toList());
+        return new DefaultLocalDateFieldItem(localDateValues.toArray(new 
LocalDate[0]));
+    }
+
+    private FieldItem internalDateTimeTemporal(PlcField field, Object[] 
values) {
+        AdsField adsField = (AdsField) field;
+        switch (adsField.getAdsDataType()) {
+            case TIME:
+            case DATE:
+            case DATE_AND_TIME:
+                break;
             default:
                 throw new IllegalArgumentException(
                     "Cannot assign temporal values to " + 
adsField.getAdsDataType().name() + " fields.");
         }
+        // TODO: support other types
+        List<LocalDateTime> localDateTimeValues = Arrays.stream(values)
+            .filter(LocalDateTime.class::isInstance)
+            .map(LocalDateTime.class::cast)
+            .collect(Collectors.toList());
+        return new 
DefaultLocalDateTimeFieldItem(localDateTimeValues.toArray(new 
LocalDateTime[0]));
     }
 }
diff --git 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianDecoder.java
 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianDecoder.java
index 8d37edb..e09b508 100644
--- 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianDecoder.java
+++ 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianDecoder.java
@@ -317,7 +317,9 @@ public class LittleEndianDecoder {
                 LinkedList<LocalDate> values = new LinkedList<>();
                 while (wrappedBuffer.isReadable()) {
                     long aByte = wrappedBuffer.readUnsignedIntLE();
-                    values.offer(LocalDate.ofEpochDay(aByte));
+                    // TODO: where to get the zone offset from
+                    LocalDateTime localDateTime = 
LocalDateTime.ofEpochSecond(aByte, 0, ZoneOffset.UTC);
+                    values.offer(localDateTime.toLocalDate());
                 }
                 return new DefaultLocalDateFieldItem(values.toArray(new 
LocalDate[0]));
             }
@@ -325,7 +327,9 @@ public class LittleEndianDecoder {
                 LinkedList<LocalDateTime> values = new LinkedList<>();
                 while (wrappedBuffer.isReadable()) {
                     long aByte = wrappedBuffer.readUnsignedIntLE();
-                    values.offer(LocalDateTime.ofEpochSecond(aByte, 0, 
ZoneOffset.UTC));
+                    // TODO: where to get the zone offset from
+                    LocalDateTime localDateTime = 
LocalDateTime.ofEpochSecond(aByte, 0, ZoneOffset.UTC);
+                    values.offer(localDateTime);
                 }
                 return new DefaultLocalDateTimeFieldItem(values.toArray(new 
LocalDateTime[0]));
             }
diff --git 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianEncoder.java
 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianEncoder.java
index a039766..44b1247 100644
--- 
a/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianEncoder.java
+++ 
b/plc4j/protocols/ads/src/main/java/org/apache/plc4x/java/ads/protocol/util/LittleEndianEncoder.java
@@ -19,7 +19,6 @@
 package org.apache.plc4x.java.ads.protocol.util;
 
 import org.apache.commons.lang3.ArrayUtils;
-import org.apache.plc4x.java.ads.api.commands.types.TimeStamp;
 import org.apache.plc4x.java.ads.model.AdsDataType;
 import org.apache.plc4x.java.api.exceptions.PlcProtocolException;
 import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
@@ -29,9 +28,9 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.math.BigInteger;
 import java.nio.charset.Charset;
+import java.time.*;
+import java.time.temporal.ChronoUnit;
 import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
 import java.util.stream.Stream;
 
 // TODO: we might user 
ByteBuffer.wrap(buffer).order(ByteOrder.LITTLE_ENDIAN).putInt(port).asArray() 
etc
@@ -59,8 +58,12 @@ public class LittleEndianEncoder {
             result = encodeLong(adsDataType, 
Arrays.stream(values).map(Long.class::cast));
         } else if (valueType == BigInteger.class) {
             result = encodeBigInteger(adsDataType, 
Arrays.stream(values).map(BigInteger.class::cast));
-        } else if (valueType == Calendar.class || 
Calendar.class.isAssignableFrom(valueType)) {
-            result = encodeCalendar(adsDataType, 
Arrays.stream(values).map(Calendar.class::cast));
+        } else if (valueType == LocalTime.class) {
+            result = encodeLocalTime(adsDataType, 
Arrays.stream(values).map(LocalTime.class::cast));
+        } else if (valueType == LocalDate.class) {
+            result = encodeLocalDate(adsDataType, 
Arrays.stream(values).map(LocalDate.class::cast));
+        } else if (valueType == LocalDateTime.class) {
+            result = encodeLocalDateTime(adsDataType, 
Arrays.stream(values).map(LocalDateTime.class::cast));
         } else if (valueType == Float.class) {
             result = encodeFloat(adsDataType, 
Arrays.stream(values).map(Float.class::cast));
         } else if (valueType == Double.class) {
@@ -184,14 +187,47 @@ public class LittleEndianEncoder {
             });
     }
 
-    private static Stream<byte[]> encodeCalendar(AdsDataType adsDataType, 
Stream<Calendar> calendarStream) {
-        return calendarStream
-            .map(Calendar.class::cast)
-            .map(Calendar::getTime)
-            .map(Date::getTime)
-            .map(BigInteger::valueOf)
-            .map(TimeStamp::javaToWinTime)
-            .map(BigInteger::longValue)
+    private static Stream<byte[]> encodeLocalTime(AdsDataType adsDataType, 
Stream<LocalTime> localTimeStream) {
+        return localTimeStream
+            .map(localTime -> ChronoUnit.MILLIS.between(LocalTime.of(0, 0), 
localTime))
+            .peek(value -> checkBound(adsDataType, value))
+            .map(time -> new byte[]{
+                (byte) (time & 0x00000000_000000ffL),
+                (byte) ((time & 0x00000000_0000ff00L) >> 8),
+                (byte) ((time & 0x00000000_00ff0000L) >> 16),
+                (byte) ((time & 0x00000000_ff000000L) >> 24),
+
+                (byte) ((time & 0x000000ff_00000000L) >> 32),
+                (byte) ((time & 0x0000ff00_00000000L) >> 40),
+                (byte) ((time & 0x00ff0000_00000000L) >> 48),
+                (byte) ((time & 0xff000000_00000000L) >> 56),
+            });
+    }
+
+    private static Stream<byte[]> encodeLocalDate(AdsDataType adsDataType, 
Stream<LocalDate> localDateStream) {
+        return localDateStream
+            // TODO: fixme: which offset should we use?
+            .map(localDate -> localDate.atTime(0, 0).toInstant(ZoneOffset.UTC))
+            .map(Instant::getEpochSecond)
+            .peek(value -> checkBound(adsDataType, value))
+            .map(time -> new byte[]{
+                (byte) (time & 0x00000000_000000ffL),
+                (byte) ((time & 0x00000000_0000ff00L) >> 8),
+                (byte) ((time & 0x00000000_00ff0000L) >> 16),
+                (byte) ((time & 0x00000000_ff000000L) >> 24),
+
+                (byte) ((time & 0x000000ff_00000000L) >> 32),
+                (byte) ((time & 0x0000ff00_00000000L) >> 40),
+                (byte) ((time & 0x00ff0000_00000000L) >> 48),
+                (byte) ((time & 0xff000000_00000000L) >> 56),
+            });
+    }
+
+    private static Stream<byte[]> encodeLocalDateTime(AdsDataType adsDataType, 
Stream<LocalDateTime> localDateTimeStream) {
+        return localDateTimeStream
+            // TODO: fixme: which offset should we use?
+            .map(localDateTime -> localDateTime.toInstant(ZoneOffset.UTC))
+            .map(Instant::getEpochSecond)
             .peek(value -> checkBound(adsDataType, value))
             .map(time -> new byte[]{
                 (byte) (time & 0x00000000_000000ffL),
diff --git 
a/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/protocol/Plc4x2AdsProtocolTest.java
 
b/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/protocol/Plc4x2AdsProtocolTest.java
index a97be10..95c6628 100644
--- 
a/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/protocol/Plc4x2AdsProtocolTest.java
+++ 
b/plc4j/protocols/ads/src/test/java/org/apache/plc4x/java/ads/protocol/Plc4x2AdsProtocolTest.java
@@ -46,7 +46,11 @@ import org.slf4j.LoggerFactory;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
+import java.math.BigDecimal;
 import java.math.BigInteger;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
@@ -99,7 +103,7 @@ public class Plc4x2AdsProtocolTest {
         Invoke invokeId = Invoke.of(2);
         return streamOfLittleEndianDataTypePairs()
             // TODO: calender doesnt work anymore so we might need to adjust 
the generator above.
-            .filter(o -> o.getDataTypeClass() != GregorianCalendar.class)
+            .filter(o -> o.getDataTypeClass() != LocalDateTime.class)
             .filter(o -> o.getDataTypeClass() != Byte[].class)
             .filter(o -> o.getDataTypeClass() != byte[].class)
             .map(Plc4x2AdsProtocolTest::mapToAdsDataType)
@@ -121,21 +125,24 @@ public class Plc4x2AdsProtocolTest {
             ))
             .flatMap(stream -> stream)
             // TODO: request doesn't know its type anymore... fixme
-            .map(pair -> new Object[]{Object.class.getSimpleName(), pair.left, 
pair.left.getResponseFuture(), 
pair.left.getRequest().getClass().getSimpleName(), pair.right, 
pair.right.getClass().getSimpleName()}).collect(Collectors.toList());
+            .map(pair -> new Object[]{"???", pair.left, 
pair.left.getResponseFuture(), 
pair.left.getRequest().getClass().getSimpleName(), pair.right, 
pair.right.getClass().getSimpleName()}).collect(Collectors.toList());
     }
 
     private static AdsDataTypePair 
mapToAdsDataType(Plc4XSupportedDataTypes.DataTypePair dataTypePair) {
-        // TODO: check usefull type mapping
         Map<Class<?>, AdsDataType> dataTypeMap = new HashMap<>();
         dataTypeMap.put(Boolean.class, AdsDataType.BOOL);
         dataTypeMap.put(Byte.class, AdsDataType.BYTE);
         dataTypeMap.put(Short.class, AdsDataType.INT);
-        dataTypeMap.put(Float.class, AdsDataType.REAL);
         dataTypeMap.put(Integer.class, AdsDataType.INT32);
-        dataTypeMap.put(Double.class, AdsDataType.LREAL);
+        dataTypeMap.put(Long.class, AdsDataType.INT64);
         dataTypeMap.put(BigInteger.class, AdsDataType.INT64);
-        dataTypeMap.put(Calendar.class, AdsDataType.DATE_AND_TIME);
+        dataTypeMap.put(Float.class, AdsDataType.REAL);
+        dataTypeMap.put(Double.class, AdsDataType.LREAL);
+        dataTypeMap.put(BigDecimal.class, AdsDataType.LREAL);
         dataTypeMap.put(String.class, AdsDataType.STRING);
+        dataTypeMap.put(LocalTime.class, AdsDataType.TIME);
+        dataTypeMap.put(LocalDate.class, AdsDataType.DATE);
+        dataTypeMap.put(LocalDateTime.class, AdsDataType.DATE_AND_TIME);
         dataTypeMap.put(byte[].class, AdsDataType.BYTE);
         dataTypeMap.put(Byte[].class, AdsDataType.BYTE);
         return new AdsDataTypePair(dataTypePair, 
dataTypeMap.getOrDefault(dataTypePair.getDataTypeClass(), AdsDataType.BYTE));
@@ -149,10 +156,6 @@ public class Plc4x2AdsProtocolTest {
             super(dataTypePair.getDataTypePair());
             this.adsDataType = adsDataType;
         }
-
-        private AdsDataType getAdsDataType() {
-            return adsDataType;
-        }
     }
 
     @Before
@@ -182,16 +185,30 @@ public class Plc4x2AdsProtocolTest {
                 assertThat(value, equalTo(new byte[]{0x1}));
             } else if (payloadClazzName.equals(Short.class.getSimpleName())) {
                 assertThat(value, equalTo(new byte[]{0x1, 0x0}));
-            } else if 
(payloadClazzName.equals(GregorianCalendar.class.getSimpleName())) {
-                assertThat(value, equalTo(new byte[]{0x0, (byte) 0x80, 0x3E, 
0x15, (byte) 0xAB, 0X47, (byte) 0xFC, 0x28}));
+            } else if (payloadClazzName.equals(Integer.class.getSimpleName())) 
{
+                assertThat(value, equalTo(new byte[]{0x1, 0x0, 0x0, 0x0}));
+            } else if (payloadClazzName.equals(Long.class.getSimpleName())) {
+                assertThat(value, equalTo(new byte[]{0x1, 0x0, 0x0, 0x0}));
+            } else if 
(payloadClazzName.equals(BigInteger.class.getSimpleName())) {
+                assertThat(value, equalTo(new byte[]{0x1, 0x0, 0x0, 0x0}));
             } else if (payloadClazzName.equals(Float.class.getSimpleName())) {
                 assertThat(value, equalTo(new byte[]{0x0, 0x0, (byte) 0x80, 
0x3F}));
             } else if (payloadClazzName.equals(Double.class.getSimpleName())) {
                 assertThat(value, equalTo(new byte[]{0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, (byte) 0xF0, 0x3F}));
-            } else if (payloadClazzName.equals(Integer.class.getSimpleName())) 
{
-                assertThat(value, equalTo(new byte[]{0x1, 0x0, 0x0, 0x0}));
+            } else if 
(payloadClazzName.equals(BigDecimal.class.getSimpleName())) {
+                assertThat(value, equalTo(new byte[]{0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, (byte) 0xF0, 0x3F}));
             } else if (payloadClazzName.equals(String.class.getSimpleName())) {
                 assertThat(value, equalTo(new byte[]{0x48, 0x65, 0x6c, 0x6c, 
0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00}));
+            } else if 
(payloadClazzName.equals(LocalTime.class.getSimpleName())) {
+                assertThat(value, equalTo(new byte[]{0x48, 0x65, 0x6c, 0x6c, 
0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00}));
+            } else if 
(payloadClazzName.equals(LocalDate.class.getSimpleName())) {
+                assertThat(value, equalTo(new byte[]{0x48, 0x65, 0x6c, 0x6c, 
0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00}));
+            } else if 
(payloadClazzName.equals(LocalDateTime.class.getSimpleName())) {
+                assertThat(value, equalTo(new byte[]{0x48, 0x65, 0x6c, 0x6c, 
0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00}));
+            } else if (payloadClazzName.equals(byte[].class.getSimpleName())) {
+                assertThat(value, equalTo(new byte[]{0x48, 0x65, 0x6c, 0x6c, 
0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00}));
+            } else if (payloadClazzName.equals(Byte[].class.getSimpleName())) {
+                assertThat(value, equalTo(new byte[]{0x48, 0x65, 0x6c, 0x6c, 
0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00}));
             }
         }
     }
diff --git 
a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcWriteRequest.java
 
b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcWriteRequest.java
index d7e4086..c78ff08 100644
--- 
a/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcWriteRequest.java
+++ 
b/plc4j/protocols/driver-bases/base/src/main/java/org/apache/plc4x/java/base/messages/DefaultPlcWriteRequest.java
@@ -121,8 +121,8 @@ public class DefaultPlcWriteRequest implements 
InternalPlcWriteRequest, Internal
             handlerMap.put(BigInteger.class, fieldHandler::encodeBigInteger);
             handlerMap.put(Long.class, fieldHandler::encodeLong);
             handlerMap.put(Float.class, fieldHandler::encodeFloat);
-            handlerMap.put(BigDecimal.class, fieldHandler::encodeBigDecimal);
             handlerMap.put(Double.class, fieldHandler::encodeDouble);
+            handlerMap.put(BigDecimal.class, fieldHandler::encodeBigDecimal);
             handlerMap.put(String.class, fieldHandler::encodeString);
             handlerMap.put(LocalTime.class, fieldHandler::encodeTime);
             handlerMap.put(LocalDate.class, fieldHandler::encodeDate);
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 2797f83..ffe5234 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
@@ -24,8 +24,15 @@ import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.math.BigInteger;
-import java.util.*;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
 import java.util.function.Function;
 import java.util.stream.Stream;
 
@@ -38,19 +45,20 @@ public class Plc4XSupportedDataTypes {
     private final static Map<Class, DataTypePair<?>> bigEndianMap;
 
     static {
-        Calendar calenderInstance = Calendar.getInstance();
-        calenderInstance.setTime(new Date(283686951976960L));
         littleEndianMap = new HashMap<>();
         littleEndianMap.put(Boolean.class, DataTypePair.of(Boolean.TRUE, new 
byte[]{0x01}));
         littleEndianMap.put(Byte.class, DataTypePair.of(Byte.valueOf("1"), new 
byte[]{0x1}));
         littleEndianMap.put(Short.class, DataTypePair.of(Short.valueOf("1"), 
new byte[]{0x1, 0x0}));
-        littleEndianMap.put(Float.class, DataTypePair.of(Float.valueOf("1"), 
new byte[]{0x0, 0x0, (byte) 0x80, 0x3F}));
         littleEndianMap.put(Integer.class, 
DataTypePair.of(Integer.valueOf("1"), new byte[]{0x1, 0x0, 0x0, 0x0}));
-        littleEndianMap.put(Double.class, DataTypePair.of(Double.valueOf("1"), 
new byte[]{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, (byte) 0xF0, 0x3F}));
+        littleEndianMap.put(Long.class, DataTypePair.of(BigInteger.valueOf(1), 
new byte[]{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}));
         littleEndianMap.put(BigInteger.class, 
DataTypePair.of(BigInteger.valueOf(1), new byte[]{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0}));
-        littleEndianMap.put(Calendar.class, DataTypePair.of(calenderInstance, 
new byte[]{0x0, (byte) 0x80, 0x3E, 0x15, (byte) 0xAB, 0x47, (byte) 0xFC, 
0x28}));
-        littleEndianMap.put(GregorianCalendar.class, 
littleEndianMap.get(Calendar.class));
+        littleEndianMap.put(Float.class, DataTypePair.of(Float.valueOf("1"), 
new byte[]{0x0, 0x0, (byte) 0x80, 0x3F}));
+        littleEndianMap.put(Double.class, DataTypePair.of(Double.valueOf("1"), 
new byte[]{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, (byte) 0xF0, 0x3F}));
+        littleEndianMap.put(BigDecimal.class, 
DataTypePair.of(Double.valueOf("1"), new byte[]{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
(byte) 0xF0, 0x3F}));
         littleEndianMap.put(String.class, 
DataTypePair.of(String.valueOf("Hello World!"), new byte[]{0x48, 0x65, 0x6c, 
0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00}));
+        littleEndianMap.put(LocalTime.class, 
DataTypePair.of(LocalTime.ofSecondOfDay(1), new byte[]{0x1, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0}));
+        littleEndianMap.put(LocalDate.class, 
DataTypePair.of(LocalDate.of(1970, 1, 1), new byte[]{0x1, 0x0, 0x0, 0x0, 0x0, 
0x0, 0x0, 0x0}));
+        littleEndianMap.put(LocalDateTime.class, 
DataTypePair.of(LocalDateTime.of(LocalDate.of(1970, 1, 1), 
LocalTime.ofSecondOfDay(1)), new byte[]{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 
0x0}));
         littleEndianMap.put(byte[].class, DataTypePair.of(new byte[]{0x1, 0x2, 
0x3, 0x4}, new byte[]{0x1, 0x2, 0x3, 0x4}));
         littleEndianMap.put(Byte[].class, DataTypePair.of(new Byte[]{0x1, 0x2, 
0x3, 0x4}, new byte[]{0x1, 0x2, 0x3, 0x4}));
         bigEndianMap = new HashMap<>();
@@ -77,12 +85,16 @@ public class Plc4XSupportedDataTypes {
             Boolean.class,
             Byte.class,
             Short.class,
-            Float.class,
             Integer.class,
-            Double.class,
+            Long.class,
             BigInteger.class,
-            Calendar.class,
+            Float.class,
+            Double.class,
+            BigDecimal.class,
             String.class,
+            LocalTime.class,
+            LocalDate.class,
+            LocalDateTime.class,
             byte[].class,
             Byte[].class
         );
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 7e9099e..b67f97a 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
@@ -65,7 +65,6 @@ public class Plc4XModbusProtocolTest {
     public ExpectedException expectedException = ExpectedException.none();
     // TODO: implement these types
     private List<String> notYetSupportedDataType = Stream.of(
-        GregorianCalendar.class,
         String.class
     ).map(Class::getSimpleName).collect(Collectors.toList());
 

Reply via email to