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/21 16:44:51 UTC

[plc4x] branch develop updated (cfffc808d -> 3f286e3ff)

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

sruehl pushed a change to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git


    from cfffc808d feat(cbus): validate the checksum on read
     new de934ecc6 fix(cbus): fix reset and write command
     new 3f286e3ff test(cbus): added tests from quick start reference

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../protocols/cbus/readwrite/model/CALDataWrite.go |  30 +-
 .../protocols/cbus/readwrite/model/RequestReset.go | 130 +++++++-
 .../internal/cbusanalyzer/analyzer.go              |   1 +
 .../org/apache/plc4x/java/cbus/ReferenceTest.java  | 363 +++++++++++++++++++++
 .../src/main/resources/protocols/cbus/c-bus.mspec  |   8 +-
 5 files changed, 527 insertions(+), 5 deletions(-)


[plc4x] 01/02: fix(cbus): fix reset and write command

Posted by sr...@apache.org.
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 de934ecc67f9cbb718109c01d7ac3dd700fb8c50
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Thu Jul 21 18:44:21 2022 +0200

    fix(cbus): fix reset and write command
---
 .../protocols/cbus/readwrite/model/CALDataWrite.go |  30 ++++-
 .../protocols/cbus/readwrite/model/RequestReset.go | 130 ++++++++++++++++++++-
 .../src/main/resources/protocols/cbus/c-bus.mspec  |   8 +-
 3 files changed, 163 insertions(+), 5 deletions(-)

diff --git a/plc4go/protocols/cbus/readwrite/model/CALDataWrite.go b/plc4go/protocols/cbus/readwrite/model/CALDataWrite.go
index 82b765f04..9f98c93ab 100644
--- a/plc4go/protocols/cbus/readwrite/model/CALDataWrite.go
+++ b/plc4go/protocols/cbus/readwrite/model/CALDataWrite.go
@@ -33,6 +33,8 @@ type CALDataWrite interface {
 	CALData
 	// GetParamNo returns ParamNo (property field)
 	GetParamNo() Parameter
+	// GetCode returns Code (property field)
+	GetCode() byte
 	// GetData returns Data (property field)
 	GetData() []byte
 }
