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 2022/06/07 12:14:27 UTC

[plc4x] 02/02: feat(bacnet): implemented unique properties for global group type

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

commit 7ed03bfc118e0efca155f7231fbfba25e99306af
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Tue Jun 7 14:14:19 2022 +0200

    feat(bacnet): implemented unique properties for global group type
    
    - COVU_PERIOD
    - COVU_RECIPIENTS
    - GROUP_MEMBER_NAMES
    - MEMBER_STATUS_FLAGS
    - REQUESTED_UPDATE_INTERVAL
---
 .../readwrite/model/BACnetConstructedData.go       |  10 +
 .../model/BACnetConstructedDataCOVUPeriod.go       | 211 +++++++++++++++++++
 .../model/BACnetConstructedDataCOVURecipients.go   | 226 +++++++++++++++++++++
 .../model/BACnetConstructedDataGroupMemberNames.go | 226 +++++++++++++++++++++
 .../BACnetConstructedDataMemberStatusFlags.go      | 211 +++++++++++++++++++
 ...BACnetConstructedDataRequestedUpdateInterval.go | 211 +++++++++++++++++++
 .../resources/protocols/bacnetip/bacnetip.mspec    |  26 ++-
 .../bacnetip/ObjectPropertyDeDuplicationTest.java  |   6 +
 8 files changed, 1122 insertions(+), 5 deletions(-)

