You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2024/02/06 12:22:14 UTC

(plc4x) branch develop updated: feat(plc4go): support for DATE_AND_LTIME

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

sruehl 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 51434bd8bd feat(plc4go): support for DATE_AND_LTIME
51434bd8bd is described below

commit 51434bd8bde1b43785d83d5665566a4bdcb0561b
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Tue Feb 6 13:22:06 2024 +0100

    feat(plc4go): support for DATE_AND_LTIME
---
 .../templates/go/data-io-template.go.ftlh          |   9 ++
 plc4go/pkg/api/values/plc_value.go                 |   3 +-
 plc4go/protocols/s7/readwrite/model/DataItem.go    |   5 +-
 plc4go/spi/values/PlcDATE_AND_LTIME.go             | 132 +++++++++++++++++++++
 4 files changed, 145 insertions(+), 4 deletions(-)

diff --git a/code-generation/language-go/src/main/resources/templates/go/data-io-template.go.ftlh b/code-generation/language-go/src/main/resources/templates/go/data-io-template.go.ftlh
index 7782f4bff7..4c37061ddc 100644
--- a/code-generation/language-go/src/main/resources/templates/go/data-io-template.go.ftlh
+++ b/code-generation/language-go/src/main/resources/templates/go/data-io-template.go.ftlh
@@ -177,6 +177,7 @@ func ${type.name}ParseWithBuffer(ctx context.Context, readBuffer utils.ReadBuffe
 				|| (simpleField.name == "seconds")
 				|| (simpleField.name == "nanoseconds")
 				|| (simpleField.name == "nannosecondsOfSecond")
+				|| (simpleField.name == "nanosecondsSinceEpoch")
 				|| (simpleField.name == "dayOfWeek")
 				)
 			)
