You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2020/12/09 19:29:55 UTC

[plc4x] 03/03: - Improve the reading of S7 Date and Time handling

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

cdutz pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git

commit 9c25eb319f5c4e9192d4fc6a4abf5bedc3838c0c
Author: cdutz <ch...@c-ware.de>
AuthorDate: Wed Dec 9 20:29:32 2020 +0100

    - Improve the reading of S7 Date and Time handling
---
 .../main/resources/templates/java/data-io-template.ftlh   | 15 ++++++++++++++-
 .../java/org/apache/plc4x/java/spi/values/PlcLTIME.java   |  5 +++++
 protocols/s7/src/main/resources/protocols/s7/s7.mspec     | 11 ++++++++---
 3 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/build-utils/language-java/src/main/resources/templates/java/data-io-template.ftlh b/build-utils/language-java/src/main/resources/templates/java/data-io-template.ftlh
index 0f36832..1aec527 100644
--- a/build-utils/language-java/src/main/resources/templates/java/data-io-template.ftlh
+++ b/build-utils/language-java/src/main/resources/templates/java/data-io-template.ftlh
@@ -188,7 +188,7 @@ public class ${type.name}IO {
 
             // Simple Field (${field.name})
             ${helper.getNonPrimitiveLanguageTypeNameForField(field)} ${field.name} = <#if helper.isSimpleTypeReference(field.type)>${helper.getReadBufferReadMethodCall(field.type)}<#else>${field.type.name}IO.staticParse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getLanguageTypeNameForTypeReference(helper.getArgumentType(field.type, parserArgument?index), true)}) (${helper.toParseExpression(field, parserArgument, type.parserArguments)})<#sep>, </#sep [...]
-                        <#if field.name == "value">
+                        <#if case.name == "Struct" || ((case.name == "DATE_AND_TIME") && ((field.name == "year") || (field.name == "month") || (field.name == "day") || (field.name == "hour") || (field.name == "minutes") || (field.name == "seconds"))) || ((case.name == "DATE") && ((field.name == "year") || (field.name == "month") || (field.name == "day"))) || ((case.name == "TIME_OF_DAY") && ((field.name == "hour") || (field.name == "minutes") || (field.name == "seconds"))) || field.name  [...]
                             <#assign valueDefined=true>
                         </#if>
                     <#break>
@@ -252,12 +252,25 @@ public class ${type.name}IO {
             return new PlcTIME(value);
                     <#break>
                     <#case "DATE">
+                    <#if helper.hasFieldsWithNames(case.fields, "year", "month", "day")>
+            LocalDate value = LocalDate.of(year.intValue(), month.intValue(), day.intValue());
+                    </#if>
             return new PlcDATE(value);
                     <#break>
                     <#case "TIME_OF_DAY">
+                    <#if helper.hasFieldsWithNames(case.fields, "hour", "minutes", "seconds", "nanos")>
+            LocalTime value = LocalTime.of(hour.intValue(), minutes.intValue(), seconds.intValue(), nanos.intValue());
+                    <#elseif helper.hasFieldsWithNames(case.fields, "hour", "minutes", "seconds")>
+            LocalTime value = LocalTime.of(hour.intValue(), minutes.intValue(), seconds.intValue());
+                    </#if>
             return new PlcTIME_OF_DAY(value);
                     <#break>
                     <#case "DATE_AND_TIME">
+                    <#if helper.hasFieldsWithNames(case.fields, "year", "month", "day", "hour", "minutes", "seconds", "nanos")>
+            LocalDateTime value = LocalDateTime.of(year.intValue(), month.intValue(), day.intValue(), hour.intValue(), minutes.intValue(), seconds.intValue(), nanos.intValue());
+                    <#elseif helper.hasFieldsWithNames(case.fields, "year", "month", "day", "hour", "minutes", "seconds")>
+            LocalDateTime value = LocalDateTime.of(year.intValue(), month.intValue(), day.intValue(), hour.intValue(), minutes.intValue(), seconds.intValue());
+                    </#if>
             return new PlcDATE_AND_TIME(value);
                     <#break>
                     <#case "Struct">
diff --git a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLTIME.java b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLTIME.java
index 206cc72..6e0bfbe 100644
--- a/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLTIME.java
+++ b/plc4j/spi/src/main/java/org/apache/plc4x/java/spi/values/PlcLTIME.java
@@ -25,6 +25,7 @@ import com.fasterxml.jackson.annotation.JsonTypeInfo;
 import org.apache.plc4x.java.api.exceptions.PlcRuntimeException;
 import org.w3c.dom.Element;
 
+import java.math.BigInteger;
 import java.time.Duration;
 import java.time.temporal.ChronoUnit;
 
@@ -55,6 +56,10 @@ public class PlcLTIME extends PlcSimpleValue<Duration> {
         super(Duration.of(value, ChronoUnit.NANOS), true);
     }
 
+    public PlcLTIME(@JsonProperty("value") BigInteger value) {
+        super(Duration.of(value.longValue(), ChronoUnit.NANOS), true);
+    }
+
     @Override
     @JsonIgnore
     public boolean isString() {
diff --git a/protocols/s7/src/main/resources/protocols/s7/s7.mspec b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
index 578a4d6..9d32e1b 100644
--- a/protocols/s7/src/main/resources/protocols/s7/s7.mspec
+++ b/protocols/s7/src/main/resources/protocols/s7/s7.mspec
@@ -353,9 +353,14 @@
         ['IEC61131_TIME' TIME
             [simple uint 32 'value']
         ]
-        ['S7_S5TIME' TIME
-        ]
+        //['S7_S5TIME' TIME
+        //    [reserved uint 2  '0x00']
+        //    [uint     uint 2  'base']
+        //    [simple   uint 12 'value']
+        //]
+        // Interpreted as "number of nanoseconds"
         ['IEC61131_LTIME' LTIME
+            [simple uint 64 'value']
         ]
         // Interpreted as "number of days since 1990-01-01"
         ['IEC61131_DATE' DATE
@@ -443,7 +448,7 @@
 
     // Dates and time values (Please note that we seem to have to rewrite queries for these types to reading bytes or we'll get "Data type not supported" errors)
     ['0x0B' TIME             ['X'              , '4'                 , 'null'                  , 'null'                               , 'IEC61131_TIME'         , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
-    ['0x0C' S5TIME           ['X'              , '4'                 , 'null'                  , 'null'                               , 'S7_S5TIME'             , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
+    //['0x0C' S5TIME           ['X'              , '4'                 , 'null'                  , 'null'                               , 'S7_S5TIME'             , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
     ['0x00' LTIME            ['X'              , '8'                 , 'TransportSize.TIME'    , 'null'                               , 'IEC61131_LTIME'        , 'false'               , 'false'               , 'false'                , 'true'                 , 'false'             ]]
     ['0x09' DATE             ['X'              , '2'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD'  , 'IEC61131_DATE'         , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]
     ['0x06' TIME_OF_DAY      ['X'              , '4'                 , 'null'                  , 'DataTransportSize.BYTE_WORD_DWORD'  , 'IEC61131_TIME_OF_DAY'  , 'true'                , 'true'                , 'true'                 , 'true'                 , 'true'              ]]