@@ -48,6 +50,7 @@ type CALDataWriteExactly interface {
 type _CALDataWrite struct {
 	*_CALData
 	ParamNo Parameter
+	Code    byte
 	Data    []byte
 }
 
@@ -79,6 +82,10 @@ func (m *_CALDataWrite) GetParamNo() Parameter {
 	return m.ParamNo
 }
 
+func (m *_CALDataWrite) GetCode() byte {
+	return m.Code
+}
+
 func (m *_CALDataWrite) GetData() []byte {
 	return m.Data
 }
@@ -89,9 +96,10 @@ func (m *_CALDataWrite) GetData() []byte {
 ///////////////////////////////////////////////////////////
 
 // NewCALDataWrite factory function for _CALDataWrite
-func NewCALDataWrite(paramNo Parameter, data []byte, commandTypeContainer CALCommandTypeContainer, additionalData CALData, requestContext RequestContext) *_CALDataWrite {
+func NewCALDataWrite(paramNo Parameter, code byte, data []byte, commandTypeContainer CALCommandTypeContainer, additionalData CALData, requestContext RequestContext) *_CALDataWrite {
 	_result := &_CALDataWrite{
 		ParamNo:  paramNo,
+		Code:     code,
 		Data:     data,
 		_CALData: NewCALData(commandTypeContainer, additionalData, requestContext),
 	}
@@ -124,6 +132,9 @@ func (m *_CALDataWrite) GetLengthInBitsConditional(lastItem bool) uint16 {
 	// Simple field (paramNo)
 	lengthInBits += 8
 
+	// Simple field (code)
+	lengthInBits += 8
+
 	// Array field
 	if len(m.Data) > 0 {
 		lengthInBits += 8 * uint16(len(m.Data))
@@ -157,8 +168,15 @@ func CALDataWriteParse(readBuffer utils.ReadBuffer, requestContext RequestContex
 	if closeErr := readBuffer.CloseContext("paramNo"); closeErr != nil {
 		return nil, errors.Wrap(closeErr, "Error closing for paramNo")
 	}
+
+	// Simple Field (code)
+	_code, _codeErr := readBuffer.ReadByte("code")
+	if _codeErr != nil {
+		return nil, errors.Wrap(_codeErr, "Error parsing 'code' field of CALDataWrite")
+	}
+	code := _code
 	// Byte Array field (data)
-	numberOfBytesdata := int(uint16(commandTypeContainer.NumBytes()) - uint16(uint16(1)))
+	numberOfBytesdata := int(uint16(commandTypeContainer.NumBytes()) - uint16(uint16(2)))
 	data, _readArrayErr := readBuffer.ReadByteArray("data", numberOfBytesdata)
 	if _readArrayErr != nil {
 		return nil, errors.Wrap(_readArrayErr, "Error parsing 'data' field of CALDataWrite")
@@ -171,6 +189,7 @@ func CALDataWriteParse(readBuffer utils.ReadBuffer, requestContext RequestContex
 	// Create a partially initialized instance
 	_child := &_CALDataWrite{
 		ParamNo: paramNo,
+		Code:    code,
 		Data:    data,
 		_CALData: &_CALData{
 			RequestContext: requestContext,
@@ -200,6 +219,13 @@ func (m *_CALDataWrite) Serialize(writeBuffer utils.WriteBuffer) error {
 			return errors.Wrap(_paramNoErr, "Error serializing 'paramNo' field")
 		}
 
+		// Simple Field (code)
+		code := byte(m.GetCode())
+		_codeErr := writeBuffer.WriteByte("code", (code))
+		if _codeErr != nil {
+			return errors.Wrap(_codeErr, "Error serializing 'code' field")
+		}
+
 		// Array Field (data)
 		// Byte Array field (data)
 		if err := writeBuffer.WriteByteArray("data", m.GetData()); err != nil {
diff --git a/plc4go/protocols/cbus/readwrite/model/RequestReset.go b/plc4go/protocols/cbus/readwrite/model/RequestReset.go
index 23ce05c89..d34c43d5d 100644
--- a/plc4go/protocols/cbus/readwrite/model/RequestReset.go
+++ b/plc4go/protocols/cbus/readwrite/model/RequestReset.go
@@ -31,6 +31,14 @@ type RequestReset interface {
 	utils.LengthAware
 	utils.Serializable
 	Request
+	// GetTildePeek returns TildePeek (property field)
+	GetTildePeek() RequestType
+	// GetSecondTilde returns SecondTilde (property field)
+	GetSecondTilde() *byte
+	// GetTildePeek2 returns TildePeek2 (property field)
+	GetTildePeek2() RequestType
+	// GetThirdTilde returns ThirdTilde (property field)
+	GetThirdTilde() *byte
 }
 
 // RequestResetExactly can be used when we want exactly this type and not a type which fulfills RequestReset.
@@ -43,6 +51,10 @@ type RequestResetExactly interface {
 // _RequestReset is the data-structure of this message
 type _RequestReset struct {
 	*_Request
+	TildePeek   RequestType
+	SecondTilde *byte
+	TildePeek2  RequestType
+	ThirdTilde  *byte
 }
 
 ///////////////////////////////////////////////////////////
@@ -67,10 +79,40 @@ func (m *_RequestReset) GetParent() Request {
 	return m._Request
 }
 
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_RequestReset) GetTildePeek() RequestType {
+	return m.TildePeek
+}
+
+func (m *_RequestReset) GetSecondTilde() *byte {
+	return m.SecondTilde
+}
+
+func (m *_RequestReset) GetTildePeek2() RequestType {
+	return m.TildePeek2
+}
+
+func (m *_RequestReset) GetThirdTilde() *byte {
+	return m.ThirdTilde
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
 // NewRequestReset factory function for _RequestReset
-func NewRequestReset(peekedByte RequestType, startingCR *RequestType, resetMode *RequestType, secondPeek RequestType, termination RequestTermination, cBusOptions CBusOptions, messageLength uint16) *_RequestReset {
+func NewRequestReset(tildePeek RequestType, secondTilde *byte, tildePeek2 RequestType, thirdTilde *byte, peekedByte RequestType, startingCR *RequestType, resetMode *RequestType, secondPeek RequestType, termination RequestTermination, cBusOptions CBusOptions, messageLength uint16) *_RequestReset {
 	_result := &_RequestReset{
-		_Request: NewRequest(peekedByte, startingCR, resetMode, secondPeek, termination, cBusOptions, messageLength),
+		TildePeek:   tildePeek,
+		SecondTilde: secondTilde,
+		TildePeek2:  tildePeek2,
+		ThirdTilde:  thirdTilde,
+		_Request:    NewRequest(peekedByte, startingCR, resetMode, secondPeek, termination, cBusOptions, messageLength),
 	}
 	_result._Request._RequestChildRequirements = _result
 	return _result
@@ -98,6 +140,16 @@ func (m *_RequestReset) GetLengthInBits() uint16 {
 func (m *_RequestReset) GetLengthInBitsConditional(lastItem bool) uint16 {
 	lengthInBits := uint16(m.GetParentLengthInBits())
 
+	// Optional Field (secondTilde)
+	if m.SecondTilde != nil {
+		lengthInBits += 8
+	}
+
+	// Optional Field (thirdTilde)
+	if m.ThirdTilde != nil {
+		lengthInBits += 8
+	}
+
 	return lengthInBits
 }
 
@@ -114,12 +166,66 @@ func RequestResetParse(readBuffer utils.ReadBuffer, cBusOptions CBusOptions, mes
 	currentPos := positionAware.GetPos()
 	_ = currentPos
 
+	// Peek Field (tildePeek)
+	currentPos = positionAware.GetPos()
+	if pullErr := readBuffer.PullContext("tildePeek"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for tildePeek")
+	}
+	tildePeek, _err := RequestTypeParse(readBuffer)
+	if _err != nil {
+		return nil, errors.Wrap(_err, "Error parsing 'tildePeek' field of RequestReset")
+	}
+	if closeErr := readBuffer.CloseContext("tildePeek"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for tildePeek")
+	}
+
+	readBuffer.Reset(currentPos)
+
+	// Optional Field (secondTilde) (Can be skipped, if a given expression evaluates to false)
+	var secondTilde *byte = nil
+	if bool((tildePeek) == (RequestType_RESET)) {
+		_val, _err := readBuffer.ReadByte("secondTilde")
+		if _err != nil {
+			return nil, errors.Wrap(_err, "Error parsing 'secondTilde' field of RequestReset")
+		}
+		secondTilde = &_val
+	}
+
+	// Peek Field (tildePeek2)
+	currentPos = positionAware.GetPos()
+	if pullErr := readBuffer.PullContext("tildePeek2"); pullErr != nil {
+		return nil, errors.Wrap(pullErr, "Error pulling for tildePeek2")
+	}
+	tildePeek2, _err := RequestTypeParse(readBuffer)
+	if _err != nil {
+		return nil, errors.Wrap(_err, "Error parsing 'tildePeek2' field of RequestReset")
+	}
+	if closeErr := readBuffer.CloseContext("tildePeek2"); closeErr != nil {
+		return nil, errors.Wrap(closeErr, "Error closing for tildePeek2")
+	}
+
+	readBuffer.Reset(currentPos)
+
+	// Optional Field (thirdTilde) (Can be skipped, if a given expression evaluates to false)
+	var thirdTilde *byte = nil
+	if bool((tildePeek2) == (RequestType_RESET)) {
+		_val, _err := readBuffer.ReadByte("thirdTilde")
+		if _err != nil {
+			return nil, errors.Wrap(_err, "Error parsing 'thirdTilde' field of RequestReset")
+		}
+		thirdTilde = &_val
+	}
+
 	if closeErr := readBuffer.CloseContext("RequestReset"); closeErr != nil {
 		return nil, errors.Wrap(closeErr, "Error closing for RequestReset")
 	}
 
 	// Create a partially initialized instance
 	_child := &_RequestReset{
+		TildePeek:   tildePeek,
+		SecondTilde: secondTilde,
+		TildePeek2:  tildePeek2,
+		ThirdTilde:  thirdTilde,
 		_Request: &_Request{
 			CBusOptions:   cBusOptions,
 			MessageLength: messageLength,
@@ -137,6 +243,26 @@ func (m *_RequestReset) Serialize(writeBuffer utils.WriteBuffer) error {
 			return errors.Wrap(pushErr, "Error pushing for RequestReset")
 		}
 
+		// Optional Field (secondTilde) (Can be skipped, if the value is null)
+		var secondTilde *byte = nil
+		if m.GetSecondTilde() != nil {
+			secondTilde = m.GetSecondTilde()
+			_secondTildeErr := writeBuffer.WriteByte("secondTilde", *(secondTilde))
+			if _secondTildeErr != nil {
+				return errors.Wrap(_secondTildeErr, "Error serializing 'secondTilde' field")
+			}
+		}
+
+		// Optional Field (thirdTilde) (Can be skipped, if the value is null)
+		var thirdTilde *byte = nil
+		if m.GetThirdTilde() != nil {
+			thirdTilde = m.GetThirdTilde()
+			_thirdTildeErr := writeBuffer.WriteByte("thirdTilde", *(thirdTilde))
+			if _thirdTildeErr != nil {
+				return errors.Wrap(_thirdTildeErr, "Error serializing 'thirdTilde' field")
+			}
+		}
+
 		if popErr := writeBuffer.PopContext("RequestReset"); popErr != nil {
 			return errors.Wrap(popErr, "Error popping for RequestReset")
 		}
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 8f18b5658..594ddff41 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
@@ -78,6 +78,10 @@
             [optional byte        secondPipe 'pipePeek == RequestType.SMART_CONNECT_SHORTCUT']
         ]
         ['RESET' *Reset
+            [peek     RequestType tildePeek                                     ]
+            [optional byte        secondTilde 'tildePeek == RequestType.RESET'  ]
+            [peek     RequestType tildePeek2                                    ]
+            [optional byte        thirdTilde 'tildePeek2 == RequestType.RESET'  ]
         ]
         ['DIRECT_COMMAND' *DirectCommandAccess(uint 16 payloadLength)
             [const    byte    at        0x40                                ]
@@ -583,7 +587,9 @@
         ]
         ['WRITE'            *Write(CALCommandTypeContainer commandTypeContainer)                // Request
             [simple Parameter paramNo                                                       ]
-            [array  byte      data        count 'commandTypeContainer.numBytes-1'           ]
+            [simple byte      code                                                          ]
+            // TODO: we can decode this with the parametert above... e.g. INTERFACE_OPTIONS_1 is defined below
+            [array  byte      data        count 'commandTypeContainer.numBytes - 2'         ]
         ]
         ['REPLY', 'true'    *IdentifyReply(CALCommandTypeContainer commandTypeContainer)        // Reply
             [simple Attribute   attribute                                                   ]


[plc4x] 02/02: test(cbus): added tests from quick start reference

Posted by sr...@apache.org.
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 3f286e3ff41116efd72cf4d7561d7128f45a34e0
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Thu Jul 21 18:44:44 2022 +0200

    test(cbus): added tests from quick start reference
---
 .../internal/cbusanalyzer/analyzer.go              |   1 +
 .../org/apache/plc4x/java/cbus/ReferenceTest.java  | 363 +++++++++++++++++++++
 2 files changed, 364 insertions(+)

diff --git a/plc4go/tools/plc4xpcapanalyzer/internal/cbusanalyzer/analyzer.go b/plc4go/tools/plc4xpcapanalyzer/internal/cbusanalyzer/analyzer.go
index 3ba9b6400..5694f02fb 100644
--- a/plc4go/tools/plc4xpcapanalyzer/internal/cbusanalyzer/analyzer.go
+++ b/plc4go/tools/plc4xpcapanalyzer/internal/cbusanalyzer/analyzer.go
@@ -64,6 +64,7 @@ func (a *Analyzer) PackageParse(packetInformation common.PacketInformation, payl
 	if err != nil {
 		return nil, err
 	}
+	// TODO: apparently we only do crc on receive with our tests so we need to implement that
 	parse, err := model.CBusMessageParse(utils.NewReadBufferByteBased(currentPayload), isResponse, a.requestContext, a.cBusOptions, uint16(len(currentPayload)))
 	if err != nil {
 		return nil, errors.Wrap(err, "Error parsing CBusCommand")
diff --git a/plc4j/drivers/c-bus/src/test/java/org/apache/plc4x/java/cbus/ReferenceTest.java b/plc4j/drivers/c-bus/src/test/java/org/apache/plc4x/java/cbus/ReferenceTest.java
index 4959ede87..1a26c2a41 100644
--- a/plc4j/drivers/c-bus/src/test/java/org/apache/plc4x/java/cbus/ReferenceTest.java
+++ b/plc4j/drivers/c-bus/src/test/java/org/apache/plc4x/java/cbus/ReferenceTest.java
@@ -641,6 +641,369 @@ public class ReferenceTest {
             assertMessageMatches(bytes, msg);
         }
 
+        //5.2
+        @Nested
+        class PCI_Setup {
+
+            // 5.2.1
+            @Nested
+            class MMIMessagesNotRequired {
+
+                @Test
+                void init() throws Exception {
+                    byte[] bytes = "~~~\r".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, false, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                }
+
+                @Test
+                void writeSomething() throws Exception {
+                    byte[] bytes = "A3210038g\r".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, false, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                    System.out.println(((RequestObsolete) ((CBusMessageToServer) msg).getRequest()).getCalData());
+                }
+
+                @Test
+                void writeSomethingResponse() throws Exception {
+                    byte[] bytes = "g.322100AD\r\n".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    requestContext = new RequestContext(true, false, false);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                    System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((ReplyOrConfirmationConfirmation) ((CBusMessageToClient) msg).getReply()).getEmbeddedReply()).getReply()).getEncodedReply());
+                }
+
+                @Test
+                void writeSomething2() throws Exception {
+                    byte[] bytes = "A3420002g\r".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, false, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                    System.out.println(((RequestObsolete) ((CBusMessageToServer) msg).getRequest()).getCalData());
+                }
+
+                @Test
+                void writeSomethingResponse2() throws Exception {
+                    byte[] bytes = "g.3242008C\r\n".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    requestContext = new RequestContext(true, false, false);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                    System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((ReplyOrConfirmationConfirmation) ((CBusMessageToClient) msg).getReply()).getEmbeddedReply()).getReply()).getEncodedReply());
+                }
+
+                @Test
+                void writeSomething3() throws Exception {
+                    byte[] bytes = "A3300059g\r".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, false, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                    System.out.println(((RequestObsolete) ((CBusMessageToServer) msg).getRequest()).getCalData());
+                }
+
+                @Test
+                void writeSomethingResponse3() throws Exception {
+                    byte[] bytes = "g.8600000032300000\r\n".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    requestContext = new RequestContext(true, false, false);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                    System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((ReplyOrConfirmationConfirmation) ((CBusMessageToClient) msg).getReply()).getEmbeddedReply()).getReply()).getEncodedReply());
+                }
+            }
+
+            // 5.2.2
+            @Test
+            void MMIMessagesRequired() throws Exception {
+                byte[] bytes = "A3300079g\r".getBytes(StandardCharsets.UTF_8);
+                ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, false, requestContext, cBusOptions, bytes.length);
+                assertThat(msg).isNotNull();
+                System.out.println(msg);
+                System.out.println(((RequestObsolete) ((CBusMessageToServer) msg).getRequest()).getCalData());
+            }
+        }
+
+        // 6
+        @Nested
+        class TransmittingCBusLightingControlCommands {
+            // 6.1
+            @Test
+            void TransmitAnONCommand() throws Exception {
+                byte[] bytes = "\\053800790842u\r".getBytes(StandardCharsets.UTF_8);
+                ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, false, requestContext, cBusOptions, bytes.length);
+                assertThat(msg).isNotNull();
+                System.out.println(msg);
+                System.out.println(((RequestCommand) ((CBusMessageToServer) msg).getRequest()).getCbusCommand());
+            }
+
+            // 6.2
+            @Test
+            void TransmitAnOFFCommand() throws Exception {
+                byte[] bytes = "\\0538000108BAu\r".getBytes(StandardCharsets.UTF_8);
+                ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, false, requestContext, cBusOptions, bytes.length);
+                assertThat(msg).isNotNull();
+                System.out.println(msg);
+                System.out.println(((RequestCommand) ((CBusMessageToServer) msg).getRequest()).getCbusCommand());
+            }
+
+            // 6.3
+            @Test
+            void TransmitAnRampToLevelCommand() throws Exception {
+                byte[] bytes = "\\0538005A08550Cu\r".getBytes(StandardCharsets.UTF_8);
+                ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, false, requestContext, cBusOptions, bytes.length);
+                assertThat(msg).isNotNull();
+                System.out.println(msg);
+                System.out.println(((RequestCommand) ((CBusMessageToServer) msg).getRequest()).getCbusCommand());
+            }
+        }
+
+        // 7
+        @Nested
+        class ReceivingCBusLightingControlCommands {
+            // 7.1
+            @Test
+            void ReceiveAnONCommand() throws Exception {
+                byte[] bytes = "05003800790842\r\n".getBytes(StandardCharsets.UTF_8);
+                ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                assertThat(msg).isNotNull();
+                System.out.println(msg);
+                System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((CBusMessageToClient) msg).getReply()).getReply()).getEncodedReply());
+            }
+
+            // 7.1
+            @Test
+            void ReceiveAnONCommandAlternative() throws Exception {
+                byte[] bytes = "0500380100790841\r\n".getBytes(StandardCharsets.UTF_8);
+                ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                assertThat(msg).isNotNull();
+                System.out.println(msg);
+                System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((CBusMessageToClient) msg).getReply()).getReply()).getEncodedReply());
+            }
+
+            // 7.2
+            @Test
+            void ReceiveAnOFFCommand() throws Exception {
+                byte[] bytes = "050038000108BA\r\n".getBytes(StandardCharsets.UTF_8);
+                ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                assertThat(msg).isNotNull();
+                System.out.println(msg);
+                System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((CBusMessageToClient) msg).getReply()).getReply()).getEncodedReply());
+            }
+
+            // 7.2
+            @Test
+            void ReceiveAnOFFCommandAlternative() throws Exception {
+                byte[] bytes = "05003801000108B9\r\n".getBytes(StandardCharsets.UTF_8);
+                ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                assertThat(msg).isNotNull();
+                System.out.println(msg);
+                System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((CBusMessageToClient) msg).getReply()).getReply()).getEncodedReply());
+            }
+
+            // 7.3
+            @Test
+            void ReceiveAnRampToLevelCommand() throws Exception {
+                byte[] bytes = "05003800550855C3\r\n".getBytes(StandardCharsets.UTF_8);
+                ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                assertThat(msg).isNotNull();
+                System.out.println(msg);
+                System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((CBusMessageToClient) msg).getReply()).getReply()).getEncodedReply());
+            }
+
+            // 7.3
+            @Test
+            void ReceiveAnRampToLevelCommandAlternative() throws Exception {
+                byte[] bytes = "0500380100550855C2\r\n".getBytes(StandardCharsets.UTF_8);
+                ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                assertThat(msg).isNotNull();
+                System.out.println(msg);
+                System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((CBusMessageToClient) msg).getReply()).getReply()).getEncodedReply());
+            }
+
+            @Disabled("Needs to be implemented")
+            // 7.4
+            @Nested
+            class ReceivingOtherCommands {
+                @Test
+                void Case1() throws Exception {
+                    // Test with nn not 00 or 01... they should be discarded
+                    byte[] bytes = "05ss38nn....zz\r".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                    System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((CBusMessageToClient) msg).getReply()).getReply()).getEncodedReply());
+                }
+
+                @Test
+                void Case2() throws Exception {
+                    // Test with nn not 00 or 01... they should be discarded
+                    byte[] bytes = "05ss3800cc....zz\r".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                    System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((CBusMessageToClient) msg).getReply()).getReply()).getEncodedReply());
+                }
+
+                @Test
+                void Case2Alternative() throws Exception {
+                    // Test with nn not 00 or 01... they should be discarded
+                    byte[] bytes = "05ss380100cc....zz\r".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                    System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((CBusMessageToClient) msg).getReply()).getReply()).getEncodedReply());
+                }
+            }
+
+        }
+
+        // 8
+        @Nested
+        class InterpretingTheMmi {
+            @Test
+            void BigMMI1() throws Exception {
+                byte[] bytes = "D8380068AA0140550550001000000014000000000000000000CF\r\n".getBytes(StandardCharsets.UTF_8);
+                ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                assertThat(msg).isNotNull();
+                System.out.println(msg);
+                System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((CBusMessageToClient) msg).getReply()).getReply()).getEncodedReply());
+            }
+
+            @Test
+            void BigMMI2() throws Exception {
+                byte[] bytes = "D838580000000000000000000000000000000000000000000098\r\n".getBytes(StandardCharsets.UTF_8);
+                ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                assertThat(msg).isNotNull();
+                System.out.println(msg);
+                System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((CBusMessageToClient) msg).getReply()).getReply()).getEncodedReply());
+            }
+
+            @Test
+            void BigMMI3() throws Exception {
+                byte[] bytes = "D638B000000000FF00000000000000000000000000000043\r\n".getBytes(StandardCharsets.UTF_8);
+                ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                assertThat(msg).isNotNull();
+                System.out.println(msg);
+                System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((CBusMessageToClient) msg).getReply()).getReply()).getEncodedReply());
+            }
+        }
+
+        // 9
+        @Nested
+        class Example {
+            @Nested
+            class ControlExamples {
+                @Test
+                void turnOnLight() throws Exception {
+                    byte[] bytes = "\\053800792129g\r".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, false, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                    System.out.println(((RequestCommand) ((CBusMessageToServer) msg).getRequest()).getCbusCommand());
+                }
+
+                @Test
+                void turnOffLight() throws Exception {
+                    byte[] bytes = "\\0538000121A1g\r".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, false, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                    System.out.println(((RequestCommand) ((CBusMessageToServer) msg).getRequest()).getCbusCommand());
+                }
+
+                @Test
+                void rampLight() throws Exception {
+                    byte[] bytes = "\\0538000A217F19g\r".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, false, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                    System.out.println(((RequestCommand) ((CBusMessageToServer) msg).getRequest()).getCbusCommand());
+                }
+            }
+
+            @Nested
+            class MontiorExamples {
+                @Test
+                void onCommand() throws Exception {
+                    byte[] bytes = "050B380079201F\r\n".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                    System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((CBusMessageToClient) msg).getReply()).getReply()).getEncodedReply());
+                }
+
+                @Test
+                void offCommand() throws Exception {
+                    byte[] bytes = "050B3800012097\r\n".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                    System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((CBusMessageToClient) msg).getReply()).getReply()).getEncodedReply());
+                }
+
+                @Test
+                void Ramp() throws Exception {
+                    byte[] bytes = "050B38000220484E\r\n".getBytes(StandardCharsets.UTF_8);
+                    ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
+                    cBusOptions = new CBusOptions(false, false, false, false, false, false, false, false, true);
+                    CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
+                    assertThat(msg).isNotNull();
+                    System.out.println(msg);
+                    System.out.println(((ReplyEncodedReply) ((ReplyOrConfirmationReply) ((CBusMessageToClient) msg).getReply()).getReply()).getEncodedReply());
+                }
+            }
+        }
     }
 
     // from: https://updates.clipsal.com/ClipsalSoftwareDownload/DL/downloads/OpenCBus/Chapter%2002%20-%20C-Bus%20Lighting%20Application.pdf