You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cg...@apache.org on 2024/01/29 02:29:44 UTC

(plc4x) 01/01: Fix reading/writing of DATE_AND_TIME type

This is an automated email from the ASF dual-hosted git repository.

cgarcia pushed a commit to branch fix/DATE_AND_TIME
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 4177949559da110ec31280a321ccf12f9072223b
Author: Cesar Garcia <ce...@ceos.com.ve>
AuthorDate: Sun Jan 28 22:19:25 2024 -0400

    Fix reading/writing of DATE_AND_TIME type
---
 .../templates/java/data-io-template.java.ftlh      |   3 +-
 .../java/bacnetip/readwrite/BACnetVendorId.java    |   6 -
 .../java/knxnetip/readwrite/KnxDatapoint.java      |   8 +-
 .../apache/plc4x/java/s7/readwrite/DataItem.java   | 146 +++++++++++----------
 .../plc4x/java/s7/readwrite/TransportSize.java     |  10 +-
 .../java/s7/readwrite/utils/StaticHelper.java      |  94 ++++++++++++-
 .../protocols/bacnetip/bacnet-vendorids.mspec      |   6 -
 .../s7/src/main/resources/protocols/s7/s7.mspec    |  29 ++--
 8 files changed, 195 insertions(+), 107 deletions(-)