@@ -258,6 +259,14 @@ func ${type.name}ParseWithBuffer(ctx context.Context, readBuffer utils.ReadBuffe
 			return values.NewPlcDATA_AND_TIMEFromSecondsSinceEpoch(secondsSinceEpoch), nil
                 </#if>
                 <#break>
+            <#case "DATE_AND_LTIME">
+			readBuffer.CloseContext("${type.name}")
+                <#if helper.hasFieldsWithNames(case.fields, "year", "month", "day", "hour", "minutes", "seconds", "nanoseconds")>
+			return values.NewPlcDATA_AND_LTIMEFromSegments(uint32(year), uint32(month), uint32(day), uint32(hour), uint32(minutes), uint32(seconds), uint32(nanoseconds)), nil
+                <#elseif helper.hasFieldsWithNames(case.fields, "nanosecondsSinceEpoch")>
+			return values.NewPlcDATA_AND_LTIMEFromNanosecondsSinceEpoch(nanosecondsSinceEpoch), nil
+                </#if>
+                <#break>
             <#case "LDATE_AND_TIME">
 			readBuffer.CloseContext("${type.name}")
                 <#if helper.hasFieldsWithNames(case.fields, "nanosecondsSinceEpoch")>
diff --git a/plc4go/pkg/api/values/plc_value.go b/plc4go/pkg/api/values/plc_value.go
index 614aa68aaa..673c5a30fc 100644
--- a/plc4go/pkg/api/values/plc_value.go
+++ b/plc4go/pkg/api/values/plc_value.go
@@ -237,7 +237,8 @@ const (
 	TIME_OF_DAY    PlcValueType = 0x55
 	LTIME_OF_DAY   PlcValueType = 0x56
 	DATE_AND_TIME  PlcValueType = 0x57
-	LDATE_AND_TIME PlcValueType = 0x58
+	DATE_AND_LTIME PlcValueType = 0x58
+	LDATE_AND_TIME PlcValueType = 0x59
 	Struct         PlcValueType = 0x61
 	List           PlcValueType = 0x62
 	RAW_BYTE_ARRAY PlcValueType = 0x71
diff --git a/plc4go/protocols/s7/readwrite/model/DataItem.go b/plc4go/protocols/s7/readwrite/model/DataItem.go
index a99f65e9be..3197e939ac 100644
--- a/plc4go/protocols/s7/readwrite/model/DataItem.go
+++ b/plc4go/protocols/s7/readwrite/model/DataItem.go
@@ -328,13 +328,13 @@ func DataItemParseWithBuffer(ctx context.Context, readBuffer utils.ReadBuffer, d
 		readBuffer.CloseContext("DataItem")
 	case dataProtocolId == "IEC61131_DATE_AND_LTIME": // DATE_AND_LTIME
 		// Simple Field (nanosecondsSinceEpoch)
-		_, _nanosecondsSinceEpochErr := readBuffer.ReadUint64("nanosecondsSinceEpoch", 64)
+		nanosecondsSinceEpoch, _nanosecondsSinceEpochErr := readBuffer.ReadUint64("nanosecondsSinceEpoch", 64)
 		if _nanosecondsSinceEpochErr != nil {
 			return nil, errors.Wrap(_nanosecondsSinceEpochErr, "Error parsing 'nanosecondsSinceEpoch' field")
 		}
 		_ = nanosecondsSinceEpoch // TODO: temporary till we fix TIME stuff in golang (see above in the template)
 		readBuffer.CloseContext("DataItem")
-		return values.NewPlcDATE_AND_LTIME(value), nil
+		return values.NewPlcDATA_AND_LTIMEFromNanosecondsSinceEpoch(nanosecondsSinceEpoch), nil
 	case dataProtocolId == "IEC61131_DTL": // DATE_AND_LTIME
 		// Simple Field (year)
 		year, _yearErr := readBuffer.ReadUint16("year", 16)
@@ -392,7 +392,6 @@ func DataItemParseWithBuffer(ctx context.Context, readBuffer utils.ReadBuffer, d
 		}
 		_ = nannosecondsOfSecond // TODO: temporary till we fix TIME stuff in golang (see above in the template)
 		readBuffer.CloseContext("DataItem")
-		return values.NewPlcDATE_AND_LTIME(value), nil
 	}
 	// TODO: add more info which type it is actually
 	return nil, errors.New("unsupported type")
diff --git a/plc4go/spi/values/PlcDATE_AND_LTIME.go b/plc4go/spi/values/PlcDATE_AND_LTIME.go
new file mode 100644
index 0000000000..6ec332080e
--- /dev/null
+++ b/plc4go/spi/values/PlcDATE_AND_LTIME.go
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package values
+
+import (
+	"context"
+	"encoding/binary"
+	"fmt"
+	"time"
+
+	apiValues "github.com/apache/plc4x/plc4go/pkg/api/values"
+	"github.com/apache/plc4x/plc4go/spi/utils"
+)
+
+type PlcDATE_AND_LTIME struct {
+	PlcValueAdapter
+	value time.Time
+}
+
+func NewPlcDATE_AND_LTIME(value time.Time) PlcDATE_AND_LTIME {
+	return PlcDATE_AND_LTIME{
+		value: value,
+	}
+}
+
+func NewPlcDATA_AND_LTIMEFromSegments(year, month, day, hour, minutes, seconds, nanoseconds uint32) PlcDATE_AND_LTIME {
+	return NewPlcDATE_AND_LTIME(time.Date(int(year), time.Month(month), int(day), int(hour), int(minutes), int(seconds), int(nanoseconds), time.Local))
+}
+
+func NewPlcDATA_AND_LTIMEFromNanosecondsSinceEpoch(nanosecondsSinceEpoch uint64) PlcDATE_AND_LTIME {
+	timeStamp := time.Time{}
+	timeStamp.Add(time.Duration(nanosecondsSinceEpoch) * time.Nanosecond)
+	return NewPlcDATE_AND_LTIME(timeStamp)
+}
+
+func (m PlcDATE_AND_LTIME) IsRaw() bool {
+	return true
+}
+
+func (m PlcDATE_AND_LTIME) GetRaw() []byte {
+	theBytes, _ := m.Serialize()
+	return theBytes
+}
+
+func (m PlcDATE_AND_LTIME) GetSecondsSinceEpoch() uint32 {
+	return uint32(m.value.Unix())
+}
+
+func (m PlcDATE_AND_LTIME) GetYear() uint16 {
+	return uint16(m.value.Year())
+}
+
+func (m PlcDATE_AND_LTIME) GetMonth() uint8 {
+	return uint8(m.value.Month())
+}
+
+func (m PlcDATE_AND_LTIME) GetDay() uint8 {
+	return uint8(m.value.Day())
+}
+
+func (m PlcDATE_AND_LTIME) GetDayOfWeek() uint8 {
+	return uint8(m.value.Weekday())
+}
+
+func (m PlcDATE_AND_LTIME) GetHour() uint8 {
+	return uint8(m.value.Hour())
+}
+
+func (m PlcDATE_AND_LTIME) GetMinutes() uint8 {
+	return uint8(m.value.Minute())
+}
+
+func (m PlcDATE_AND_LTIME) GetSeconds() uint8 {
+	return uint8(m.value.Second())
+}
+
+func (m PlcDATE_AND_LTIME) GetNanoseconds() uint32 {
+	return uint32(m.value.Nanosecond())
+}
+
+func (m PlcDATE_AND_LTIME) GetMillisecondsOfSecond() uint64 {
+	return uint64(time.Duration(m.GetNanoseconds()).Milliseconds())
+}
+
+func (m PlcDATE_AND_LTIME) IsDateTime() bool {
+	return true
+}
+
+func (m PlcDATE_AND_LTIME) GetDateTime() time.Time {
+	return m.value
+}
+
+func (m PlcDATE_AND_LTIME) GetString() string {
+	return fmt.Sprintf("%v", m.GetDateTime())
+}
+
+func (m PlcDATE_AND_LTIME) GetPlcValueType() apiValues.PlcValueType {
+	return apiValues.DATE_AND_LTIME
+}
+
+func (m PlcDATE_AND_LTIME) Serialize() ([]byte, error) {
+	wb := utils.NewWriteBufferByteBased(utils.WithByteOrderForByteBasedBuffer(binary.BigEndian))
+	if err := m.SerializeWithWriteBuffer(context.Background(), wb); err != nil {
+		return nil, err
+	}
+	return wb.GetBytes(), nil
+}
+
+func (m PlcDATE_AND_LTIME) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error {
+	return writeBuffer.WriteString("PlcDATE_AND_LTIME", uint32(len([]rune(m.GetString()))*8), "UTF-8", m.GetString())
+}
+
+func (m PlcDATE_AND_LTIME) String() string {
+	return fmt.Sprintf("%s(%dbit):%v", m.GetPlcValueType(), uint32(len([]rune(m.GetString()))*8), m.value)
+}