diff --git a/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedData.go b/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedData.go
index b8c3d438d4..f009266469 100644
--- a/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedData.go
+++ b/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedData.go
@@ -416,6 +416,10 @@ func BACnetConstructedDataParse(readBuffer utils.ReadBuffer, tagNumber uint8, ob
 		_child, typeSwitchError = BACnetConstructedDataCOVIncrementParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
 	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_COV_PERIOD: // BACnetConstructedDataCOVPeriod
 		_child, typeSwitchError = BACnetConstructedDataCOVPeriodParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
+	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_COVU_PERIOD: // BACnetConstructedDataCOVUPeriod
+		_child, typeSwitchError = BACnetConstructedDataCOVUPeriodParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
+	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_COVU_RECIPIENTS: // BACnetConstructedDataCOVURecipients
+		_child, typeSwitchError = BACnetConstructedDataCOVURecipientsParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
 	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_CREDENTIAL_DISABLE: // BACnetConstructedDataCredentialDisable
 		_child, typeSwitchError = BACnetConstructedDataCredentialDisableParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
 	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_CREDENTIAL_STATUS: // BACnetConstructedDataCredentialStatus
@@ -514,6 +518,8 @@ func BACnetConstructedDataParse(readBuffer utils.ReadBuffer, tagNumber uint8, ob
 		_child, typeSwitchError = BACnetConstructedDataFloorTextParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
 	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_FULL_DUTY_BASELINE: // BACnetConstructedDataFullDutyBaseline
 		_child, typeSwitchError = BACnetConstructedDataFullDutyBaselineParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
+	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_GROUP_MEMBER_NAMES: // BACnetConstructedDataGroupMemberNames
+		_child, typeSwitchError = BACnetConstructedDataGroupMemberNamesParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
 	case objectTypeArgument == BACnetObjectType_ACCUMULATOR && propertyIdentifierArgument == BACnetPropertyIdentifier_HIGH_LIMIT: // BACnetConstructedDataAccumulatorHighLimit
 		_child, typeSwitchError = BACnetConstructedDataAccumulatorHighLimitParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
 	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_HIGH_LIMIT: // BACnetConstructedDataHighLimit
@@ -640,6 +646,8 @@ func BACnetConstructedDataParse(readBuffer utils.ReadBuffer, tagNumber uint8, ob
 		_child, typeSwitchError = BACnetConstructedDataMaximumOutputParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
 	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_MEMBER_OF: // BACnetConstructedDataMemberOf
 		_child, typeSwitchError = BACnetConstructedDataMemberOfParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
+	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_MEMBER_STATUS_FLAGS: // BACnetConstructedDataMemberStatusFlags
+		_child, typeSwitchError = BACnetConstructedDataMemberStatusFlagsParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
 	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_MEMBERS: // BACnetConstructedDataMembers
 		_child, typeSwitchError = BACnetConstructedDataMembersParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
 	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_MIN_ACTUAL_VALUE: // BACnetConstructedDataMinActualValue
@@ -742,6 +750,8 @@ func BACnetConstructedDataParse(readBuffer utils.ReadBuffer, tagNumber uint8, ob
 		_child, typeSwitchError = BACnetConstructedDataRepresentsParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
 	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_REQUESTED_SHED_LEVEL: // BACnetConstructedDataRequestedShedLevel
 		_child, typeSwitchError = BACnetConstructedDataRequestedShedLevelParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
+	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_REQUESTED_UPDATE_INTERVAL: // BACnetConstructedDataRequestedUpdateInterval
+		_child, typeSwitchError = BACnetConstructedDataRequestedUpdateIntervalParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
 	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_RESOLUTION: // BACnetConstructedDataResolution
 		_child, typeSwitchError = BACnetConstructedDataResolutionParse(readBuffer, tagNumber, objectTypeArgument, propertyIdentifierArgument)
 	case true && propertyIdentifierArgument == BACnetPropertyIdentifier_ROUTING_TABLE: // BACnetConstructedDataRoutingTable
diff --git a/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedDataCOVUPeriod.go b/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedDataCOVUPeriod.go
new file mode 100644
index 0000000000..c5bb455f54
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedDataCOVUPeriod.go
@@ -0,0 +1,211 @@
+/*
+ * 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
+ *
+ *   http://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 model
+
+import (
+	"github.com/apache/plc4x/plc4go/internal/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// BACnetConstructedDataCOVUPeriod is the data-structure of this message
+type BACnetConstructedDataCOVUPeriod struct {
+	*BACnetConstructedData
+	CovuPeriod *BACnetApplicationTagUnsignedInteger
+
+	// Arguments.
+	TagNumber uint8
+}
+
+// IBACnetConstructedDataCOVUPeriod is the corresponding interface of BACnetConstructedDataCOVUPeriod
+type IBACnetConstructedDataCOVUPeriod interface {
+	IBACnetConstructedData
+	// GetCovuPeriod returns CovuPeriod (property field)
+	GetCovuPeriod() *BACnetApplicationTagUnsignedInteger
+	// GetLengthInBytes returns the length in bytes
+	GetLengthInBytes() uint16
+	// GetLengthInBits returns the length in bits
+	GetLengthInBits() uint16
+	// Serialize serializes this type
+	Serialize(writeBuffer utils.WriteBuffer) error
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *BACnetConstructedDataCOVUPeriod) GetObjectTypeArgument() BACnetObjectType {
+	return 0
+}
+
+func (m *BACnetConstructedDataCOVUPeriod) GetPropertyIdentifierArgument() BACnetPropertyIdentifier {
+	return BACnetPropertyIdentifier_COVU_PERIOD
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *BACnetConstructedDataCOVUPeriod) InitializeParent(parent *BACnetConstructedData, openingTag *BACnetOpeningTag, closingTag *BACnetClosingTag) {
+	m.BACnetConstructedData.OpeningTag = openingTag
+	m.BACnetConstructedData.ClosingTag = closingTag
+}
+
+func (m *BACnetConstructedDataCOVUPeriod) GetParent() *BACnetConstructedData {
+	return m.BACnetConstructedData
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *BACnetConstructedDataCOVUPeriod) GetCovuPeriod() *BACnetApplicationTagUnsignedInteger {
+	return m.CovuPeriod
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewBACnetConstructedDataCOVUPeriod factory function for BACnetConstructedDataCOVUPeriod
+func NewBACnetConstructedDataCOVUPeriod(covuPeriod *BACnetApplicationTagUnsignedInteger, openingTag *BACnetOpeningTag, closingTag *BACnetClosingTag, tagNumber uint8) *BACnetConstructedDataCOVUPeriod {
+	_result := &BACnetConstructedDataCOVUPeriod{
+		CovuPeriod:            covuPeriod,
+		BACnetConstructedData: NewBACnetConstructedData(openingTag, closingTag, tagNumber),
+	}
+	_result.Child = _result
+	return _result
+}
+
+func CastBACnetConstructedDataCOVUPeriod(structType interface{}) *BACnetConstructedDataCOVUPeriod {
+	if casted, ok := structType.(BACnetConstructedDataCOVUPeriod); ok {
+		return &casted
+	}
+	if casted, ok := structType.(*BACnetConstructedDataCOVUPeriod); ok {
+		return casted
+	}
+	if casted, ok := structType.(BACnetConstructedData); ok {
+		return CastBACnetConstructedDataCOVUPeriod(casted.Child)
+	}
+	if casted, ok := structType.(*BACnetConstructedData); ok {
+		return CastBACnetConstructedDataCOVUPeriod(casted.Child)
+	}
+	return nil
+}
+
+func (m *BACnetConstructedDataCOVUPeriod) GetTypeName() string {
+	return "BACnetConstructedDataCOVUPeriod"
+}
+
+func (m *BACnetConstructedDataCOVUPeriod) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *BACnetConstructedDataCOVUPeriod) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Simple field (covuPeriod)
+	lengthInBits += m.CovuPeriod.GetLengthInBits()
+
+	return lengthInBits
+}
+
+func (m *BACnetConstructedDataCOVUPeriod) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func BACnetConstructedDataCOVUPeriodParse(readBuffer utils.ReadBuffer, tagNumber uint8, objectTypeArgument BACnetObjectType, propertyIdentifierArgument BACnetPropertyIdentifier) (*BACnetConstructedDataCOVUPeriod, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("BACnetConstructedDataCOVUPeriod"); pullErr != nil {
+		return nil, pullErr
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (covuPeriod)
+	if pullErr := readBuffer.PullContext("covuPeriod"); pullErr != nil {
+		return nil, pullErr
+	}
+	_covuPeriod, _covuPeriodErr := BACnetApplicationTagParse(readBuffer)
+	if _covuPeriodErr != nil {
+		return nil, errors.Wrap(_covuPeriodErr, "Error parsing 'covuPeriod' field")
+	}
+	covuPeriod := CastBACnetApplicationTagUnsignedInteger(_covuPeriod)
+	if closeErr := readBuffer.CloseContext("covuPeriod"); closeErr != nil {
+		return nil, closeErr
+	}
+
+	if closeErr := readBuffer.CloseContext("BACnetConstructedDataCOVUPeriod"); closeErr != nil {
+		return nil, closeErr
+	}
+
+	// Create a partially initialized instance
+	_child := &BACnetConstructedDataCOVUPeriod{
+		CovuPeriod:            CastBACnetApplicationTagUnsignedInteger(covuPeriod),
+		BACnetConstructedData: &BACnetConstructedData{},
+	}
+	_child.BACnetConstructedData.Child = _child
+	return _child, nil
+}
+
+func (m *BACnetConstructedDataCOVUPeriod) Serialize(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("BACnetConstructedDataCOVUPeriod"); pushErr != nil {
+			return pushErr
+		}
+
+		// Simple Field (covuPeriod)
+		if pushErr := writeBuffer.PushContext("covuPeriod"); pushErr != nil {
+			return pushErr
+		}
+		_covuPeriodErr := m.CovuPeriod.Serialize(writeBuffer)
+		if popErr := writeBuffer.PopContext("covuPeriod"); popErr != nil {
+			return popErr
+		}
+		if _covuPeriodErr != nil {
+			return errors.Wrap(_covuPeriodErr, "Error serializing 'covuPeriod' field")
+		}
+
+		if popErr := writeBuffer.PopContext("BACnetConstructedDataCOVUPeriod"); popErr != nil {
+			return popErr
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *BACnetConstructedDataCOVUPeriod) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	buffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	if err := m.Serialize(buffer); err != nil {
+		return err.Error()
+	}
+	return buffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedDataCOVURecipients.go b/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedDataCOVURecipients.go
new file mode 100644
index 0000000000..8f80d48b88
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedDataCOVURecipients.go
@@ -0,0 +1,226 @@
+/*
+ * 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
+ *
+ *   http://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 model
+
+import (
+	"github.com/apache/plc4x/plc4go/internal/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// BACnetConstructedDataCOVURecipients is the data-structure of this message
+type BACnetConstructedDataCOVURecipients struct {
+	*BACnetConstructedData
+	CovuRecipients []*BACnetRecipient
+
+	// Arguments.
+	TagNumber uint8
+}
+
+// IBACnetConstructedDataCOVURecipients is the corresponding interface of BACnetConstructedDataCOVURecipients
+type IBACnetConstructedDataCOVURecipients interface {
+	IBACnetConstructedData
+	// GetCovuRecipients returns CovuRecipients (property field)
+	GetCovuRecipients() []*BACnetRecipient
+	// GetLengthInBytes returns the length in bytes
+	GetLengthInBytes() uint16
+	// GetLengthInBits returns the length in bits
+	GetLengthInBits() uint16
+	// Serialize serializes this type
+	Serialize(writeBuffer utils.WriteBuffer) error
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *BACnetConstructedDataCOVURecipients) GetObjectTypeArgument() BACnetObjectType {
+	return 0
+}
+
+func (m *BACnetConstructedDataCOVURecipients) GetPropertyIdentifierArgument() BACnetPropertyIdentifier {
+	return BACnetPropertyIdentifier_COVU_RECIPIENTS
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *BACnetConstructedDataCOVURecipients) InitializeParent(parent *BACnetConstructedData, openingTag *BACnetOpeningTag, closingTag *BACnetClosingTag) {
+	m.BACnetConstructedData.OpeningTag = openingTag
+	m.BACnetConstructedData.ClosingTag = closingTag
+}
+
+func (m *BACnetConstructedDataCOVURecipients) GetParent() *BACnetConstructedData {
+	return m.BACnetConstructedData
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *BACnetConstructedDataCOVURecipients) GetCovuRecipients() []*BACnetRecipient {
+	return m.CovuRecipients
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewBACnetConstructedDataCOVURecipients factory function for BACnetConstructedDataCOVURecipients
+func NewBACnetConstructedDataCOVURecipients(covuRecipients []*BACnetRecipient, openingTag *BACnetOpeningTag, closingTag *BACnetClosingTag, tagNumber uint8) *BACnetConstructedDataCOVURecipients {
+	_result := &BACnetConstructedDataCOVURecipients{
+		CovuRecipients:        covuRecipients,
+		BACnetConstructedData: NewBACnetConstructedData(openingTag, closingTag, tagNumber),
+	}
+	_result.Child = _result
+	return _result
+}
+
+func CastBACnetConstructedDataCOVURecipients(structType interface{}) *BACnetConstructedDataCOVURecipients {
+	if casted, ok := structType.(BACnetConstructedDataCOVURecipients); ok {
+		return &casted
+	}
+	if casted, ok := structType.(*BACnetConstructedDataCOVURecipients); ok {
+		return casted
+	}
+	if casted, ok := structType.(BACnetConstructedData); ok {
+		return CastBACnetConstructedDataCOVURecipients(casted.Child)
+	}
+	if casted, ok := structType.(*BACnetConstructedData); ok {
+		return CastBACnetConstructedDataCOVURecipients(casted.Child)
+	}
+	return nil
+}
+
+func (m *BACnetConstructedDataCOVURecipients) GetTypeName() string {
+	return "BACnetConstructedDataCOVURecipients"
+}
+
+func (m *BACnetConstructedDataCOVURecipients) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *BACnetConstructedDataCOVURecipients) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Array field
+	if len(m.CovuRecipients) > 0 {
+		for _, element := range m.CovuRecipients {
+			lengthInBits += element.GetLengthInBits()
+		}
+	}
+
+	return lengthInBits
+}
+
+func (m *BACnetConstructedDataCOVURecipients) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func BACnetConstructedDataCOVURecipientsParse(readBuffer utils.ReadBuffer, tagNumber uint8, objectTypeArgument BACnetObjectType, propertyIdentifierArgument BACnetPropertyIdentifier) (*BACnetConstructedDataCOVURecipients, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("BACnetConstructedDataCOVURecipients"); pullErr != nil {
+		return nil, pullErr
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Array field (covuRecipients)
+	if pullErr := readBuffer.PullContext("covuRecipients", utils.WithRenderAsList(true)); pullErr != nil {
+		return nil, pullErr
+	}
+	// Terminated array
+	covuRecipients := make([]*BACnetRecipient, 0)
+	{
+		for !bool(IsBACnetConstructedDataClosingTag(readBuffer, false, tagNumber)) {
+			_item, _err := BACnetRecipientParse(readBuffer)
+			if _err != nil {
+				return nil, errors.Wrap(_err, "Error parsing 'covuRecipients' field")
+			}
+			covuRecipients = append(covuRecipients, CastBACnetRecipient(_item))
+
+		}
+	}
+	if closeErr := readBuffer.CloseContext("covuRecipients", utils.WithRenderAsList(true)); closeErr != nil {
+		return nil, closeErr
+	}
+
+	if closeErr := readBuffer.CloseContext("BACnetConstructedDataCOVURecipients"); closeErr != nil {
+		return nil, closeErr
+	}
+
+	// Create a partially initialized instance
+	_child := &BACnetConstructedDataCOVURecipients{
+		CovuRecipients:        covuRecipients,
+		BACnetConstructedData: &BACnetConstructedData{},
+	}
+	_child.BACnetConstructedData.Child = _child
+	return _child, nil
+}
+
+func (m *BACnetConstructedDataCOVURecipients) Serialize(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("BACnetConstructedDataCOVURecipients"); pushErr != nil {
+			return pushErr
+		}
+
+		// Array Field (covuRecipients)
+		if m.CovuRecipients != nil {
+			if pushErr := writeBuffer.PushContext("covuRecipients", utils.WithRenderAsList(true)); pushErr != nil {
+				return pushErr
+			}
+			for _, _element := range m.CovuRecipients {
+				_elementErr := _element.Serialize(writeBuffer)
+				if _elementErr != nil {
+					return errors.Wrap(_elementErr, "Error serializing 'covuRecipients' field")
+				}
+			}
+			if popErr := writeBuffer.PopContext("covuRecipients", utils.WithRenderAsList(true)); popErr != nil {
+				return popErr
+			}
+		}
+
+		if popErr := writeBuffer.PopContext("BACnetConstructedDataCOVURecipients"); popErr != nil {
+			return popErr
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *BACnetConstructedDataCOVURecipients) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	buffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	if err := m.Serialize(buffer); err != nil {
+		return err.Error()
+	}
+	return buffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedDataGroupMemberNames.go b/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedDataGroupMemberNames.go
new file mode 100644
index 0000000000..a8d1e0e036
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedDataGroupMemberNames.go
@@ -0,0 +1,226 @@
+/*
+ * 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
+ *
+ *   http://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 model
+
+import (
+	"github.com/apache/plc4x/plc4go/internal/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// BACnetConstructedDataGroupMemberNames is the data-structure of this message
+type BACnetConstructedDataGroupMemberNames struct {
+	*BACnetConstructedData
+	GroupMemberNames []*BACnetApplicationTagCharacterString
+
+	// Arguments.
+	TagNumber uint8
+}
+
+// IBACnetConstructedDataGroupMemberNames is the corresponding interface of BACnetConstructedDataGroupMemberNames
+type IBACnetConstructedDataGroupMemberNames interface {
+	IBACnetConstructedData
+	// GetGroupMemberNames returns GroupMemberNames (property field)
+	GetGroupMemberNames() []*BACnetApplicationTagCharacterString
+	// GetLengthInBytes returns the length in bytes
+	GetLengthInBytes() uint16
+	// GetLengthInBits returns the length in bits
+	GetLengthInBits() uint16
+	// Serialize serializes this type
+	Serialize(writeBuffer utils.WriteBuffer) error
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *BACnetConstructedDataGroupMemberNames) GetObjectTypeArgument() BACnetObjectType {
+	return 0
+}
+
+func (m *BACnetConstructedDataGroupMemberNames) GetPropertyIdentifierArgument() BACnetPropertyIdentifier {
+	return BACnetPropertyIdentifier_GROUP_MEMBER_NAMES
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *BACnetConstructedDataGroupMemberNames) InitializeParent(parent *BACnetConstructedData, openingTag *BACnetOpeningTag, closingTag *BACnetClosingTag) {
+	m.BACnetConstructedData.OpeningTag = openingTag
+	m.BACnetConstructedData.ClosingTag = closingTag
+}
+
+func (m *BACnetConstructedDataGroupMemberNames) GetParent() *BACnetConstructedData {
+	return m.BACnetConstructedData
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *BACnetConstructedDataGroupMemberNames) GetGroupMemberNames() []*BACnetApplicationTagCharacterString {
+	return m.GroupMemberNames
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewBACnetConstructedDataGroupMemberNames factory function for BACnetConstructedDataGroupMemberNames
+func NewBACnetConstructedDataGroupMemberNames(groupMemberNames []*BACnetApplicationTagCharacterString, openingTag *BACnetOpeningTag, closingTag *BACnetClosingTag, tagNumber uint8) *BACnetConstructedDataGroupMemberNames {
+	_result := &BACnetConstructedDataGroupMemberNames{
+		GroupMemberNames:      groupMemberNames,
+		BACnetConstructedData: NewBACnetConstructedData(openingTag, closingTag, tagNumber),
+	}
+	_result.Child = _result
+	return _result
+}
+
+func CastBACnetConstructedDataGroupMemberNames(structType interface{}) *BACnetConstructedDataGroupMemberNames {
+	if casted, ok := structType.(BACnetConstructedDataGroupMemberNames); ok {
+		return &casted
+	}
+	if casted, ok := structType.(*BACnetConstructedDataGroupMemberNames); ok {
+		return casted
+	}
+	if casted, ok := structType.(BACnetConstructedData); ok {
+		return CastBACnetConstructedDataGroupMemberNames(casted.Child)
+	}
+	if casted, ok := structType.(*BACnetConstructedData); ok {
+		return CastBACnetConstructedDataGroupMemberNames(casted.Child)
+	}
+	return nil
+}
+
+func (m *BACnetConstructedDataGroupMemberNames) GetTypeName() string {
+	return "BACnetConstructedDataGroupMemberNames"
+}
+
+func (m *BACnetConstructedDataGroupMemberNames) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *BACnetConstructedDataGroupMemberNames) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Array field
+	if len(m.GroupMemberNames) > 0 {
+		for _, element := range m.GroupMemberNames {
+			lengthInBits += element.GetLengthInBits()
+		}
+	}
+
+	return lengthInBits
+}
+
+func (m *BACnetConstructedDataGroupMemberNames) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func BACnetConstructedDataGroupMemberNamesParse(readBuffer utils.ReadBuffer, tagNumber uint8, objectTypeArgument BACnetObjectType, propertyIdentifierArgument BACnetPropertyIdentifier) (*BACnetConstructedDataGroupMemberNames, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("BACnetConstructedDataGroupMemberNames"); pullErr != nil {
+		return nil, pullErr
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Array field (groupMemberNames)
+	if pullErr := readBuffer.PullContext("groupMemberNames", utils.WithRenderAsList(true)); pullErr != nil {
+		return nil, pullErr
+	}
+	// Terminated array
+	groupMemberNames := make([]*BACnetApplicationTagCharacterString, 0)
+	{
+		for !bool(IsBACnetConstructedDataClosingTag(readBuffer, false, tagNumber)) {
+			_item, _err := BACnetApplicationTagParse(readBuffer)
+			if _err != nil {
+				return nil, errors.Wrap(_err, "Error parsing 'groupMemberNames' field")
+			}
+			groupMemberNames = append(groupMemberNames, CastBACnetApplicationTagCharacterString(_item))
+
+		}
+	}
+	if closeErr := readBuffer.CloseContext("groupMemberNames", utils.WithRenderAsList(true)); closeErr != nil {
+		return nil, closeErr
+	}
+
+	if closeErr := readBuffer.CloseContext("BACnetConstructedDataGroupMemberNames"); closeErr != nil {
+		return nil, closeErr
+	}
+
+	// Create a partially initialized instance
+	_child := &BACnetConstructedDataGroupMemberNames{
+		GroupMemberNames:      groupMemberNames,
+		BACnetConstructedData: &BACnetConstructedData{},
+	}
+	_child.BACnetConstructedData.Child = _child
+	return _child, nil
+}
+
+func (m *BACnetConstructedDataGroupMemberNames) Serialize(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("BACnetConstructedDataGroupMemberNames"); pushErr != nil {
+			return pushErr
+		}
+
+		// Array Field (groupMemberNames)
+		if m.GroupMemberNames != nil {
+			if pushErr := writeBuffer.PushContext("groupMemberNames", utils.WithRenderAsList(true)); pushErr != nil {
+				return pushErr
+			}
+			for _, _element := range m.GroupMemberNames {
+				_elementErr := _element.Serialize(writeBuffer)
+				if _elementErr != nil {
+					return errors.Wrap(_elementErr, "Error serializing 'groupMemberNames' field")
+				}
+			}
+			if popErr := writeBuffer.PopContext("groupMemberNames", utils.WithRenderAsList(true)); popErr != nil {
+				return popErr
+			}
+		}
+
+		if popErr := writeBuffer.PopContext("BACnetConstructedDataGroupMemberNames"); popErr != nil {
+			return popErr
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *BACnetConstructedDataGroupMemberNames) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	buffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	if err := m.Serialize(buffer); err != nil {
+		return err.Error()
+	}
+	return buffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedDataMemberStatusFlags.go b/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedDataMemberStatusFlags.go
new file mode 100644
index 0000000000..d3ab057517
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedDataMemberStatusFlags.go
@@ -0,0 +1,211 @@
+/*
+ * 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
+ *
+ *   http://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 model
+
+import (
+	"github.com/apache/plc4x/plc4go/internal/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// BACnetConstructedDataMemberStatusFlags is the data-structure of this message
+type BACnetConstructedDataMemberStatusFlags struct {
+	*BACnetConstructedData
+	StatusFlags *BACnetStatusFlagsTagged
+
+	// Arguments.
+	TagNumber uint8
+}
+
+// IBACnetConstructedDataMemberStatusFlags is the corresponding interface of BACnetConstructedDataMemberStatusFlags
+type IBACnetConstructedDataMemberStatusFlags interface {
+	IBACnetConstructedData
+	// GetStatusFlags returns StatusFlags (property field)
+	GetStatusFlags() *BACnetStatusFlagsTagged
+	// GetLengthInBytes returns the length in bytes
+	GetLengthInBytes() uint16
+	// GetLengthInBits returns the length in bits
+	GetLengthInBits() uint16
+	// Serialize serializes this type
+	Serialize(writeBuffer utils.WriteBuffer) error
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *BACnetConstructedDataMemberStatusFlags) GetObjectTypeArgument() BACnetObjectType {
+	return 0
+}
+
+func (m *BACnetConstructedDataMemberStatusFlags) GetPropertyIdentifierArgument() BACnetPropertyIdentifier {
+	return BACnetPropertyIdentifier_MEMBER_STATUS_FLAGS
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *BACnetConstructedDataMemberStatusFlags) InitializeParent(parent *BACnetConstructedData, openingTag *BACnetOpeningTag, closingTag *BACnetClosingTag) {
+	m.BACnetConstructedData.OpeningTag = openingTag
+	m.BACnetConstructedData.ClosingTag = closingTag
+}
+
+func (m *BACnetConstructedDataMemberStatusFlags) GetParent() *BACnetConstructedData {
+	return m.BACnetConstructedData
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *BACnetConstructedDataMemberStatusFlags) GetStatusFlags() *BACnetStatusFlagsTagged {
+	return m.StatusFlags
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewBACnetConstructedDataMemberStatusFlags factory function for BACnetConstructedDataMemberStatusFlags
+func NewBACnetConstructedDataMemberStatusFlags(statusFlags *BACnetStatusFlagsTagged, openingTag *BACnetOpeningTag, closingTag *BACnetClosingTag, tagNumber uint8) *BACnetConstructedDataMemberStatusFlags {
+	_result := &BACnetConstructedDataMemberStatusFlags{
+		StatusFlags:           statusFlags,
+		BACnetConstructedData: NewBACnetConstructedData(openingTag, closingTag, tagNumber),
+	}
+	_result.Child = _result
+	return _result
+}
+
+func CastBACnetConstructedDataMemberStatusFlags(structType interface{}) *BACnetConstructedDataMemberStatusFlags {
+	if casted, ok := structType.(BACnetConstructedDataMemberStatusFlags); ok {
+		return &casted
+	}
+	if casted, ok := structType.(*BACnetConstructedDataMemberStatusFlags); ok {
+		return casted
+	}
+	if casted, ok := structType.(BACnetConstructedData); ok {
+		return CastBACnetConstructedDataMemberStatusFlags(casted.Child)
+	}
+	if casted, ok := structType.(*BACnetConstructedData); ok {
+		return CastBACnetConstructedDataMemberStatusFlags(casted.Child)
+	}
+	return nil
+}
+
+func (m *BACnetConstructedDataMemberStatusFlags) GetTypeName() string {
+	return "BACnetConstructedDataMemberStatusFlags"
+}
+
+func (m *BACnetConstructedDataMemberStatusFlags) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *BACnetConstructedDataMemberStatusFlags) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Simple field (statusFlags)
+	lengthInBits += m.StatusFlags.GetLengthInBits()
+
+	return lengthInBits
+}
+
+func (m *BACnetConstructedDataMemberStatusFlags) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func BACnetConstructedDataMemberStatusFlagsParse(readBuffer utils.ReadBuffer, tagNumber uint8, objectTypeArgument BACnetObjectType, propertyIdentifierArgument BACnetPropertyIdentifier) (*BACnetConstructedDataMemberStatusFlags, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("BACnetConstructedDataMemberStatusFlags"); pullErr != nil {
+		return nil, pullErr
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (statusFlags)
+	if pullErr := readBuffer.PullContext("statusFlags"); pullErr != nil {
+		return nil, pullErr
+	}
+	_statusFlags, _statusFlagsErr := BACnetStatusFlagsTaggedParse(readBuffer, uint8(uint8(0)), TagClass(TagClass_APPLICATION_TAGS))
+	if _statusFlagsErr != nil {
+		return nil, errors.Wrap(_statusFlagsErr, "Error parsing 'statusFlags' field")
+	}
+	statusFlags := CastBACnetStatusFlagsTagged(_statusFlags)
+	if closeErr := readBuffer.CloseContext("statusFlags"); closeErr != nil {
+		return nil, closeErr
+	}
+
+	if closeErr := readBuffer.CloseContext("BACnetConstructedDataMemberStatusFlags"); closeErr != nil {
+		return nil, closeErr
+	}
+
+	// Create a partially initialized instance
+	_child := &BACnetConstructedDataMemberStatusFlags{
+		StatusFlags:           CastBACnetStatusFlagsTagged(statusFlags),
+		BACnetConstructedData: &BACnetConstructedData{},
+	}
+	_child.BACnetConstructedData.Child = _child
+	return _child, nil
+}
+
+func (m *BACnetConstructedDataMemberStatusFlags) Serialize(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("BACnetConstructedDataMemberStatusFlags"); pushErr != nil {
+			return pushErr
+		}
+
+		// Simple Field (statusFlags)
+		if pushErr := writeBuffer.PushContext("statusFlags"); pushErr != nil {
+			return pushErr
+		}
+		_statusFlagsErr := m.StatusFlags.Serialize(writeBuffer)
+		if popErr := writeBuffer.PopContext("statusFlags"); popErr != nil {
+			return popErr
+		}
+		if _statusFlagsErr != nil {
+			return errors.Wrap(_statusFlagsErr, "Error serializing 'statusFlags' field")
+		}
+
+		if popErr := writeBuffer.PopContext("BACnetConstructedDataMemberStatusFlags"); popErr != nil {
+			return popErr
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *BACnetConstructedDataMemberStatusFlags) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	buffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	if err := m.Serialize(buffer); err != nil {
+		return err.Error()
+	}
+	return buffer.GetBox().String()
+}
diff --git a/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedDataRequestedUpdateInterval.go b/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedDataRequestedUpdateInterval.go
new file mode 100644
index 0000000000..7c55f42201
--- /dev/null
+++ b/plc4go/protocols/bacnetip/readwrite/model/BACnetConstructedDataRequestedUpdateInterval.go
@@ -0,0 +1,211 @@
+/*
+ * 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
+ *
+ *   http://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 model
+
+import (
+	"github.com/apache/plc4x/plc4go/internal/spi/utils"
+	"github.com/pkg/errors"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// BACnetConstructedDataRequestedUpdateInterval is the data-structure of this message
+type BACnetConstructedDataRequestedUpdateInterval struct {
+	*BACnetConstructedData
+	RequestedUpdateInterval *BACnetApplicationTagUnsignedInteger
+
+	// Arguments.
+	TagNumber uint8
+}
+
+// IBACnetConstructedDataRequestedUpdateInterval is the corresponding interface of BACnetConstructedDataRequestedUpdateInterval
+type IBACnetConstructedDataRequestedUpdateInterval interface {
+	IBACnetConstructedData
+	// GetRequestedUpdateInterval returns RequestedUpdateInterval (property field)
+	GetRequestedUpdateInterval() *BACnetApplicationTagUnsignedInteger
+	// GetLengthInBytes returns the length in bytes
+	GetLengthInBytes() uint16
+	// GetLengthInBits returns the length in bits
+	GetLengthInBits() uint16
+	// Serialize serializes this type
+	Serialize(writeBuffer utils.WriteBuffer) error
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+func (m *BACnetConstructedDataRequestedUpdateInterval) GetObjectTypeArgument() BACnetObjectType {
+	return 0
+}
+
+func (m *BACnetConstructedDataRequestedUpdateInterval) GetPropertyIdentifierArgument() BACnetPropertyIdentifier {
+	return BACnetPropertyIdentifier_REQUESTED_UPDATE_INTERVAL
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *BACnetConstructedDataRequestedUpdateInterval) InitializeParent(parent *BACnetConstructedData, openingTag *BACnetOpeningTag, closingTag *BACnetClosingTag) {
+	m.BACnetConstructedData.OpeningTag = openingTag
+	m.BACnetConstructedData.ClosingTag = closingTag
+}
+
+func (m *BACnetConstructedDataRequestedUpdateInterval) GetParent() *BACnetConstructedData {
+	return m.BACnetConstructedData
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *BACnetConstructedDataRequestedUpdateInterval) GetRequestedUpdateInterval() *BACnetApplicationTagUnsignedInteger {
+	return m.RequestedUpdateInterval
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewBACnetConstructedDataRequestedUpdateInterval factory function for BACnetConstructedDataRequestedUpdateInterval
+func NewBACnetConstructedDataRequestedUpdateInterval(requestedUpdateInterval *BACnetApplicationTagUnsignedInteger, openingTag *BACnetOpeningTag, closingTag *BACnetClosingTag, tagNumber uint8) *BACnetConstructedDataRequestedUpdateInterval {
+	_result := &BACnetConstructedDataRequestedUpdateInterval{
+		RequestedUpdateInterval: requestedUpdateInterval,
+		BACnetConstructedData:   NewBACnetConstructedData(openingTag, closingTag, tagNumber),
+	}
+	_result.Child = _result
+	return _result
+}
+
+func CastBACnetConstructedDataRequestedUpdateInterval(structType interface{}) *BACnetConstructedDataRequestedUpdateInterval {
+	if casted, ok := structType.(BACnetConstructedDataRequestedUpdateInterval); ok {
+		return &casted
+	}
+	if casted, ok := structType.(*BACnetConstructedDataRequestedUpdateInterval); ok {
+		return casted
+	}
+	if casted, ok := structType.(BACnetConstructedData); ok {
+		return CastBACnetConstructedDataRequestedUpdateInterval(casted.Child)
+	}
+	if casted, ok := structType.(*BACnetConstructedData); ok {
+		return CastBACnetConstructedDataRequestedUpdateInterval(casted.Child)
+	}
+	return nil
+}
+
+func (m *BACnetConstructedDataRequestedUpdateInterval) GetTypeName() string {
+	return "BACnetConstructedDataRequestedUpdateInterval"
+}
+
+func (m *BACnetConstructedDataRequestedUpdateInterval) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *BACnetConstructedDataRequestedUpdateInterval) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(m.GetParentLengthInBits())
+
+	// Simple field (requestedUpdateInterval)
+	lengthInBits += m.RequestedUpdateInterval.GetLengthInBits()
+
+	return lengthInBits
+}
+
+func (m *BACnetConstructedDataRequestedUpdateInterval) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func BACnetConstructedDataRequestedUpdateIntervalParse(readBuffer utils.ReadBuffer, tagNumber uint8, objectTypeArgument BACnetObjectType, propertyIdentifierArgument BACnetPropertyIdentifier) (*BACnetConstructedDataRequestedUpdateInterval, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("BACnetConstructedDataRequestedUpdateInterval"); pullErr != nil {
+		return nil, pullErr
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (requestedUpdateInterval)
+	if pullErr := readBuffer.PullContext("requestedUpdateInterval"); pullErr != nil {
+		return nil, pullErr
+	}
+	_requestedUpdateInterval, _requestedUpdateIntervalErr := BACnetApplicationTagParse(readBuffer)
+	if _requestedUpdateIntervalErr != nil {
+		return nil, errors.Wrap(_requestedUpdateIntervalErr, "Error parsing 'requestedUpdateInterval' field")
+	}
+	requestedUpdateInterval := CastBACnetApplicationTagUnsignedInteger(_requestedUpdateInterval)
+	if closeErr := readBuffer.CloseContext("requestedUpdateInterval"); closeErr != nil {
+		return nil, closeErr
+	}
+
+	if closeErr := readBuffer.CloseContext("BACnetConstructedDataRequestedUpdateInterval"); closeErr != nil {
+		return nil, closeErr
+	}
+
+	// Create a partially initialized instance
+	_child := &BACnetConstructedDataRequestedUpdateInterval{
+		RequestedUpdateInterval: CastBACnetApplicationTagUnsignedInteger(requestedUpdateInterval),
+		BACnetConstructedData:   &BACnetConstructedData{},
+	}
+	_child.BACnetConstructedData.Child = _child
+	return _child, nil
+}
+
+func (m *BACnetConstructedDataRequestedUpdateInterval) Serialize(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	ser := func() error {
+		if pushErr := writeBuffer.PushContext("BACnetConstructedDataRequestedUpdateInterval"); pushErr != nil {
+			return pushErr
+		}
+
+		// Simple Field (requestedUpdateInterval)
+		if pushErr := writeBuffer.PushContext("requestedUpdateInterval"); pushErr != nil {
+			return pushErr
+		}
+		_requestedUpdateIntervalErr := m.RequestedUpdateInterval.Serialize(writeBuffer)
+		if popErr := writeBuffer.PopContext("requestedUpdateInterval"); popErr != nil {
+			return popErr
+		}
+		if _requestedUpdateIntervalErr != nil {
+			return errors.Wrap(_requestedUpdateIntervalErr, "Error serializing 'requestedUpdateInterval' field")
+		}
+
+		if popErr := writeBuffer.PopContext("BACnetConstructedDataRequestedUpdateInterval"); popErr != nil {
+			return popErr
+		}
+		return nil
+	}
+	return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *BACnetConstructedDataRequestedUpdateInterval) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	buffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	if err := m.Serialize(buffer); err != nil {
+		return err.Error()
+	}
+	return buffer.GetBox().String()
+}
diff --git a/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec b/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec
index 87007e3b63..448834208f 100644
--- a/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec
+++ b/protocols/bacnetip/src/main/resources/protocols/bacnetip/bacnetip.mspec
@@ -2765,8 +2765,15 @@
             [simple   BACnetApplicationTagUnsignedInteger                               covPeriod                       ]
         ]
         //[*, 'COV_RESUBSCRIPTION_INTERVAL'             BACnetConstructedDataCOVResubscriptionInterval [validation    '1 == 2'    "TODO: implement me COV_RESUBSCRIPTION_INTERVAL BACnetConstructedDataCOVResubscriptionInterval"]]
-        //[*, 'COVU_PERIOD'                             BACnetConstructedDataCOVUPeriod [validation    '1 == 2'    "TODO: implement me COVU_PERIOD BACnetConstructedDataCOVUPeriod"]]
-        //[*, 'COVU_RECIPIENTS'                         BACnetConstructedDataCOVURecipients [validation    '1 == 2'    "TODO: implement me COVU_RECIPIENTS BACnetConstructedDataCOVURecipients"]]
+        [*, 'COVU_PERIOD'                             BACnetConstructedDataCOVUPeriod
+            [simple   BACnetApplicationTagUnsignedInteger                               covuPeriod                      ]
+        ]
+        [*, 'COVU_RECIPIENTS'                         BACnetConstructedDataCOVURecipients
+            [array    BACnetRecipient
+                                        covuRecipients
+                                                terminated
+                                                'STATIC_CALL("isBACnetConstructedDataClosingTag", readBuffer, false, tagNumber)'            ]
+        ]
         [*, 'CREDENTIAL_DISABLE'                      BACnetConstructedDataCredentialDisable
             [simple   BACnetAccessCredentialDisableTagged('0', 'TagClass.APPLICATION_TAGS')             credentialDisable]
         ]
@@ -2966,7 +2973,12 @@
         ]
         //[*, 'GLOBAL_IDENTIFIER'                       BACnetConstructedDataGlobalIdentifier [validation    '1 == 2'    "TODO: implement me GLOBAL_IDENTIFIER BACnetConstructedDataGlobalIdentifier"]]
         //[*, 'GROUP_ID'                                BACnetConstructedDataGroupId [validation    '1 == 2'    "TODO: implement me GROUP_ID BACnetConstructedDataGroupId"]]
-        //[*, 'GROUP_MEMBER_NAMES'                      BACnetConstructedDataGroupMemberNames [validation    '1 == 2'    "TODO: implement me GROUP_MEMBER_NAMES BACnetConstructedDataGroupMemberNames"]]
+        [*, 'GROUP_MEMBER_NAMES'                      BACnetConstructedDataGroupMemberNames
+            [array    BACnetApplicationTagCharacterString
+                                        groupMemberNames
+                                                terminated
+                                                'STATIC_CALL("isBACnetConstructedDataClosingTag", readBuffer, false, tagNumber)'            ]
+        ]
         //[*, 'GROUP_MEMBERS'                           BACnetConstructedDataGroupMembers [validation    '1 == 2'    "TODO: implement me GROUP_MEMBERS BACnetConstructedDataGroupMembers"]]
         //[*, 'GROUP_MODE'                              BACnetConstructedDataGroupMode [validation    '1 == 2'    "TODO: implement me GROUP_MODE BACnetConstructedDataGroupMode"]]
         ['ACCUMULATOR', 'HIGH_LIMIT'                    BACnetConstructedDataAccumulatorHighLimit
@@ -3228,7 +3240,9 @@
                             terminated
                             'STATIC_CALL("isBACnetConstructedDataClosingTag", readBuffer, false, tagNumber)'            ]
         ]
-        //[*, 'MEMBER_STATUS_FLAGS'                     BACnetConstructedDataMemberStatusFlags [validation    '1 == 2'    "TODO: implement me MEMBER_STATUS_FLAGS BACnetConstructedDataMemberStatusFlags"]]
+        [*, 'MEMBER_STATUS_FLAGS'                     BACnetConstructedDataMemberStatusFlags
+            [simple   BACnetStatusFlagsTagged('0', 'TagClass.APPLICATION_TAGS')         statusFlags                     ]
+        ]
         [*, 'MEMBERS'                                 BACnetConstructedDataMembers
             [array    BACnetDeviceObjectReference
                                     members
@@ -3450,7 +3464,9 @@
         [*, 'REQUESTED_SHED_LEVEL'                    BACnetConstructedDataRequestedShedLevel
             [simple  BACnetShedLevel            requestedShedLevel                                                      ]
         ]
-        //[*, 'REQUESTED_UPDATE_INTERVAL'               BACnetConstructedDataRequestedUpdateInterval [validation    '1 == 2'    "TODO: implement me REQUESTED_UPDATE_INTERVAL BACnetConstructedDataRequestedUpdateInterval"]]
+        [*, 'REQUESTED_UPDATE_INTERVAL'               BACnetConstructedDataRequestedUpdateInterval
+            [simple BACnetApplicationTagUnsignedInteger                       requestedUpdateInterval                   ]
+        ]
         //[*, 'REQUIRED'                                BACnetConstructedDataRequired [validation    '1 == 2'    "TODO: implement me REQUIRED BACnetConstructedDataRequired"]]
         [*, 'RESOLUTION'                              BACnetConstructedDataResolution
             [simple   BACnetApplicationTagReal                                          resolution                      ]
diff --git a/protocols/bacnetip/src/test/java/org/apache/plc4x/protocol/bacnetip/ObjectPropertyDeDuplicationTest.java b/protocols/bacnetip/src/test/java/org/apache/plc4x/protocol/bacnetip/ObjectPropertyDeDuplicationTest.java
index 3278b7e0c3..b905b44458 100644
--- a/protocols/bacnetip/src/test/java/org/apache/plc4x/protocol/bacnetip/ObjectPropertyDeDuplicationTest.java
+++ b/protocols/bacnetip/src/test/java/org/apache/plc4x/protocol/bacnetip/ObjectPropertyDeDuplicationTest.java
@@ -113,6 +113,12 @@ public class ObjectPropertyDeDuplicationTest {
                         () -> {
                             String searchedTypeName = "BACnetConstructedData" + propertyIdentifier;
                             searchedTypeName = searchedTypeName.replaceAll("_", "");
+                            switch (searchedTypeName) {
+                                case "BACnetConstructedDataOutofService":
+                                    // Global group has a typo in this and writes the "o" lowercase
+                                    searchedTypeName = "BACnetConstructedDataOutOfService";
+                                    break;
+                            }
                             assertNotNull(typeDefinitions.get(searchedTypeName), searchedTypeName + " not found");
                         })
                 );