diff --git a/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh b/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh
index fa472a86d6..6f39fa8255 100644
--- a/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh
+++ b/code-generation/language-java/src/main/resources/templates/java/data-io-template.java.ftlh
@@ -221,6 +221,7 @@ public class ${type.name} {
                         <#if case.name == "Struct" ||
                             ((case.name == "DATE_AND_TIME") && ((simpleField.name == "year") || (simpleField.name == "month") || (simpleField.name == "day") || (simpleField.name == "hour") || (simpleField.name == "minutes") || (simpleField.name == "seconds"))) ||
                             ((case.name == "DATE_AND_TIME") && (simpleField.name == "secondsSinceEpoch")) ||
+                            ((case.name == "DATE_AND_TIME") && (simpleField.name == "nanosecondsSinceEpoch)")) ||
                             ((case.name == "DATE") && ((simpleField.name == "year") || (simpleField.name == "month") || (simpleField.name == "day"))) ||
                             ((case.name == "TIME_OF_DAY") && ((simpleField.name == "hour") || (simpleField.name == "minutes") || (simpleField.name == "seconds"))) ||
                         simpleField.name == "value">
@@ -322,7 +323,7 @@ public class ${type.name} {
                     <#break>
                 <#case "DATE_AND_TIME">
                     <#if helper.hasFieldsWithNames(case.fields, "year", "month", "day", "hour", "minutes", "seconds", "nanoseconds")>
-            return PlcDATE_AND_TIME.ofSegments(year.intValue(), (month == 0) ? 1 : month.intValue(), (day == 0) ? 1 : day.intValue(), hour.intValue(), minutes.intValue(), seconds.intValue(), nanoseconds.intValue());
+            return PlcDATE_AND_TIME.ofSegments(year.intValue(), (month.intValue() == 0) ? 1 : month.intValue(), (day.intValue() == 0) ? 1 : day.intValue(), hour.intValue(), minutes.intValue(), seconds.intValue(), nanoseconds.intValue());
                     <#elseif helper.hasFieldsWithNames(case.fields, "secondsSinceEpoch")>
             return PlcDATE_AND_TIME.ofSecondsSinceEpoch(secondsSinceEpoch);
                     </#if>
diff --git a/plc4j/drivers/bacnet/src/main/generated/org/apache/plc4x/java/bacnetip/readwrite/BACnetVendorId.java b/plc4j/drivers/bacnet/src/main/generated/org/apache/plc4x/java/bacnetip/readwrite/BACnetVendorId.java
index 8702da2184..2c30a51b67 100644
--- a/plc4j/drivers/bacnet/src/main/generated/org/apache/plc4x/java/bacnetip/readwrite/BACnetVendorId.java
+++ b/plc4j/drivers/bacnet/src/main/generated/org/apache/plc4x/java/bacnetip/readwrite/BACnetVendorId.java
@@ -1670,12 +1670,6 @@ public enum BACnetVendorId {
   GRID_CONNECT_INC((int) 1454, (int) 1454, (String) "Grid Connect Inc."),
   ZIEGLER_INSTRUMENTATIONUK_LTD((int) 1455, (int) 1455, (String) "Ziegler Instrumentation UK Ltd"),
   CONTROL_TECLLC((int) 1456, (int) 1456, (String) "ControlTec, LLC"),
-  AETERLINK_CORPORATION((int) 1457, (int) 1457, (String) "Aeterlink Corporation"),
-  ALPHA_EPSILON_AUTOMATION((int) 1458, (int) 1458, (String) "Alpha Epsilon Automation"),
-  ASTRALITE_INC((int) 1459, (int) 1459, (String) "Astralite Inc."),
-  DELTA_FIRE_LTDA((int) 1460, (int) 1460, (String) "Delta Fire Ltda."),
-  BOCK_WATER_HEATERS_INC((int) 1461, (int) 1461, (String) "Bock Water Heaters, Inc."),
-  CLEAVER_BROOKS((int) 1462, (int) 1462, (String) "Cleaver-Brooks"),
   UNKNOWN_VENDOR((int) 0xFFFF, (int) 0xFFFF, (String) "Unknown");
   private static final Map<Integer, BACnetVendorId> map;
 
diff --git a/plc4j/drivers/knxnetip/src/main/generated/org/apache/plc4x/java/knxnetip/readwrite/KnxDatapoint.java b/plc4j/drivers/knxnetip/src/main/generated/org/apache/plc4x/java/knxnetip/readwrite/KnxDatapoint.java
index dfe02653e1..76342dff58 100644
--- a/plc4j/drivers/knxnetip/src/main/generated/org/apache/plc4x/java/knxnetip/readwrite/KnxDatapoint.java
+++ b/plc4j/drivers/knxnetip/src/main/generated/org/apache/plc4x/java/knxnetip/readwrite/KnxDatapoint.java
@@ -446,8 +446,8 @@ public class KnxDatapoint {
 
       return PlcDATE_AND_TIME.ofSegments(
           year.intValue(),
-          (month == 0) ? 1 : month.intValue(),
-          (day == 0) ? 1 : day.intValue(),
+          (month.intValue() == 0) ? 1 : month.intValue(),
+          (day.intValue() == 0) ? 1 : day.intValue(),
           hour.intValue(),
           minutes.intValue(),
           seconds.intValue(),
@@ -492,8 +492,8 @@ public class KnxDatapoint {
 
       return PlcDATE_AND_TIME.ofSegments(
           year.intValue(),
-          (month == 0) ? 1 : month.intValue(),
-          (day == 0) ? 1 : day.intValue(),
+          (month.intValue() == 0) ? 1 : month.intValue(),
+          (day.intValue() == 0) ? 1 : day.intValue(),
           hour.intValue(),
           minutes.intValue(),
           seconds.intValue(),
diff --git a/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/DataItem.java b/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/DataItem.java
index 0128b57c8a..4871dced66 100644
--- a/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/DataItem.java
+++ b/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/DataItem.java
@@ -221,36 +221,50 @@ public class DataItem {
       return PlcLTIME_OF_DAY.ofNanosecondsSinceMidnight(nanosecondsSinceMidnight);
     } else if (EvaluationHelper.equals(dataProtocolId, "IEC61131_DATE_AND_TIME")) { // DATE_AND_TIME
 
-      // Simple Field (year)
-      Integer year = /*TODO: migrate me*/ /*TODO: migrate me*/ readBuffer.readUnsignedInt("", 16);
-
-      // Simple Field (month)
-      Short month = /*TODO: migrate me*/ /*TODO: migrate me*/ readBuffer.readUnsignedShort("", 8);
-
-      // Simple Field (day)
-      Short day = /*TODO: migrate me*/ /*TODO: migrate me*/ readBuffer.readUnsignedShort("", 8);
-
-      // Simple Field (dayOfWeek)
-      Short dayOfWeek = /*TODO: migrate me*/ /*TODO: migrate me*/
-          readBuffer.readUnsignedShort("", 8);
-
-      // Simple Field (hour)
-      Short hour = /*TODO: migrate me*/ /*TODO: migrate me*/ readBuffer.readUnsignedShort("", 8);
-
-      // Simple Field (minutes)
-      Short minutes = /*TODO: migrate me*/ /*TODO: migrate me*/ readBuffer.readUnsignedShort("", 8);
-
-      // Simple Field (seconds)
-      Short seconds = /*TODO: migrate me*/ /*TODO: migrate me*/ readBuffer.readUnsignedShort("", 8);
-
-      // Simple Field (nanoseconds)
-      Long nanoseconds = /*TODO: migrate me*/ /*TODO: migrate me*/
-          readBuffer.readUnsignedLong("", 32);
+      // Manual Field (year)
+      BigInteger year =
+          (BigInteger)
+              (org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.parseBcdToByte(readBuffer));
+
+      // Manual Field (month)
+      BigInteger month =
+          (BigInteger)
+              (org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.parseBcdToByte(readBuffer));
+
+      // Manual Field (day)
+      BigInteger day =
+          (BigInteger)
+              (org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.parseBcdToByte(readBuffer));
+
+      // Manual Field (hour)
+      BigInteger hour =
+          (BigInteger)
+              (org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.parseBcdToByte(readBuffer));
+
+      // Manual Field (minutes)
+      BigInteger minutes =
+          (BigInteger)
+              (org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.parseBcdToByte(readBuffer));
+
+      // Manual Field (seconds)
+      BigInteger seconds =
+          (BigInteger)
+              (org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.parseBcdToByte(readBuffer));
+
+      // Manual Field (nanoseconds)
+      BigInteger nanoseconds =
+          (BigInteger)
+              (org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.parseS7MsecToNsec(readBuffer));
+
+      // Manual Field (dayOfWeek)
+      BigInteger dayOfWeek =
+          (BigInteger)
+              (org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.parseS7DayOfWeek(readBuffer));
 
       return PlcDATE_AND_TIME.ofSegments(
           year.intValue(),
-          (month == 0) ? 1 : month.intValue(),
-          (day == 0) ? 1 : day.intValue(),
+          (month.intValue() == 0) ? 1 : month.intValue(),
+          (day.intValue() == 0) ? 1 : day.intValue(),
           hour.intValue(),
           minutes.intValue(),
           seconds.intValue(),
@@ -400,40 +414,30 @@ public class DataItem {
       /*TODO: migrate me*/ writeBuffer.writeUnsignedBigInteger(
           "", 64, (BigInteger) (nanosecondsSinceMidnight));
     } else if (EvaluationHelper.equals(dataProtocolId, "IEC61131_DATE_AND_TIME")) { // DATE_AND_TIME
-      // Simple Field (year)
-      int year = (int) _value.getInt();
-      /*TODO: migrate me*/
-      /*TODO: migrate me*/ writeBuffer.writeUnsignedInt("", 16, ((Number) (year)).intValue());
-      // Simple Field (month)
-      short month = (short) _value.getShort();
-      /*TODO: migrate me*/
-      /*TODO: migrate me*/ writeBuffer.writeUnsignedShort("", 8, ((Number) (month)).shortValue());
-      // Simple Field (day)
-      short day = (short) _value.getShort();
-      /*TODO: migrate me*/
-      /*TODO: migrate me*/ writeBuffer.writeUnsignedShort("", 8, ((Number) (day)).shortValue());
-      // Simple Field (dayOfWeek)
-      short dayOfWeek = (short) _value.getShort();
-      /*TODO: migrate me*/
-      /*TODO: migrate me*/ writeBuffer.writeUnsignedShort(
-          "", 8, ((Number) (dayOfWeek)).shortValue());
-      // Simple Field (hour)
-      short hour = (short) _value.getShort();
-      /*TODO: migrate me*/
-      /*TODO: migrate me*/ writeBuffer.writeUnsignedShort("", 8, ((Number) (hour)).shortValue());
-      // Simple Field (minutes)
-      short minutes = (short) _value.getShort();
-      /*TODO: migrate me*/
-      /*TODO: migrate me*/ writeBuffer.writeUnsignedShort("", 8, ((Number) (minutes)).shortValue());
-      // Simple Field (seconds)
-      short seconds = (short) _value.getShort();
-      /*TODO: migrate me*/
-      /*TODO: migrate me*/ writeBuffer.writeUnsignedShort("", 8, ((Number) (seconds)).shortValue());
-      // Simple Field (nanoseconds)
-      long nanoseconds = (long) _value.getLong();
-      /*TODO: migrate me*/
-      /*TODO: migrate me*/ writeBuffer.writeUnsignedLong(
-          "", 32, ((Number) (nanoseconds)).longValue());
+      // Manual Field (year)
+      org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.ByteToBcd(
+          writeBuffer, _value.getDateTime().getYear());
+      // Manual Field (month)
+      org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.ByteToBcd(
+          writeBuffer, _value.getDateTime().getMonthValue());
+      // Manual Field (day)
+      org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.ByteToBcd(
+          writeBuffer, _value.getDateTime().getDayOfMonth());
+      // Manual Field (hour)
+      org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.ByteToBcd(
+          writeBuffer, _value.getDateTime().getHour());
+      // Manual Field (minutes)
+      org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.ByteToBcd(
+          writeBuffer, _value.getDateTime().getMinute());
+      // Manual Field (seconds)
+      org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.ByteToBcd(
+          writeBuffer, _value.getDateTime().getSecond());
+      // Manual Field (nanoseconds)
+      org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.serializeNsecToS7Msec(
+          writeBuffer, _value.getDateTime().getNano());
+      // Manual Field (dayOfWeek)
+      org.apache.plc4x.java.s7.readwrite.utils.StaticHelper.serializeS7DayOfWeek(
+          writeBuffer, _value.getDateTime().getDayOfWeek().getValue());
     }
   }
 
@@ -521,22 +525,22 @@ public class DataItem {
       // Simple Field (nanosecondsSinceMidnight)
       sizeInBits += 64;
     } else if (EvaluationHelper.equals(dataProtocolId, "IEC61131_DATE_AND_TIME")) { // DATE_AND_TIME
-      // Simple Field (year)
-      sizeInBits += 16;
-      // Simple Field (month)
+      // Manual Field (year)
       sizeInBits += 8;
-      // Simple Field (day)
+      // Manual Field (month)
       sizeInBits += 8;
-      // Simple Field (dayOfWeek)
+      // Manual Field (day)
       sizeInBits += 8;
-      // Simple Field (hour)
+      // Manual Field (hour)
       sizeInBits += 8;
-      // Simple Field (minutes)
+      // Manual Field (minutes)
       sizeInBits += 8;
-      // Simple Field (seconds)
+      // Manual Field (seconds)
+      sizeInBits += 8;
+      // Manual Field (nanoseconds)
+      sizeInBits += 8;
+      // Manual Field (dayOfWeek)
       sizeInBits += 8;
-      // Simple Field (nanoseconds)
-      sizeInBits += 32;
     }
     return sizeInBits;
   }
diff --git a/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/TransportSize.java b/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/TransportSize.java
index 7d9b946c42..9e14873e2e 100644
--- a/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/TransportSize.java
+++ b/plc4j/drivers/s7/src/main/generated/org/apache/plc4x/java/s7/readwrite/TransportSize.java
@@ -356,12 +356,12 @@ public enum TransportSize {
       (boolean) true,
       (boolean) false,
       (short) 0x0F,
-      (short) 12,
+      (short) 8,
       (boolean) true,
       (boolean) false,
       (short) 'X',
       (boolean) true,
-      null,
+      DataTransportSize.BYTE_WORD_DWORD,
       (String) "IEC61131_DATE_AND_TIME",
       null),
   DT(
@@ -369,12 +369,12 @@ public enum TransportSize {
       (boolean) true,
       (boolean) false,
       (short) 0x0F,
-      (short) 12,
+      (short) 8,
       (boolean) true,
       (boolean) false,
-      (short) 'X',
+      (short) 'B',
       (boolean) true,
-      null,
+      DataTransportSize.BYTE_WORD_DWORD,
       (String) "IEC61131_DATE_AND_TIME",
       null);
   private static final Map<Short, TransportSize> map;
diff --git a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java
index 3bd70e694e..fe4911fbe1 100644
--- a/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java
+++ b/plc4j/drivers/s7/src/main/java/org/apache/plc4x/java/s7/readwrite/utils/StaticHelper.java
@@ -21,6 +21,7 @@ package org.apache.plc4x.java.s7.readwrite.utils;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufUtil;
 import io.netty.buffer.Unpooled;
+import java.math.BigInteger;
 import org.apache.commons.lang3.NotImplementedException;
 import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 import org.apache.plc4x.java.api.types.PlcResponseCode;
@@ -53,6 +54,7 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import org.apache.plc4x.java.s7.readwrite.DateAndTime;
 import org.apache.plc4x.java.spi.values.PlcDATE;
 import org.apache.plc4x.java.spi.values.PlcTIME;
 
@@ -2097,10 +2099,19 @@ public class StaticHelper {
         byte dec = (byte) ((incomingByte / 10) % 10);
         return (byte) ((dec << 4) | (incomingByte % 10));
     }
+    
+    public static void ByteToBcd(final WriteBuffer buffer, PlcValue _value) throws SerializationException {
+        
+    }     
 
     private static int BcdToInt(byte bcd) {
         return (bcd >> 4) * 10 + (bcd & 0x0f);
     }
+    
+    public static int BcdToInt(final ReadBuffer buffer) throws ParseException {
+        byte bcd = buffer.readByte();
+        return (bcd >> 4) * 10 + (bcd & 0x0f);
+    }      
 
     public static void ByteToBcd(final WriteBuffer buffer, short _value) throws SerializationException {
         short incomingByte = _value;
@@ -2109,11 +2120,21 @@ public class StaticHelper {
         outputByte = (byte) ((dec << 4) | (incomingByte % 10));
         buffer.writeByte(outputByte);
     }
-
-    public static int BcdToInt(final ReadBuffer buffer) throws ParseException {
+    
+    public static void ByteToBcd(final WriteBuffer buffer, int _value) throws SerializationException {
+        ByteToBcd(buffer, (short) _value);
+    }    
+    
+    public static BigInteger parseBcdToByte(final ReadBuffer buffer) throws ParseException {
         byte bcd = buffer.readByte();
-        return (bcd >> 4) * 10 + (bcd & 0x0f);
-    }
+        return BigInteger.valueOf((short) ((bcd >> 4) * 10 + (bcd & 0x0f)));
+    }    
+    
+    public static void serializeByteToBcd(final WriteBuffer buffer, PlcValue _value) throws SerializationException {
+        byte outputByte = 0;
+        //System.out.println("Clase: " + _value.getDateTime().getN);
+    }    
+    
 
     public static int S7msecToInt(final ReadBuffer buffer) throws ParseException {
         int centenas = BcdToInt(buffer.readUnsignedByte(4));
@@ -2138,6 +2159,10 @@ public class StaticHelper {
         buffer.writeUnsignedByte(4, (byte) unidad);
     }
 
+    public static void IntToS7msec(final WriteBuffer buffer, PlcValue _value) throws SerializationException {
+        
+    }    
+    
     public static void LeftShift3(final WriteBuffer buffer, int _value) throws SerializationException {
         int valor = _value << 3;
         buffer.writeUnsignedInt(16, valor);
@@ -2663,6 +2688,67 @@ public class StaticHelper {
             return;
         }
     }
+    
+    public static LocalDateTime xparseS7DateTime(ReadBuffer io) {
+        try {
+            int year = io.readByte()  + 2000;
+            int month = io.readByte();
+            int day = io.readByte();
+            int hour = io.readByte();
+            int minute = io.readByte();
+            int second = io.readByte();
+            int ms = io.readUnsignedInt(12);
+            // Skip day-of-week
+            int dow = io.readUnsignedInt(4);
+
+            return LocalDateTime.of(year, month, day, hour, minute, second, ms * 1000000);
+        } catch (Exception e) {
+            return null;
+        }        
+    } 
+    
+    
+//    public static LocalDateTime parseS7DateTime(ReadBuffer io) {
+//        return null;    
+//        
+//    }   
+    
+    /*
+    * This is a specific solution for the DATE_AND_TIME data type. 
+    * The 12 bits they represent are capped at up to 999 in BCD.
+    */
+    public static BigInteger parseS7MsecToNsec(ReadBuffer io) {
+        BigInteger bint = BigInteger.ZERO; 
+        try {    
+            return bint.add(BigInteger.valueOf(S7msecToInt(io) * 1_000_000L));
+        } catch (ParseException ex) {
+            
+        }
+        return bint;
+    }      
+    
+    public static void serializeNsecToS7Msec(WriteBuffer io, int value) {
+        long ms = (long) (value / 1_000_000);
+        byte bhl6 = (byte) ((int) (((ms / 100) << 4) | ((ms / 10) % 10)));
+        byte bh_7 = (byte) ((ms % 10) << 4);
+        try {
+            io.writeByte(bhl6);
+            io.writeShort(4, bh_7);
+        } catch (SerializationException ex) {
+            Logger.getLogger(StaticHelper.class.getName()).log(Level.SEVERE, null, ex);
+        }                
+    } 
+    
+   public static BigInteger parseS7DayOfWeek(ReadBuffer io) throws ParseException {
+        BigInteger bint = io.readUnsignedBigInteger(4);
+        return bint;
+   }    
+   
+    public static void serializeS7DayOfWeek(WriteBuffer io, int value) throws SerializationException {
+        short dayofweek = (short) ((value < 7) ? value + 1 : 1);
+        io.writeShort(4, dayofweek); 
+    }   
+    
 
     //TODO: Call BCD converter
     public static LocalDateTime parseTiaDateTime(ReadBuffer io) {
diff --git a/protocols/bacnetip/src/main/generated/protocols/bacnetip/bacnet-vendorids.mspec b/protocols/bacnetip/src/main/generated/protocols/bacnetip/bacnet-vendorids.mspec
index b49f4330af..60c5013226 100644
--- a/protocols/bacnetip/src/main/generated/protocols/bacnetip/bacnet-vendorids.mspec
+++ b/protocols/bacnetip/src/main/generated/protocols/bacnetip/bacnet-vendorids.mspec
@@ -1469,12 +1469,6 @@
   ['1454' GRID_CONNECT_INC ['1454', '"Grid Connect Inc."']]
   ['1455' ZIEGLER_INSTRUMENTATIONUK_LTD ['1455', '"Ziegler Instrumentation UK Ltd"']]
   ['1456' CONTROL_TECLLC ['1456', '"ControlTec, LLC"']]
-  ['1457' AETERLINK_CORPORATION ['1457', '"Aeterlink Corporation"']]
-  ['1458' ALPHA_EPSILON_AUTOMATION ['1458', '"Alpha Epsilon Automation"']]
-  ['1459' ASTRALITE_INC ['1459', '"Astralite Inc."']]
-  ['1460' DELTA_FIRE_LTDA ['1460', '"Delta Fire Ltda."']]
-  ['1461' BOCK_WATER_HEATERS_INC ['1461', '"Bock Water Heaters, Inc."']]
-  ['1462' CLEAVER_BROOKS ['1462', '"Cleaver-Brooks"']]
  
   ['0xFFFF' UNKNOWN_VENDOR ['0xFFFF', '"Unknown"']]
 ]
diff --git a/protocols/s7/src/main/resources/protocols/s7/s7.mspec b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
index 89c4fbaafe..e7a608e3d1 100644
--- a/protocols/s7/src/main/resources/protocols/s7/s7.mspec
+++ b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
@@ -801,17 +801,26 @@
         ['"IEC61131_LTIME_OF_DAY"' LTIME_OF_DAY
             [simple uint 64 nanosecondsSinceMidnight]
         ]
+
         // - Date & Time: interpreted as individual components.
+        //Note: 
+        //1. Bit size 64 is used to generate the BigInteger type object. 
+        //   Any other size generates the variable of the primitive type, 
+        //   which prevents the call to create the instance of the object
+        //   in the DataItem class from being generated.
+        //2. The "dayOfWeek" field is taken from the PLC, but is unused 
+        //   since it is generated internally in the LocalDateTime instances.
         ['"IEC61131_DATE_AND_TIME"' DATE_AND_TIME
-            [simple uint 16 year]
-            [simple uint 8  month]
-            [simple uint 8  day]
-            [simple uint 8  dayOfWeek]
-            [simple uint 8  hour]
-            [simple uint 8  minutes]
-            [simple uint 8  seconds]
-            [simple uint 32 nanoseconds]
+            [manual uint 64  year        'STATIC_CALL("parseBcdToByte", readBuffer)'    'STATIC_CALL("ByteToBcd", writeBuffer, _value.DateTime().Year())'    '8']
+            [manual uint 64  month       'STATIC_CALL("parseBcdToByte", readBuffer)'    'STATIC_CALL("ByteToBcd", writeBuffer, _value.DateTime().MonthValue())'    '8']
+            [manual uint 64  day         'STATIC_CALL("parseBcdToByte", readBuffer)'    'STATIC_CALL("ByteToBcd", writeBuffer, _value.DateTime().DayOfMonth())'    '8']
+            [manual uint 64  hour        'STATIC_CALL("parseBcdToByte", readBuffer)'    'STATIC_CALL("ByteToBcd", writeBuffer, _value.DateTime().Hour())'    '8']
+            [manual uint 64  minutes     'STATIC_CALL("parseBcdToByte", readBuffer)'    'STATIC_CALL("ByteToBcd", writeBuffer, _value.DateTime().Minute())'    '8']
+            [manual uint 64  seconds     'STATIC_CALL("parseBcdToByte", readBuffer)'    'STATIC_CALL("ByteToBcd", writeBuffer, _value.DateTime().Second())'    '8']
+            [manual uint 64  nanoseconds 'STATIC_CALL("parseS7MsecToNsec", readBuffer)'   'STATIC_CALL("serializeNsecToS7Msec", writeBuffer, _value.DateTime().Nano())'   '8']  //(01)
+            [manual uint 64  dayOfWeek   'STATIC_CALL("parseS7DayOfWeek", readBuffer)'   'STATIC_CALL("serializeS7DayOfWeek", writeBuffer, _value.DateTime().DayOfWeek().Value())'   '8']         
         ]
+
         // - Date & Time: Interpreted as "number of nanoseconds since 1990-01-01"
         //['"IEC61131_LDATE_AND_TIME"' LDATE_AND_TIME
         //    [implicit uint 16 nanosecondsSinceSiemensEpoch 'nanosecondsSinceEpoch ...']
@@ -891,8 +900,8 @@
     ['0x17' DATE          ['0x09'     , 'X'             , '2'                 , 'null'                  , 'BYTE_WORD_DWORD'              , 'IEC61131_DATE'         , 'true'              , 'true'              , 'true'               , 'true'               , 'true'              ]]
     ['0x18' TIME_OF_DAY   ['0x06'     , 'X'             , '4'                 , 'null'                  , 'BYTE_WORD_DWORD'              , 'IEC61131_TIME_OF_DAY'  , 'true'              , 'true'              , 'true'               , 'true'               , 'true'              ]]
     ['0x19' TOD           ['0x06'     , 'X'             , '4'                 , 'null'                  , 'BYTE_WORD_DWORD'              , 'IEC61131_TIME_OF_DAY'  , 'true'              , 'true'              , 'true'               , 'true'               , 'true'              ]]
-    ['0x1A' DATE_AND_TIME ['0x0F'     , 'X'             , '12'                , 'null'                  , 'null'                         , 'IEC61131_DATE_AND_TIME', 'true'              , 'true'              , 'false'              , 'true'               , 'false'             ]]
-    ['0x1B' DT            ['0x0F'     , 'X'             , '12'                , 'null'                  , 'null'                         , 'IEC61131_DATE_AND_TIME', 'true'              , 'true'              , 'false'              , 'true'               , 'false'             ]]
+    ['0x1A' DATE_AND_TIME ['0x0F'     , 'X'             , '8'                 , 'null'                  , 'BYTE_WORD_DWORD'              , 'IEC61131_DATE_AND_TIME', 'true'              , 'true'              , 'false'              , 'true'               , 'false'             ]]
+    ['0x1B' DT            ['0x0F'     , 'B'             , '8'                 , 'null'                  , 'BYTE_WORD_DWORD'              , 'IEC61131_DATE_AND_TIME', 'true'              , 'true'              , 'false'              , 'true'               , 'false'             ]]
 ]
 
 [enum uint 8 MemoryArea(string 24 shortName)