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 2021/03/30 13:59:00 UTC

[plc4x] branch develop updated: - Fixed the handling of DATE_AND_TIME variants of ADS in Go

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


The following commit(s) were added to refs/heads/develop by this push:
     new a507848  - Fixed the handling of DATE_AND_TIME variants of ADS in Go
a507848 is described below

commit a507848230a80fb6f827c1320f248b28a9e96f76
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Tue Mar 30 15:56:24 2021 +0200

    - Fixed the handling of DATE_AND_TIME variants of ADS in Go
---
 .../plc4x/language/go/GoLanguageTemplateHelper.java      |  3 ++-
 .../main/resources/templates/go/data-io-template.ftlh    |  4 +++-
 .../main/resources/templates/java/data-io-template.ftlh  |  9 ++++++++-
 plc4go/internal/plc4go/ads/readwrite/model/DataItem.go   | 16 ++++++++++++++++
 .../java/org/apache/plc4x/test/manual/ManualTest.java    | 12 ++++++------
 protocols/ads/src/main/resources/protocols/ads/ads.mspec |  7 +++----
 6 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java b/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java
index c89f4a8..854d1d5 100644
--- a/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java
+++ b/build-utils/language-go/src/main/java/org/apache/plc4x/language/go/GoLanguageTemplateHelper.java
@@ -870,7 +870,8 @@ public class GoLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHelp
         if (dataIo.getSwitchField().getCases().stream().anyMatch(typeCase ->
             (typeCase.getName().equals("TIME_OF_DAY") && hasFieldsWithNames(typeCase.getFields(), "hour", "minutes", "seconds")) ||
                 (typeCase.getName().equals("DATE") && hasFieldsWithNames(typeCase.getFields(), "year", "month", "day")) ||
-                (typeCase.getName().equals("DATE_AND_TIME") && hasFieldsWithNames(typeCase.getFields(), "year", "month", "day", "hour", "minutes", "seconds")))) {
+                (typeCase.getName().equals("DATE_AND_TIME") && hasFieldsWithNames(typeCase.getFields(), "year", "month", "day", "hour", "minutes", "seconds")) ||
+                (typeCase.getName().equals("DATE_AND_TIME") && hasFieldsWithNames(typeCase.getFields(), "secondsSinceEpoch")))) {
             imports.add("\"time\"");
         }
         return imports;
