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/07/13 10:32:41 UTC

[plc4x] branch develop updated: feat(cbus): mapped more identify reply commands

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 8a50d2a13 feat(cbus): mapped more identify reply commands
8a50d2a13 is described below

commit 8a50d2a13689f26151bac695c60745087a539a0a
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Wed Jul 13 12:32:34 2022 +0200

    feat(cbus): mapped more identify reply commands
---
 plc4go/protocols/cbus/readwrite/ParserHelper.go    |   2 +
 plc4go/protocols/cbus/readwrite/XmlParserHelper.go |   2 +
 .../IdentifyReplyCommandCurrentSenseLevels.go      |  38 ++-
 .../readwrite/model/IdentifyReplyCommandDelays.go  |  64 +++-
 .../model/IdentifyReplyCommandLogicalAssignment.go |  66 ++++-
 .../model/IdentifyReplyCommandMaximumLevels.go     |  38 ++-
 .../model/IdentifyReplyCommandMinimumLevels.go     |  38 ++-
 .../IdentifyReplyCommandNetworkTerminalLevels.go   |  38 ++-
 .../model/IdentifyReplyCommandTerminalLevels.go    |  38 ++-
 .../cbus/readwrite/model/LogicAssignment.go        | 328 +++++++++++++++++++++
 .../apache/plc4x/java/cbus/RandomPackagesTest.java |  19 ++
 .../src/main/resources/protocols/cbus/c-bus.mspec  |  32 +-
 12 files changed, 686 insertions(+), 17 deletions(-)

diff --git a/plc4go/protocols/cbus/readwrite/ParserHelper.go b/plc4go/protocols/cbus/readwrite/ParserHelper.go
index ac04be750..43642eb94 100644
--- a/plc4go/protocols/cbus/readwrite/ParserHelper.go
+++ b/plc4go/protocols/cbus/readwrite/ParserHelper.go
@@ -172,6 +172,8 @@ func (m CbusParserHelper) Parse(typeName string, arguments []string, io utils.Re
 	case "CBusPointToPointToMultipointCommand":
 		var cBusOptions model.CBusOptions
 		return model.CBusPointToPointToMultipointCommandParse(io, cBusOptions)
+	case "LogicAssignment":
+		return model.LogicAssignmentParse(io)
 	}
 	return nil, errors.Errorf("Unsupported type %s", typeName)
 }
diff --git a/plc4go/protocols/cbus/readwrite/XmlParserHelper.go b/plc4go/protocols/cbus/readwrite/XmlParserHelper.go
index 05f4f2aee..874b1002d 100644
--- a/plc4go/protocols/cbus/readwrite/XmlParserHelper.go
+++ b/plc4go/protocols/cbus/readwrite/XmlParserHelper.go
@@ -199,6 +199,8 @@ func (m CbusXmlParserHelper) Parse(typeName string, xmlString string, parserArgu
 		// TODO: find a way to parse the sub types
 		var cBusOptions model.CBusOptions
 		return model.CBusPointToPointToMultipointCommandParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)), cBusOptions)
+	case "LogicAssignment":
+		return model.LogicAssignmentParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
 	}
 	return nil, errors.Errorf("Unsupported type %s", typeName)
 }
diff --git a/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandCurrentSenseLevels.go b/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandCurrentSenseLevels.go
index 59cee4c1e..1032530ec 100644
--- a/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandCurrentSenseLevels.go
+++ b/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandCurrentSenseLevels.go
@@ -31,6 +31,8 @@ type IdentifyReplyCommandCurrentSenseLevels interface {
 	utils.LengthAware
 	utils.Serializable
 	IdentifyReplyCommand
+	// GetCurrentSenseLevels returns CurrentSenseLevels (property field)
+	GetCurrentSenseLevels() []byte
 }
 
 // IdentifyReplyCommandCurrentSenseLevelsExactly can be used when we want exactly this type and not a type which fulfills IdentifyReplyCommandCurrentSenseLevels.
