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)
+}