diff --git a/build-utils/language-go/src/main/resources/templates/go/data-io-template.ftlh b/build-utils/language-go/src/main/resources/templates/go/data-io-template.ftlh
index 6448f7e..acb3cf4 100644
--- a/build-utils/language-go/src/main/resources/templates/go/data-io-template.ftlh
+++ b/build-utils/language-go/src/main/resources/templates/go/data-io-template.ftlh
@@ -123,7 +123,7 @@ func ${type.name}Parse(io *utils.ReadBuffer<#if type.parserArguments?has_content
 					<#assign simpleField = field>
 
 			// Simple Field (${field.name})
-			<#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 == "value">${field.na [...]
+			<#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") || (field.name == "secondsSinceEpoch"))) || ((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" [...]
 			if _${field.name}Err != nil {
 				return nil, errors.Wrap(_${field.name}Err, "Error parsing '${field.name}' field")
 			}
@@ -151,6 +151,8 @@ func ${type.name}Parse(io *utils.ReadBuffer<#if type.parserArguments?has_content
 				<#case "DATE_AND_TIME">
 					<#if helper.hasFieldsWithNames(case.fields, "year", "month", "day", "hour", "minutes", "seconds")>
 			value := time.Date(int(year), time.Month(month), int(day), int(hour), int(minutes), int(seconds), 0, nil)
+                    <#elseif helper.hasFieldsWithNames(case.fields, "secondsSinceEpoch")>
+            value := time.Unix(int64(secondsSinceEpoch), 0)
 					</#if>
 			return values.NewPlcDATE_AND_TIME(value), nil
 					<#break>
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 a384f6e..3fe784c 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
@@ -201,7 +201,12 @@ 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>
-                        <#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  [...]
+                        <#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_AND_TIME") && (field.name == "secondsSinceEpoch")) ||
+                            ((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 == "value">
                             <#assign valueDefined=true>
                         </#if>
                     <#break>
@@ -285,6 +290,8 @@ public class ${type.name}IO {
             LocalDateTime value = LocalDateTime.of(year.intValue(), (month == 0) ? 1 : month.intValue(), (day == 0) ? 1 : 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 == 0) ? 1 : month.intValue(), (day == 0) ? 1 : day.intValue(), hour.intValue(), minutes.intValue(), seconds.intValue());
+                    <#elseif helper.hasFieldsWithNames(case.fields, "secondsSinceEpoch")>
+            LocalDateTime value = LocalDateTime.ofEpochSecond(secondsSinceEpoch, 0, ZoneOffset.UTC);
                     </#if>
             return new PlcDATE_AND_TIME(value);
                     <#break>
diff --git a/plc4go/internal/plc4go/ads/readwrite/model/DataItem.go b/plc4go/internal/plc4go/ads/readwrite/model/DataItem.go
index e52f342..d535c6c 100644
--- a/plc4go/internal/plc4go/ads/readwrite/model/DataItem.go
+++ b/plc4go/internal/plc4go/ads/readwrite/model/DataItem.go
@@ -23,6 +23,7 @@ import (
 	"github.com/apache/plc4x/plc4go/internal/plc4go/spi/values"
 	api "github.com/apache/plc4x/plc4go/pkg/plc4go/values"
 	"github.com/pkg/errors"
+	"time"
 )
 
 // Code generated by build-utils. DO NOT EDIT.
@@ -196,6 +197,15 @@ func DataItemParse(io *utils.ReadBuffer, dataFormatName string, stringLength int
 			return nil, errors.Wrap(_valueErr, "Error parsing 'value' field")
 		}
 		return values.NewPlcTIME_OF_DAY(value), nil
+	case dataFormatName == "IEC61131_DATE_AND_TIME": // DATE_AND_TIME
+
+		// Simple Field (secondsSinceEpoch)
+		secondsSinceEpoch, _secondsSinceEpochErr := io.ReadUint32(32)
+		if _secondsSinceEpochErr != nil {
+			return nil, errors.Wrap(_secondsSinceEpochErr, "Error parsing 'secondsSinceEpoch' field")
+		}
+		value := time.Unix(int64(secondsSinceEpoch), 0)
+		return values.NewPlcDATE_AND_TIME(value), nil
 	}
 	// TODO: add more info which type it is actually
 	return nil, errors.New("unsupported type")
@@ -332,6 +342,12 @@ func DataItemSerialize(io *utils.WriteBuffer, value api.PlcValue, dataFormatName
 		if _err := io.WriteUint32(32, value.GetUint32()); _err != nil {
 			return errors.Wrap(_err, "Error serializing 'value' field")
 		}
+	case dataFormatName == "IEC61131_DATE_AND_TIME": // DATE_AND_TIME
+
+		// Simple Field (secondsSinceEpoch)
+		if _err := io.WriteUint32(32, value.GetUint32()); _err != nil {
+			return errors.Wrap(_err, "Error serializing 'secondsSinceEpoch' field")
+		}
 	default:
 		// TODO: add more info which type it is actually
 		return errors.New("unsupported type")
diff --git a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java
index cb88745..9ed1a1f 100644
--- a/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java
+++ b/plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/manual/ManualTest.java
@@ -57,19 +57,19 @@ public abstract class ManualTest {
                 final PlcReadResponse readResponse = readRequest.execute().get();
 
                 // Check the result
-                Assertions.assertEquals(1, readResponse.getFieldNames().size());
-                Assertions.assertEquals(fieldName, readResponse.getFieldNames().iterator().next());
-                Assertions.assertEquals(PlcResponseCode.OK, readResponse.getResponseCode(fieldName));
-                Assertions.assertNotNull(readResponse.getPlcValue(fieldName));
+                Assertions.assertEquals(1, readResponse.getFieldNames().size(), fieldName);
+                Assertions.assertEquals(fieldName, readResponse.getFieldNames().iterator().next(), fieldName);
+                Assertions.assertEquals(PlcResponseCode.OK, readResponse.getResponseCode(fieldName), fieldName);
+                Assertions.assertNotNull(readResponse.getPlcValue(fieldName), fieldName);
                 if(readResponse.getPlcValue(fieldName) instanceof PlcList) {
                     PlcList plcList = (PlcList) readResponse.getPlcValue(fieldName);
                     List<Object> expectedValues = (List<Object>) testCase.expectedReadValue;
                     for (int j = 0; j < expectedValues.size(); j++) {
-                        Assertions.assertEquals(expectedValues.get(j), plcList.getIndex(j).getObject());
+                        Assertions.assertEquals(expectedValues.get(j), plcList.getIndex(j).getObject(), fieldName + "[" + j + "]");
                     }
                 } else {
                     Assertions.assertEquals(
-                        testCase.expectedReadValue.toString(), readResponse.getPlcValue(fieldName).getObject().toString());
+                        testCase.expectedReadValue.toString(), readResponse.getPlcValue(fieldName).getObject().toString(), fieldName);
                 }
             }
             System.out.println("Success");
diff --git a/protocols/ads/src/main/resources/protocols/ads/ads.mspec b/protocols/ads/src/main/resources/protocols/ads/ads.mspec
index 99b4e24..8e4fae8 100644
--- a/protocols/ads/src/main/resources/protocols/ads/ads.mspec
+++ b/protocols/ads/src/main/resources/protocols/ads/ads.mspec
@@ -490,10 +490,9 @@
             [simple uint 32 'value']
         ]
         // Interpreted as "seconds since epoch"
-        // TODO: Fix this
-        //['IEC61131_DATE_AND_TIME' DATE_AND_TIME
-        //    [simple uint 32 'value']
-        //]
+        ['IEC61131_DATE_AND_TIME' DATE_AND_TIME
+            [simple uint 32 'secondsSinceEpoch']
+        ]
     ]
 ]