@@ -43,6 +45,7 @@ type IdentifyReplyCommandCurrentSenseLevelsExactly interface {
 // _IdentifyReplyCommandCurrentSenseLevels is the data-structure of this message
 type _IdentifyReplyCommandCurrentSenseLevels struct {
 	*_IdentifyReplyCommand
+	CurrentSenseLevels []byte
 }
 
 ///////////////////////////////////////////////////////////
@@ -65,9 +68,24 @@ func (m *_IdentifyReplyCommandCurrentSenseLevels) GetParent() IdentifyReplyComma
 	return m._IdentifyReplyCommand
 }
 
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_IdentifyReplyCommandCurrentSenseLevels) GetCurrentSenseLevels() []byte {
+	return m.CurrentSenseLevels
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
 // NewIdentifyReplyCommandCurrentSenseLevels factory function for _IdentifyReplyCommandCurrentSenseLevels
-func NewIdentifyReplyCommandCurrentSenseLevels(numBytes uint8) *_IdentifyReplyCommandCurrentSenseLevels {
+func NewIdentifyReplyCommandCurrentSenseLevels(currentSenseLevels []byte, numBytes uint8) *_IdentifyReplyCommandCurrentSenseLevels {
 	_result := &_IdentifyReplyCommandCurrentSenseLevels{
+		CurrentSenseLevels:    currentSenseLevels,
 		_IdentifyReplyCommand: NewIdentifyReplyCommand(numBytes),
 	}
 	_result._IdentifyReplyCommand._IdentifyReplyCommandChildRequirements = _result
@@ -96,6 +114,11 @@ func (m *_IdentifyReplyCommandCurrentSenseLevels) GetLengthInBits() uint16 {
 func (m *_IdentifyReplyCommandCurrentSenseLevels) GetLengthInBitsConditional(lastItem bool) uint16 {
 	lengthInBits := uint16(m.GetParentLengthInBits())
 
+	// Array field
+	if len(m.CurrentSenseLevels) > 0 {
+		lengthInBits += 8 * uint16(len(m.CurrentSenseLevels))
+	}
+
 	return lengthInBits
 }
 
@@ -111,6 +134,12 @@ func IdentifyReplyCommandCurrentSenseLevelsParse(readBuffer utils.ReadBuffer, at
 	}
 	currentPos := positionAware.GetPos()
 	_ = currentPos
+	// Byte Array field (currentSenseLevels)
+	numberOfBytescurrentSenseLevels := int(numBytes)
+	currentSenseLevels, _readArrayErr := readBuffer.ReadByteArray("currentSenseLevels", numberOfBytescurrentSenseLevels)
+	if _readArrayErr != nil {
+		return nil, errors.Wrap(_readArrayErr, "Error parsing 'currentSenseLevels' field of IdentifyReplyCommandCurrentSenseLevels")
+	}
 
 	if closeErr := readBuffer.CloseContext("IdentifyReplyCommandCurrentSenseLevels"); closeErr != nil {
 		return nil, errors.Wrap(closeErr, "Error closing for IdentifyReplyCommandCurrentSenseLevels")
@@ -118,6 +147,7 @@ func IdentifyReplyCommandCurrentSenseLevelsParse(readBuffer utils.ReadBuffer, at
 
 	// Create a partially initialized instance
 	_child := &_IdentifyReplyCommandCurrentSenseLevels{
+		CurrentSenseLevels: currentSenseLevels,
 		_IdentifyReplyCommand: &_IdentifyReplyCommand{
 			NumBytes: numBytes,
 		},
@@ -134,6 +164,12 @@ func (m *_IdentifyReplyCommandCurrentSenseLevels) Serialize(writeBuffer utils.Wr
 			return errors.Wrap(pushErr, "Error pushing for IdentifyReplyCommandCurrentSenseLevels")
 		}
 
+		// Array Field (currentSenseLevels)
+		// Byte Array field (currentSenseLevels)
+		if err := writeBuffer.WriteByteArray("currentSenseLevels", m.GetCurrentSenseLevels()); err != nil {
+			return errors.Wrap(err, "Error serializing 'currentSenseLevels' field")
+		}
+
 		if popErr := writeBuffer.PopContext("IdentifyReplyCommandCurrentSenseLevels"); popErr != nil {
 			return errors.Wrap(popErr, "Error popping for IdentifyReplyCommandCurrentSenseLevels")
 		}
diff --git a/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandDelays.go b/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandDelays.go
index aec94fac9..d6261f1cb 100644
--- a/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandDelays.go
+++ b/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandDelays.go
@@ -31,6 +31,10 @@ type IdentifyReplyCommandDelays interface {
 	utils.LengthAware
 	utils.Serializable
 	IdentifyReplyCommand
+	// GetTerminalLevels returns TerminalLevels (property field)
+	GetTerminalLevels() []byte
+	// GetReStrikeDelay returns ReStrikeDelay (property field)
+	GetReStrikeDelay() byte
 }
 
 // IdentifyReplyCommandDelaysExactly can be used when we want exactly this type and not a type which fulfills IdentifyReplyCommandDelays.
@@ -43,6 +47,8 @@ type IdentifyReplyCommandDelaysExactly interface {
 // _IdentifyReplyCommandDelays is the data-structure of this message
 type _IdentifyReplyCommandDelays struct {
 	*_IdentifyReplyCommand
+	TerminalLevels []byte
+	ReStrikeDelay  byte
 }
 
 ///////////////////////////////////////////////////////////
@@ -65,9 +71,29 @@ func (m *_IdentifyReplyCommandDelays) GetParent() IdentifyReplyCommand {
 	return m._IdentifyReplyCommand
 }
 
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_IdentifyReplyCommandDelays) GetTerminalLevels() []byte {
+	return m.TerminalLevels
+}
+
+func (m *_IdentifyReplyCommandDelays) GetReStrikeDelay() byte {
+	return m.ReStrikeDelay
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
 // NewIdentifyReplyCommandDelays factory function for _IdentifyReplyCommandDelays
-func NewIdentifyReplyCommandDelays(numBytes uint8) *_IdentifyReplyCommandDelays {
+func NewIdentifyReplyCommandDelays(terminalLevels []byte, reStrikeDelay byte, numBytes uint8) *_IdentifyReplyCommandDelays {
 	_result := &_IdentifyReplyCommandDelays{
+		TerminalLevels:        terminalLevels,
+		ReStrikeDelay:         reStrikeDelay,
 		_IdentifyReplyCommand: NewIdentifyReplyCommand(numBytes),
 	}
 	_result._IdentifyReplyCommand._IdentifyReplyCommandChildRequirements = _result
@@ -96,6 +122,14 @@ func (m *_IdentifyReplyCommandDelays) GetLengthInBits() uint16 {
 func (m *_IdentifyReplyCommandDelays) GetLengthInBitsConditional(lastItem bool) uint16 {
 	lengthInBits := uint16(m.GetParentLengthInBits())
 
+	// Array field
+	if len(m.TerminalLevels) > 0 {
+		lengthInBits += 8 * uint16(len(m.TerminalLevels))
+	}
+
+	// Simple field (reStrikeDelay)
+	lengthInBits += 8
+
 	return lengthInBits
 }
 
@@ -111,6 +145,19 @@ func IdentifyReplyCommandDelaysParse(readBuffer utils.ReadBuffer, attribute Attr
 	}
 	currentPos := positionAware.GetPos()
 	_ = currentPos
+	// Byte Array field (terminalLevels)
+	numberOfBytesterminalLevels := int(uint16(numBytes) - uint16(uint16(1)))
+	terminalLevels, _readArrayErr := readBuffer.ReadByteArray("terminalLevels", numberOfBytesterminalLevels)
+	if _readArrayErr != nil {
+		return nil, errors.Wrap(_readArrayErr, "Error parsing 'terminalLevels' field of IdentifyReplyCommandDelays")
+	}
+
+	// Simple Field (reStrikeDelay)
+	_reStrikeDelay, _reStrikeDelayErr := readBuffer.ReadByte("reStrikeDelay")
+	if _reStrikeDelayErr != nil {
+		return nil, errors.Wrap(_reStrikeDelayErr, "Error parsing 'reStrikeDelay' field of IdentifyReplyCommandDelays")
+	}
+	reStrikeDelay := _reStrikeDelay
 
 	if closeErr := readBuffer.CloseContext("IdentifyReplyCommandDelays"); closeErr != nil {
 		return nil, errors.Wrap(closeErr, "Error closing for IdentifyReplyCommandDelays")
@@ -118,6 +165,8 @@ func IdentifyReplyCommandDelaysParse(readBuffer utils.ReadBuffer, attribute Attr
 
 	// Create a partially initialized instance
 	_child := &_IdentifyReplyCommandDelays{
+		TerminalLevels: terminalLevels,
+		ReStrikeDelay:  reStrikeDelay,
 		_IdentifyReplyCommand: &_IdentifyReplyCommand{
 			NumBytes: numBytes,
 		},
@@ -134,6 +183,19 @@ func (m *_IdentifyReplyCommandDelays) Serialize(writeBuffer utils.WriteBuffer) e
 			return errors.Wrap(pushErr, "Error pushing for IdentifyReplyCommandDelays")
 		}
 
+		// Array Field (terminalLevels)
+		// Byte Array field (terminalLevels)
+		if err := writeBuffer.WriteByteArray("terminalLevels", m.GetTerminalLevels()); err != nil {
+			return errors.Wrap(err, "Error serializing 'terminalLevels' field")
+		}
+
+		// Simple Field (reStrikeDelay)
+		reStrikeDelay := byte(m.GetReStrikeDelay())
+		_reStrikeDelayErr := writeBuffer.WriteByte("reStrikeDelay", (reStrikeDelay))
+		if _reStrikeDelayErr != nil {
+			return errors.Wrap(_reStrikeDelayErr, "Error serializing 'reStrikeDelay' field")
+		}
+
 		if popErr := writeBuffer.PopContext("IdentifyReplyCommandDelays"); popErr != nil {
 			return errors.Wrap(popErr, "Error popping for IdentifyReplyCommandDelays")
 		}
diff --git a/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandLogicalAssignment.go b/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandLogicalAssignment.go
index e0633103f..42730d1f3 100644
--- a/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandLogicalAssignment.go
+++ b/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandLogicalAssignment.go
@@ -31,6 +31,8 @@ type IdentifyReplyCommandLogicalAssignment interface {
 	utils.LengthAware
 	utils.Serializable
 	IdentifyReplyCommand
+	// GetLogicAssigment returns LogicAssigment (property field)
+	GetLogicAssigment() []LogicAssignment
 }
 
 // IdentifyReplyCommandLogicalAssignmentExactly can be used when we want exactly this type and not a type which fulfills IdentifyReplyCommandLogicalAssignment.
@@ -43,6 +45,7 @@ type IdentifyReplyCommandLogicalAssignmentExactly interface {
 // _IdentifyReplyCommandLogicalAssignment is the data-structure of this message
 type _IdentifyReplyCommandLogicalAssignment struct {
 	*_IdentifyReplyCommand
+	LogicAssigment []LogicAssignment
 }
 
 ///////////////////////////////////////////////////////////
@@ -65,9 +68,24 @@ func (m *_IdentifyReplyCommandLogicalAssignment) GetParent() IdentifyReplyComman
 	return m._IdentifyReplyCommand
 }
 
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_IdentifyReplyCommandLogicalAssignment) GetLogicAssigment() []LogicAssignment {
+	return m.LogicAssigment
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
 // NewIdentifyReplyCommandLogicalAssignment factory function for _IdentifyReplyCommandLogicalAssignment
-func NewIdentifyReplyCommandLogicalAssignment(numBytes uint8) *_IdentifyReplyCommandLogicalAssignment {
+func NewIdentifyReplyCommandLogicalAssignment(logicAssigment []LogicAssignment, numBytes uint8) *_IdentifyReplyCommandLogicalAssignment {
 	_result := &_IdentifyReplyCommandLogicalAssignment{
+		LogicAssigment:        logicAssigment,
 		_IdentifyReplyCommand: NewIdentifyReplyCommand(numBytes),
 	}
 	_result._IdentifyReplyCommand._IdentifyReplyCommandChildRequirements = _result
@@ -96,6 +114,14 @@ func (m *_IdentifyReplyCommandLogicalAssignment) GetLengthInBits() uint16 {
 func (m *_IdentifyReplyCommandLogicalAssignment) GetLengthInBitsConditional(lastItem bool) uint16 {
 	lengthInBits := uint16(m.GetParentLengthInBits())
 
+	// Array field
+	if len(m.LogicAssigment) > 0 {
+		for i, element := range m.LogicAssigment {
+			last := i == len(m.LogicAssigment)-1
+			lengthInBits += element.(interface{ GetLengthInBitsConditional(bool) uint16 }).GetLengthInBitsConditional(last)
+		}
+	}
+
 	return lengthInBits
 }
 
@@ -112,12 +138,36 @@ func IdentifyReplyCommandLogicalAssignmentParse(readBuffer utils.ReadBuffer, att
 	currentPos := positionAware.GetPos()
 	_ = currentPos
 
+	// Array field (logicAssigment)
+	if pullErr := readBuffer.PullContext("logicAssigment", utils.WithRenderAsList(true)); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for logicAssigment")
+	}
+	// Count array
+	logicAssigment := make([]LogicAssignment, numBytes)
+	// This happens when the size is set conditional to 0
+	if len(logicAssigment) == 0 {
+		logicAssigment = nil
+	}
+	{
+		for curItem := uint16(0); curItem < uint16(numBytes); curItem++ {
+			_item, _err := LogicAssignmentParse(readBuffer)
+			if _err != nil {
+				return nil, errors.Wrap(_err, "Error parsing 'logicAssigment' field of IdentifyReplyCommandLogicalAssignment")
+			}
+			logicAssigment[curItem] = _item.(LogicAssignment)
+		}
+	}
+	if closeErr := readBuffer.CloseContext("logicAssigment", utils.WithRenderAsList(true)); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for logicAssigment")
+	}
+
 	if closeErr := readBuffer.CloseContext("IdentifyReplyCommandLogicalAssignment"); closeErr != nil {
 		return nil, errors.Wrap(closeErr, "Error closing for IdentifyReplyCommandLogicalAssignment")
 	}
 
 	// Create a partially initialized instance
 	_child := &_IdentifyReplyCommandLogicalAssignment{
+		LogicAssigment: logicAssigment,
 		_IdentifyReplyCommand: &_IdentifyReplyCommand{
 			NumBytes: numBytes,
 		},
@@ -134,6 +184,20 @@ func (m *_IdentifyReplyCommandLogicalAssignment) Serialize(writeBuffer utils.Wri
 			return errors.Wrap(pushErr, "Error pushing for IdentifyReplyCommandLogicalAssignment")
 		}
 
+		// Array Field (logicAssigment)
+		if pushErr := writeBuffer.PushContext("logicAssigment", utils.WithRenderAsList(true)); pushErr != nil {
+			return errors.Wrap(pushErr, "Error pushing for logicAssigment")
+		}
+		for _, _element := range m.GetLogicAssigment() {
+			_elementErr := writeBuffer.WriteSerializable(_element)
+			if _elementErr != nil {
+				return errors.Wrap(_elementErr, "Error serializing 'logicAssigment' field")
+			}
+		}
+		if popErr := writeBuffer.PopContext("logicAssigment", utils.WithRenderAsList(true)); popErr != nil {
+			return errors.Wrap(popErr, "Error popping for logicAssigment")
+		}
+
 		if popErr := writeBuffer.PopContext("IdentifyReplyCommandLogicalAssignment"); popErr != nil {
 			return errors.Wrap(popErr, "Error popping for IdentifyReplyCommandLogicalAssignment")
 		}
diff --git a/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandMaximumLevels.go b/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandMaximumLevels.go
index d4cc097bb..f836c8392 100644
--- a/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandMaximumLevels.go
+++ b/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandMaximumLevels.go
@@ -31,6 +31,8 @@ type IdentifyReplyCommandMaximumLevels interface {
 	utils.LengthAware
 	utils.Serializable
 	IdentifyReplyCommand
+	// GetMaximumLevels returns MaximumLevels (property field)
+	GetMaximumLevels() []byte
 }
 
 // IdentifyReplyCommandMaximumLevelsExactly can be used when we want exactly this type and not a type which fulfills IdentifyReplyCommandMaximumLevels.
@@ -43,6 +45,7 @@ type IdentifyReplyCommandMaximumLevelsExactly interface {
 // _IdentifyReplyCommandMaximumLevels is the data-structure of this message
 type _IdentifyReplyCommandMaximumLevels struct {
 	*_IdentifyReplyCommand
+	MaximumLevels []byte
 }
 
 ///////////////////////////////////////////////////////////
@@ -65,9 +68,24 @@ func (m *_IdentifyReplyCommandMaximumLevels) GetParent() IdentifyReplyCommand {
 	return m._IdentifyReplyCommand
 }
 
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_IdentifyReplyCommandMaximumLevels) GetMaximumLevels() []byte {
+	return m.MaximumLevels
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
 // NewIdentifyReplyCommandMaximumLevels factory function for _IdentifyReplyCommandMaximumLevels
-func NewIdentifyReplyCommandMaximumLevels(numBytes uint8) *_IdentifyReplyCommandMaximumLevels {
+func NewIdentifyReplyCommandMaximumLevels(maximumLevels []byte, numBytes uint8) *_IdentifyReplyCommandMaximumLevels {
 	_result := &_IdentifyReplyCommandMaximumLevels{
+		MaximumLevels:         maximumLevels,
 		_IdentifyReplyCommand: NewIdentifyReplyCommand(numBytes),
 	}
 	_result._IdentifyReplyCommand._IdentifyReplyCommandChildRequirements = _result
@@ -96,6 +114,11 @@ func (m *_IdentifyReplyCommandMaximumLevels) GetLengthInBits() uint16 {
 func (m *_IdentifyReplyCommandMaximumLevels) GetLengthInBitsConditional(lastItem bool) uint16 {
 	lengthInBits := uint16(m.GetParentLengthInBits())
 
+	// Array field
+	if len(m.MaximumLevels) > 0 {
+		lengthInBits += 8 * uint16(len(m.MaximumLevels))
+	}
+
 	return lengthInBits
 }
 
@@ -111,6 +134,12 @@ func IdentifyReplyCommandMaximumLevelsParse(readBuffer utils.ReadBuffer, attribu
 	}
 	currentPos := positionAware.GetPos()
 	_ = currentPos
+	// Byte Array field (maximumLevels)
+	numberOfBytesmaximumLevels := int(numBytes)
+	maximumLevels, _readArrayErr := readBuffer.ReadByteArray("maximumLevels", numberOfBytesmaximumLevels)
+	if _readArrayErr != nil {
+		return nil, errors.Wrap(_readArrayErr, "Error parsing 'maximumLevels' field of IdentifyReplyCommandMaximumLevels")
+	}
 
 	if closeErr := readBuffer.CloseContext("IdentifyReplyCommandMaximumLevels"); closeErr != nil {
 		return nil, errors.Wrap(closeErr, "Error closing for IdentifyReplyCommandMaximumLevels")
@@ -118,6 +147,7 @@ func IdentifyReplyCommandMaximumLevelsParse(readBuffer utils.ReadBuffer, attribu
 
 	// Create a partially initialized instance
 	_child := &_IdentifyReplyCommandMaximumLevels{
+		MaximumLevels: maximumLevels,
 		_IdentifyReplyCommand: &_IdentifyReplyCommand{
 			NumBytes: numBytes,
 		},
@@ -134,6 +164,12 @@ func (m *_IdentifyReplyCommandMaximumLevels) Serialize(writeBuffer utils.WriteBu
 			return errors.Wrap(pushErr, "Error pushing for IdentifyReplyCommandMaximumLevels")
 		}
 
+		// Array Field (maximumLevels)
+		// Byte Array field (maximumLevels)
+		if err := writeBuffer.WriteByteArray("maximumLevels", m.GetMaximumLevels()); err != nil {
+			return errors.Wrap(err, "Error serializing 'maximumLevels' field")
+		}
+
 		if popErr := writeBuffer.PopContext("IdentifyReplyCommandMaximumLevels"); popErr != nil {
 			return errors.Wrap(popErr, "Error popping for IdentifyReplyCommandMaximumLevels")
 		}
diff --git a/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandMinimumLevels.go b/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandMinimumLevels.go
index 5a4b5a6f1..1d7780751 100644
--- a/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandMinimumLevels.go
+++ b/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandMinimumLevels.go
@@ -31,6 +31,8 @@ type IdentifyReplyCommandMinimumLevels interface {
 	utils.LengthAware
 	utils.Serializable
 	IdentifyReplyCommand
+	// GetMinimumLevels returns MinimumLevels (property field)
+	GetMinimumLevels() []byte
 }
 
 // IdentifyReplyCommandMinimumLevelsExactly can be used when we want exactly this type and not a type which fulfills IdentifyReplyCommandMinimumLevels.
@@ -43,6 +45,7 @@ type IdentifyReplyCommandMinimumLevelsExactly interface {
 // _IdentifyReplyCommandMinimumLevels is the data-structure of this message
 type _IdentifyReplyCommandMinimumLevels struct {
 	*_IdentifyReplyCommand
+	MinimumLevels []byte
 }
 
 ///////////////////////////////////////////////////////////
@@ -65,9 +68,24 @@ func (m *_IdentifyReplyCommandMinimumLevels) GetParent() IdentifyReplyCommand {
 	return m._IdentifyReplyCommand
 }
 
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_IdentifyReplyCommandMinimumLevels) GetMinimumLevels() []byte {
+	return m.MinimumLevels
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
 // NewIdentifyReplyCommandMinimumLevels factory function for _IdentifyReplyCommandMinimumLevels
-func NewIdentifyReplyCommandMinimumLevels(numBytes uint8) *_IdentifyReplyCommandMinimumLevels {
+func NewIdentifyReplyCommandMinimumLevels(minimumLevels []byte, numBytes uint8) *_IdentifyReplyCommandMinimumLevels {
 	_result := &_IdentifyReplyCommandMinimumLevels{
+		MinimumLevels:         minimumLevels,
 		_IdentifyReplyCommand: NewIdentifyReplyCommand(numBytes),
 	}
 	_result._IdentifyReplyCommand._IdentifyReplyCommandChildRequirements = _result
@@ -96,6 +114,11 @@ func (m *_IdentifyReplyCommandMinimumLevels) GetLengthInBits() uint16 {
 func (m *_IdentifyReplyCommandMinimumLevels) GetLengthInBitsConditional(lastItem bool) uint16 {
 	lengthInBits := uint16(m.GetParentLengthInBits())
 
+	// Array field
+	if len(m.MinimumLevels) > 0 {
+		lengthInBits += 8 * uint16(len(m.MinimumLevels))
+	}
+
 	return lengthInBits
 }
 
@@ -111,6 +134,12 @@ func IdentifyReplyCommandMinimumLevelsParse(readBuffer utils.ReadBuffer, attribu
 	}
 	currentPos := positionAware.GetPos()
 	_ = currentPos
+	// Byte Array field (minimumLevels)
+	numberOfBytesminimumLevels := int(numBytes)
+	minimumLevels, _readArrayErr := readBuffer.ReadByteArray("minimumLevels", numberOfBytesminimumLevels)
+	if _readArrayErr != nil {
+		return nil, errors.Wrap(_readArrayErr, "Error parsing 'minimumLevels' field of IdentifyReplyCommandMinimumLevels")
+	}
 
 	if closeErr := readBuffer.CloseContext("IdentifyReplyCommandMinimumLevels"); closeErr != nil {
 		return nil, errors.Wrap(closeErr, "Error closing for IdentifyReplyCommandMinimumLevels")
@@ -118,6 +147,7 @@ func IdentifyReplyCommandMinimumLevelsParse(readBuffer utils.ReadBuffer, attribu
 
 	// Create a partially initialized instance
 	_child := &_IdentifyReplyCommandMinimumLevels{
+		MinimumLevels: minimumLevels,
 		_IdentifyReplyCommand: &_IdentifyReplyCommand{
 			NumBytes: numBytes,
 		},
@@ -134,6 +164,12 @@ func (m *_IdentifyReplyCommandMinimumLevels) Serialize(writeBuffer utils.WriteBu
 			return errors.Wrap(pushErr, "Error pushing for IdentifyReplyCommandMinimumLevels")
 		}
 
+		// Array Field (minimumLevels)
+		// Byte Array field (minimumLevels)
+		if err := writeBuffer.WriteByteArray("minimumLevels", m.GetMinimumLevels()); err != nil {
+			return errors.Wrap(err, "Error serializing 'minimumLevels' field")
+		}
+
 		if popErr := writeBuffer.PopContext("IdentifyReplyCommandMinimumLevels"); popErr != nil {
 			return errors.Wrap(popErr, "Error popping for IdentifyReplyCommandMinimumLevels")
 		}
diff --git a/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandNetworkTerminalLevels.go b/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandNetworkTerminalLevels.go
index fd9a3693f..f0c3fb3d4 100644
--- a/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandNetworkTerminalLevels.go
+++ b/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandNetworkTerminalLevels.go
@@ -31,6 +31,8 @@ type IdentifyReplyCommandNetworkTerminalLevels interface {
 	utils.LengthAware
 	utils.Serializable
 	IdentifyReplyCommand
+	// GetMinimumLevels returns MinimumLevels (property field)
+	GetMinimumLevels() []byte
 }
 
 // IdentifyReplyCommandNetworkTerminalLevelsExactly can be used when we want exactly this type and not a type which fulfills IdentifyReplyCommandNetworkTerminalLevels.
@@ -43,6 +45,7 @@ type IdentifyReplyCommandNetworkTerminalLevelsExactly interface {
 // _IdentifyReplyCommandNetworkTerminalLevels is the data-structure of this message
 type _IdentifyReplyCommandNetworkTerminalLevels struct {
 	*_IdentifyReplyCommand
+	MinimumLevels []byte
 }
 
 ///////////////////////////////////////////////////////////
@@ -65,9 +68,24 @@ func (m *_IdentifyReplyCommandNetworkTerminalLevels) GetParent() IdentifyReplyCo
 	return m._IdentifyReplyCommand
 }
 
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_IdentifyReplyCommandNetworkTerminalLevels) GetMinimumLevels() []byte {
+	return m.MinimumLevels
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
 // NewIdentifyReplyCommandNetworkTerminalLevels factory function for _IdentifyReplyCommandNetworkTerminalLevels
-func NewIdentifyReplyCommandNetworkTerminalLevels(numBytes uint8) *_IdentifyReplyCommandNetworkTerminalLevels {
+func NewIdentifyReplyCommandNetworkTerminalLevels(minimumLevels []byte, numBytes uint8) *_IdentifyReplyCommandNetworkTerminalLevels {
 	_result := &_IdentifyReplyCommandNetworkTerminalLevels{
+		MinimumLevels:         minimumLevels,
 		_IdentifyReplyCommand: NewIdentifyReplyCommand(numBytes),
 	}
 	_result._IdentifyReplyCommand._IdentifyReplyCommandChildRequirements = _result
@@ -96,6 +114,11 @@ func (m *_IdentifyReplyCommandNetworkTerminalLevels) GetLengthInBits() uint16 {
 func (m *_IdentifyReplyCommandNetworkTerminalLevels) GetLengthInBitsConditional(lastItem bool) uint16 {
 	lengthInBits := uint16(m.GetParentLengthInBits())
 
+	// Array field
+	if len(m.MinimumLevels) > 0 {
+		lengthInBits += 8 * uint16(len(m.MinimumLevels))
+	}
+
 	return lengthInBits
 }
 
@@ -111,6 +134,12 @@ func IdentifyReplyCommandNetworkTerminalLevelsParse(readBuffer utils.ReadBuffer,
 	}
 	currentPos := positionAware.GetPos()
 	_ = currentPos
+	// Byte Array field (minimumLevels)
+	numberOfBytesminimumLevels := int(numBytes)
+	minimumLevels, _readArrayErr := readBuffer.ReadByteArray("minimumLevels", numberOfBytesminimumLevels)
+	if _readArrayErr != nil {
+		return nil, errors.Wrap(_readArrayErr, "Error parsing 'minimumLevels' field of IdentifyReplyCommandNetworkTerminalLevels")
+	}
 
 	if closeErr := readBuffer.CloseContext("IdentifyReplyCommandNetworkTerminalLevels"); closeErr != nil {
 		return nil, errors.Wrap(closeErr, "Error closing for IdentifyReplyCommandNetworkTerminalLevels")
@@ -118,6 +147,7 @@ func IdentifyReplyCommandNetworkTerminalLevelsParse(readBuffer utils.ReadBuffer,
 
 	// Create a partially initialized instance
 	_child := &_IdentifyReplyCommandNetworkTerminalLevels{
+		MinimumLevels: minimumLevels,
 		_IdentifyReplyCommand: &_IdentifyReplyCommand{
 			NumBytes: numBytes,
 		},
@@ -134,6 +164,12 @@ func (m *_IdentifyReplyCommandNetworkTerminalLevels) Serialize(writeBuffer utils
 			return errors.Wrap(pushErr, "Error pushing for IdentifyReplyCommandNetworkTerminalLevels")
 		}
 
+		// Array Field (minimumLevels)
+		// Byte Array field (minimumLevels)
+		if err := writeBuffer.WriteByteArray("minimumLevels", m.GetMinimumLevels()); err != nil {
+			return errors.Wrap(err, "Error serializing 'minimumLevels' field")
+		}
+
 		if popErr := writeBuffer.PopContext("IdentifyReplyCommandNetworkTerminalLevels"); popErr != nil {
 			return errors.Wrap(popErr, "Error popping for IdentifyReplyCommandNetworkTerminalLevels")
 		}
diff --git a/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandTerminalLevels.go b/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandTerminalLevels.go
index 55d89cd12..879a67cd0 100644
--- a/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandTerminalLevels.go
+++ b/plc4go/protocols/cbus/readwrite/model/IdentifyReplyCommandTerminalLevels.go
@@ -31,6 +31,8 @@ type IdentifyReplyCommandTerminalLevels interface {
 	utils.LengthAware
 	utils.Serializable
 	IdentifyReplyCommand
+	// GetTerminalLevels returns TerminalLevels (property field)
+	GetTerminalLevels() []byte
 }
 
 // IdentifyReplyCommandTerminalLevelsExactly can be used when we want exactly this type and not a type which fulfills IdentifyReplyCommandTerminalLevels.
@@ -43,6 +45,7 @@ type IdentifyReplyCommandTerminalLevelsExactly interface {
 // _IdentifyReplyCommandTerminalLevels is the data-structure of this message
 type _IdentifyReplyCommandTerminalLevels struct {
 	*_IdentifyReplyCommand
+	TerminalLevels []byte
 }
 
 ///////////////////////////////////////////////////////////
@@ -65,9 +68,24 @@ func (m *_IdentifyReplyCommandTerminalLevels) GetParent() IdentifyReplyCommand {
 	return m._IdentifyReplyCommand
 }
 
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_IdentifyReplyCommandTerminalLevels) GetTerminalLevels() []byte {
+	return m.TerminalLevels
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
 // NewIdentifyReplyCommandTerminalLevels factory function for _IdentifyReplyCommandTerminalLevels
-func NewIdentifyReplyCommandTerminalLevels(numBytes uint8) *_IdentifyReplyCommandTerminalLevels {
+func NewIdentifyReplyCommandTerminalLevels(terminalLevels []byte, numBytes uint8) *_IdentifyReplyCommandTerminalLevels {
 	_result := &_IdentifyReplyCommandTerminalLevels{
+		TerminalLevels:        terminalLevels,
 		_IdentifyReplyCommand: NewIdentifyReplyCommand(numBytes),
 	}
 	_result._IdentifyReplyCommand._IdentifyReplyCommandChildRequirements = _result
@@ -96,6 +114,11 @@ func (m *_IdentifyReplyCommandTerminalLevels) GetLengthInBits() uint16 {
 func (m *_IdentifyReplyCommandTerminalLevels) GetLengthInBitsConditional(lastItem bool) uint16 {
 	lengthInBits := uint16(m.GetParentLengthInBits())
 
+	// Array field
+	if len(m.TerminalLevels) > 0 {
+		lengthInBits += 8 * uint16(len(m.TerminalLevels))
+	}
+
 	return lengthInBits
 }
 
@@ -111,6 +134,12 @@ func IdentifyReplyCommandTerminalLevelsParse(readBuffer utils.ReadBuffer, attrib
 	}
 	currentPos := positionAware.GetPos()
 	_ = currentPos
+	// Byte Array field (terminalLevels)
+	numberOfBytesterminalLevels := int(numBytes)
+	terminalLevels, _readArrayErr := readBuffer.ReadByteArray("terminalLevels", numberOfBytesterminalLevels)
+	if _readArrayErr != nil {
+		return nil, errors.Wrap(_readArrayErr, "Error parsing 'terminalLevels' field of IdentifyReplyCommandTerminalLevels")
+	}
 
 	if closeErr := readBuffer.CloseContext("IdentifyReplyCommandTerminalLevels"); closeErr != nil {
 		return nil, errors.Wrap(closeErr, "Error closing for IdentifyReplyCommandTerminalLevels")
@@ -118,6 +147,7 @@ func IdentifyReplyCommandTerminalLevelsParse(readBuffer utils.ReadBuffer, attrib
 
 	// Create a partially initialized instance
 	_child := &_IdentifyReplyCommandTerminalLevels{
+		TerminalLevels: terminalLevels,
 		_IdentifyReplyCommand: &_IdentifyReplyCommand{
 			NumBytes: numBytes,
 		},
@@ -134,6 +164,12 @@ func (m *_IdentifyReplyCommandTerminalLevels) Serialize(writeBuffer utils.WriteB
 			return errors.Wrap(pushErr, "Error pushing for IdentifyReplyCommandTerminalLevels")
 		}
 
+		// Array Field (terminalLevels)
+		// Byte Array field (terminalLevels)
+		if err := writeBuffer.WriteByteArray("terminalLevels", m.GetTerminalLevels()); err != nil {
+			return errors.Wrap(err, "Error serializing 'terminalLevels' field")
+		}
+
 		if popErr := writeBuffer.PopContext("IdentifyReplyCommandTerminalLevels"); popErr != nil {
 			return errors.Wrap(popErr, "Error popping for IdentifyReplyCommandTerminalLevels")
 		}
diff --git a/plc4go/protocols/cbus/readwrite/model/LogicAssignment.go b/plc4go/protocols/cbus/readwrite/model/LogicAssignment.go
new file mode 100644
index 000000000..8c6dce4db
--- /dev/null
+++ b/plc4go/protocols/cbus/readwrite/model/LogicAssignment.go
@@ -0,0 +1,328 @@
+/*
+ * 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 model
+
+import (
+	"github.com/apache/plc4x/plc4go/internal/spi/utils"
+	"github.com/pkg/errors"
+	"github.com/rs/zerolog/log"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// LogicAssignment is the corresponding interface of LogicAssignment
+type LogicAssignment interface {
+	utils.LengthAware
+	utils.Serializable
+	// GetGreaterOfOrLogic returns GreaterOfOrLogic (property field)
+	GetGreaterOfOrLogic() bool
+	// GetReStrikeDelay returns ReStrikeDelay (property field)
+	GetReStrikeDelay() bool
+	// GetAssignedToGav16 returns AssignedToGav16 (property field)
+	GetAssignedToGav16() bool
+	// GetAssignedToGav15 returns AssignedToGav15 (property field)
+	GetAssignedToGav15() bool
+	// GetAssignedToGav14 returns AssignedToGav14 (property field)
+	GetAssignedToGav14() bool
+	// GetAssignedToGav13 returns AssignedToGav13 (property field)
+	GetAssignedToGav13() bool
+}
+
+// LogicAssignmentExactly can be used when we want exactly this type and not a type which fulfills LogicAssignment.
+// This is useful for switch cases.
+type LogicAssignmentExactly interface {
+	LogicAssignment
+	isLogicAssignment() bool
+}
+
+// _LogicAssignment is the data-structure of this message
+type _LogicAssignment struct {
+	GreaterOfOrLogic bool
+	ReStrikeDelay    bool
+	AssignedToGav16  bool
+	AssignedToGav15  bool
+	AssignedToGav14  bool
+	AssignedToGav13  bool
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_LogicAssignment) GetGreaterOfOrLogic() bool {
+	return m.GreaterOfOrLogic
+}
+
+func (m *_LogicAssignment) GetReStrikeDelay() bool {
+	return m.ReStrikeDelay
+}
+
+func (m *_LogicAssignment) GetAssignedToGav16() bool {
+	return m.AssignedToGav16
+}
+
+func (m *_LogicAssignment) GetAssignedToGav15() bool {
+	return m.AssignedToGav15
+}
+
+func (m *_LogicAssignment) GetAssignedToGav14() bool {
+	return m.AssignedToGav14
+}
+
+func (m *_LogicAssignment) GetAssignedToGav13() bool {
+	return m.AssignedToGav13
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewLogicAssignment factory function for _LogicAssignment
+func NewLogicAssignment(greaterOfOrLogic bool, reStrikeDelay bool, assignedToGav16 bool, assignedToGav15 bool, assignedToGav14 bool, assignedToGav13 bool) *_LogicAssignment {
+	return &_LogicAssignment{GreaterOfOrLogic: greaterOfOrLogic, ReStrikeDelay: reStrikeDelay, AssignedToGav16: assignedToGav16, AssignedToGav15: assignedToGav15, AssignedToGav14: assignedToGav14, AssignedToGav13: assignedToGav13}
+}
+
+// Deprecated: use the interface for direct cast
+func CastLogicAssignment(structType interface{}) LogicAssignment {
+	if casted, ok := structType.(LogicAssignment); ok {
+		return casted
+	}
+	if casted, ok := structType.(*LogicAssignment); ok {
+		return *casted
+	}
+	return nil
+}
+
+func (m *_LogicAssignment) GetTypeName() string {
+	return "LogicAssignment"
+}
+
+func (m *_LogicAssignment) GetLengthInBits() uint16 {
+	return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_LogicAssignment) GetLengthInBitsConditional(lastItem bool) uint16 {
+	lengthInBits := uint16(0)
+
+	// Simple field (greaterOfOrLogic)
+	lengthInBits += 1
+
+	// Simple field (reStrikeDelay)
+	lengthInBits += 1
+
+	// Reserved Field (reserved)
+	lengthInBits += 1
+
+	// Reserved Field (reserved)
+	lengthInBits += 1
+
+	// Simple field (assignedToGav16)
+	lengthInBits += 1
+
+	// Simple field (assignedToGav15)
+	lengthInBits += 1
+
+	// Simple field (assignedToGav14)
+	lengthInBits += 1
+
+	// Simple field (assignedToGav13)
+	lengthInBits += 1
+
+	return lengthInBits
+}
+
+func (m *_LogicAssignment) GetLengthInBytes() uint16 {
+	return m.GetLengthInBits() / 8
+}
+
+func LogicAssignmentParse(readBuffer utils.ReadBuffer) (LogicAssignment, error) {
+	positionAware := readBuffer
+	_ = positionAware
+	if pullErr := readBuffer.PullContext("LogicAssignment"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for LogicAssignment")
+	}
+	currentPos := positionAware.GetPos()
+	_ = currentPos
+
+	// Simple Field (greaterOfOrLogic)
+	_greaterOfOrLogic, _greaterOfOrLogicErr := readBuffer.ReadBit("greaterOfOrLogic")
+	if _greaterOfOrLogicErr != nil {
+		return nil, errors.Wrap(_greaterOfOrLogicErr, "Error parsing 'greaterOfOrLogic' field of LogicAssignment")
+	}
+	greaterOfOrLogic := _greaterOfOrLogic
+
+	// Simple Field (reStrikeDelay)
+	_reStrikeDelay, _reStrikeDelayErr := readBuffer.ReadBit("reStrikeDelay")
+	if _reStrikeDelayErr != nil {
+		return nil, errors.Wrap(_reStrikeDelayErr, "Error parsing 'reStrikeDelay' field of LogicAssignment")
+	}
+	reStrikeDelay := _reStrikeDelay
+
+	// Reserved Field (Compartmentalized so the "reserved" variable can't leak)
+	{
+		reserved, _err := readBuffer.ReadBit("reserved")
+		if _err != nil {
+			return nil, errors.Wrap(_err, "Error parsing 'reserved' field of LogicAssignment")
+		}
+		if reserved != bool(false) {
+			log.Info().Fields(map[string]interface{}{
+				"expected value": bool(false),
+				"got value":      reserved,
+			}).Msg("Got unexpected response for reserved field.")
+		}
+	}
+
+	// Reserved Field (Compartmentalized so the "reserved" variable can't leak)
+	{
+		reserved, _err := readBuffer.ReadBit("reserved")
+		if _err != nil {
+			return nil, errors.Wrap(_err, "Error parsing 'reserved' field of LogicAssignment")
+		}
+		if reserved != bool(false) {
+			log.Info().Fields(map[string]interface{}{
+				"expected value": bool(false),
+				"got value":      reserved,
+			}).Msg("Got unexpected response for reserved field.")
+		}
+	}
+
+	// Simple Field (assignedToGav16)
+	_assignedToGav16, _assignedToGav16Err := readBuffer.ReadBit("assignedToGav16")
+	if _assignedToGav16Err != nil {
+		return nil, errors.Wrap(_assignedToGav16Err, "Error parsing 'assignedToGav16' field of LogicAssignment")
+	}
+	assignedToGav16 := _assignedToGav16
+
+	// Simple Field (assignedToGav15)
+	_assignedToGav15, _assignedToGav15Err := readBuffer.ReadBit("assignedToGav15")
+	if _assignedToGav15Err != nil {
+		return nil, errors.Wrap(_assignedToGav15Err, "Error parsing 'assignedToGav15' field of LogicAssignment")
+	}
+	assignedToGav15 := _assignedToGav15
+
+	// Simple Field (assignedToGav14)
+	_assignedToGav14, _assignedToGav14Err := readBuffer.ReadBit("assignedToGav14")
+	if _assignedToGav14Err != nil {
+		return nil, errors.Wrap(_assignedToGav14Err, "Error parsing 'assignedToGav14' field of LogicAssignment")
+	}
+	assignedToGav14 := _assignedToGav14
+
+	// Simple Field (assignedToGav13)
+	_assignedToGav13, _assignedToGav13Err := readBuffer.ReadBit("assignedToGav13")
+	if _assignedToGav13Err != nil {
+		return nil, errors.Wrap(_assignedToGav13Err, "Error parsing 'assignedToGav13' field of LogicAssignment")
+	}
+	assignedToGav13 := _assignedToGav13
+
+	if closeErr := readBuffer.CloseContext("LogicAssignment"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for LogicAssignment")
+	}
+
+	// Create the instance
+	return NewLogicAssignment(greaterOfOrLogic, reStrikeDelay, assignedToGav16, assignedToGav15, assignedToGav14, assignedToGav13), nil
+}
+
+func (m *_LogicAssignment) Serialize(writeBuffer utils.WriteBuffer) error {
+	positionAware := writeBuffer
+	_ = positionAware
+	if pushErr := writeBuffer.PushContext("LogicAssignment"); pushErr != nil {
+		return errors.Wrap(pushErr, "Error pushing for LogicAssignment")
+	}
+
+	// Simple Field (greaterOfOrLogic)
+	greaterOfOrLogic := bool(m.GetGreaterOfOrLogic())
+	_greaterOfOrLogicErr := writeBuffer.WriteBit("greaterOfOrLogic", (greaterOfOrLogic))
+	if _greaterOfOrLogicErr != nil {
+		return errors.Wrap(_greaterOfOrLogicErr, "Error serializing 'greaterOfOrLogic' field")
+	}
+
+	// Simple Field (reStrikeDelay)
+	reStrikeDelay := bool(m.GetReStrikeDelay())
+	_reStrikeDelayErr := writeBuffer.WriteBit("reStrikeDelay", (reStrikeDelay))
+	if _reStrikeDelayErr != nil {
+		return errors.Wrap(_reStrikeDelayErr, "Error serializing 'reStrikeDelay' field")
+	}
+
+	// Reserved Field (reserved)
+	{
+		_err := writeBuffer.WriteBit("reserved", bool(false))
+		if _err != nil {
+			return errors.Wrap(_err, "Error serializing 'reserved' field")
+		}
+	}
+
+	// Reserved Field (reserved)
+	{
+		_err := writeBuffer.WriteBit("reserved", bool(false))
+		if _err != nil {
+			return errors.Wrap(_err, "Error serializing 'reserved' field")
+		}
+	}
+
+	// Simple Field (assignedToGav16)
+	assignedToGav16 := bool(m.GetAssignedToGav16())
+	_assignedToGav16Err := writeBuffer.WriteBit("assignedToGav16", (assignedToGav16))
+	if _assignedToGav16Err != nil {
+		return errors.Wrap(_assignedToGav16Err, "Error serializing 'assignedToGav16' field")
+	}
+
+	// Simple Field (assignedToGav15)
+	assignedToGav15 := bool(m.GetAssignedToGav15())
+	_assignedToGav15Err := writeBuffer.WriteBit("assignedToGav15", (assignedToGav15))
+	if _assignedToGav15Err != nil {
+		return errors.Wrap(_assignedToGav15Err, "Error serializing 'assignedToGav15' field")
+	}
+
+	// Simple Field (assignedToGav14)
+	assignedToGav14 := bool(m.GetAssignedToGav14())
+	_assignedToGav14Err := writeBuffer.WriteBit("assignedToGav14", (assignedToGav14))
+	if _assignedToGav14Err != nil {
+		return errors.Wrap(_assignedToGav14Err, "Error serializing 'assignedToGav14' field")
+	}
+
+	// Simple Field (assignedToGav13)
+	assignedToGav13 := bool(m.GetAssignedToGav13())
+	_assignedToGav13Err := writeBuffer.WriteBit("assignedToGav13", (assignedToGav13))
+	if _assignedToGav13Err != nil {
+		return errors.Wrap(_assignedToGav13Err, "Error serializing 'assignedToGav13' field")
+	}
+
+	if popErr := writeBuffer.PopContext("LogicAssignment"); popErr != nil {
+		return errors.Wrap(popErr, "Error popping for LogicAssignment")
+	}
+	return nil
+}
+
+func (m *_LogicAssignment) isLogicAssignment() bool {
+	return true
+}
+
+func (m *_LogicAssignment) String() string {
+	if m == nil {
+		return "<nil>"
+	}
+	writeBuffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4j/drivers/c-bus/src/test/java/org/apache/plc4x/java/cbus/RandomPackagesTest.java b/plc4j/drivers/c-bus/src/test/java/org/apache/plc4x/java/cbus/RandomPackagesTest.java
index 259bba7ad..8a8b338cd 100644
--- a/plc4j/drivers/c-bus/src/test/java/org/apache/plc4x/java/cbus/RandomPackagesTest.java
+++ b/plc4j/drivers/c-bus/src/test/java/org/apache/plc4x/java/cbus/RandomPackagesTest.java
@@ -787,5 +787,24 @@ public class RandomPackagesTest {
             CBusCommand cbusCommand = requestCommand.getCbusCommand();
             System.out.println(cbusCommand);
         }
+
+        @Test
+        void wat() throws Exception {
+            byte[] bytes = "D8FF0024000002000000000000000008000000000000000000\r\n".getBytes(StandardCharsets.UTF_8);
+            ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+            cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+            requestContext = new RequestContext(true, false, false);
+            CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+            assertThat(msg).isNotNull();
+            System.out.println(msg);
+            CBusMessageToClient messageToClient = (CBusMessageToClient) msg;
+            ReplyOrConfirmationReply reply = (ReplyOrConfirmationReply) messageToClient.getReply();
+            /*
+            MonitoredSALReply monitoredSALReply = (MonitoredSALReply) reply.getReply();
+            System.out.println(monitoredSALReply.getMonitoredSAL());
+             */
+            ReplyCALReply replyReply = (ReplyCALReply) reply.getReply();
+            System.out.println(replyReply.getCalReply());
+        }
     }
 }
diff --git a/protocols/c-bus/src/main/resources/protocols/cbus/c-bus.mspec b/protocols/c-bus/src/main/resources/protocols/cbus/c-bus.mspec
index 32036b66e..7c1b9a45b 100644
--- a/protocols/c-bus/src/main/resources/protocols/cbus/c-bus.mspec
+++ b/protocols/c-bus/src/main/resources/protocols/cbus/c-bus.mspec
@@ -1026,10 +1026,10 @@
             [simple   bit                     microPowerReset        ]
         ]
         ['NetworkTerminalLevels'        IdentifyReplyCommandNetworkTerminalLevels
-            //TODO: read dynamic
+            [array  byte        minimumLevels        count 'numBytes'       ] // TODO: check datatype
         ]
         ['TerminalLevel'                IdentifyReplyCommandTerminalLevels
-            //TODO: read dynamic
+            [array  byte        terminalLevels        count 'numBytes'       ] // TODO: check datatype
         ]
         ['NetworkVoltage'               IdentifyReplyCommandNetworkVoltage
            [simple string 2     volts                   ]
@@ -1038,28 +1038,29 @@
            [const  byte         v       0x56            ]
         ]
         ['GAVValuesCurrent'             IdentifyReplyCommandGAVValuesCurrent
-           [array  byte         values  count   '16'    ] // TODO: check datatype
+            [array  byte        values  count   '16'    ] // TODO: check datatype
         ]
         ['GAVValuesStored'              IdentifyReplyCommandGAVValuesStored
-           [array  byte         values  count   '16'    ] // TODO: check datatype
+            [array  byte        values  count   '16'    ] // TODO: check datatype
         ]
         ['GAVPhysicalAddresses'         IdentifyReplyCommandGAVPhysicalAddresses
-           [array  byte         values  count   '16'    ] // TODO: check datatype
+            [array  byte        values  count   '16'    ] // TODO: check datatype
         ]
         ['LogicalAssignment'            IdentifyReplyCommandLogicalAssignment
-            //TODO: read dynamic
+            [array  LogicAssignment   logicAssigment        count 'numBytes'       ]
         ]
         ['Delays'                       IdentifyReplyCommandDelays
-            //TODO: read dynamic
+            [array  byte        terminalLevels        count 'numBytes-1'       ]
+            [simple byte        reStrikeDelay                   ]
         ]
         ['MinimumLevels'                IdentifyReplyCommandMinimumLevels
-            //TODO: read dynamic
+            [array  byte        minimumLevels       count 'numBytes'       ]
         ]
         ['MaximumLevels'                IdentifyReplyCommandMaximumLevels
-            //TODO: read dynamic
+            [array  byte        maximumLevels       count 'numBytes'       ]
         ]
         ['CurrentSenseLevels'           IdentifyReplyCommandCurrentSenseLevels
-            //TODO: read dynamic
+            [array  byte        currentSenseLevels  count 'numBytes'       ]
         ]
         ['OutputUnitSummary'            IdentifyReplyCommandOutputUnitSummary
             // TODO: we can use the bytes from above, but how is that dynamic? repeat the complete block here?
@@ -1095,6 +1096,17 @@
     [simple bit unitGeneratingClock     ]
 ]
 
+[type LogicAssignment
+    [simple   bit greaterOfOrLogic  ]
+    [simple   bit reStrikeDelay     ]
+    [reserved bit 'false'           ]
+    [reserved bit 'false'           ]
+    [simple   bit assignedToGav16   ]
+    [simple   bit assignedToGav15   ]
+    [simple   bit assignedToGav14   ]
+    [simple   bit assignedToGav13   ]
+]
+
 [enum uint 8 ChannelStatus
     ['0'    OK                      ]
     ['2'    LAMP_FAULT              ]