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/28 12:46:41 UTC
[plc4x] 03/03: fix(cbus): fixed level reporting for ExtendedFormatStatusReply
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 0b713c67bbb6c1fc86a01cd18f11a71a20536400
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Thu Jul 28 14:46:31 2022 +0200
fix(cbus): fixed level reporting for ExtendedFormatStatusReply
---
plc4go/internal/cbus/Reader.go | 20 +-
plc4go/protocols/cbus/readwrite/ParserHelper.go | 2 +
plc4go/protocols/cbus/readwrite/XmlParserHelper.go | 2 +
.../readwrite/model/ExtendedFormatStatusReply.go | 123 +++++++-
.../cbus/readwrite/model/LevelInformation.go | 344 +++++++++++++++++++++
.../cbus/readwrite/model/LevelInformationAbsent.go | 180 +++++++++++
.../readwrite/model/LevelInformationCorrupted.go | 268 ++++++++++++++++
.../readwrite/model/LevelInformationNibblePair.go | 323 +++++++++++++++++++
.../cbus/readwrite/model/LevelInformationNormal.go | 264 ++++++++++++++++
.../org/apache/plc4x/java/cbus/ReferenceTest.java | 2 +-
.../src/main/resources/protocols/cbus/c-bus.mspec | 57 +++-
.../server/cbus/protocol/CBusServerAdapter.java | 8 +-
12 files changed, 1572 insertions(+), 21 deletions(-)
diff --git a/plc4go/internal/cbus/Reader.go b/plc4go/internal/cbus/Reader.go
index 6eaa35c20..ccab01381 100644
--- a/plc4go/internal/cbus/Reader.go
+++ b/plc4go/internal/cbus/Reader.go
@@ -163,10 +163,22 @@ func (m *Reader) Read(readRequest model.PlcReadRequest) <-chan model.PlcReadRequ
blockStart := reply.GetReply().GetBlockStart()
// TODO: verify application... this should be the same
_ = blockStart
- statusBytes := reply.GetReply().GetStatusBytes()
- addResponseCode(fieldNameCopy, model.PlcResponseCode_OK)
- // TODO: how should we serialize that???
- addPlcValue(fieldNameCopy, values2.NewPlcSTRING(fmt.Sprintf("%s", statusBytes)))
+ switch coding {
+ case readWriteModel.StatusCoding_BINARY_BY_THIS_SERIAL_INTERFACE:
+ fallthrough
+ case readWriteModel.StatusCoding_BINARY_BY_ELSEWHERE:
+ statusBytes := reply.GetReply().GetStatusBytes()
+ addResponseCode(fieldNameCopy, model.PlcResponseCode_OK)
+ // TODO: how should we serialize that???
+ addPlcValue(fieldNameCopy, values2.NewPlcSTRING(fmt.Sprintf("%s", statusBytes)))
+ case readWriteModel.StatusCoding_LEVEL_BY_THIS_SERIAL_INTERFACE:
+ fallthrough
+ case readWriteModel.StatusCoding_LEVEL_BY_ELSEWHERE:
+ levelInformation := reply.GetReply().GetLevelInformation()
+ addResponseCode(fieldNameCopy, model.PlcResponseCode_OK)
+ // TODO: how should we serialize that???
+ addPlcValue(fieldNameCopy, values2.NewPlcSTRING(fmt.Sprintf("%s", levelInformation)))
+ }
case readWriteModel.EncodedReplyCALReplyExactly:
calData := reply.GetCalReply().GetCalData()
addResponseCode(fieldNameCopy, model.PlcResponseCode_OK)
diff --git a/plc4go/protocols/cbus/readwrite/ParserHelper.go b/plc4go/protocols/cbus/readwrite/ParserHelper.go
index 382deb3a6..76039241c 100644
--- a/plc4go/protocols/cbus/readwrite/ParserHelper.go
+++ b/plc4go/protocols/cbus/readwrite/ParserHelper.go
@@ -151,6 +151,8 @@ func (m CbusParserHelper) Parse(typeName string, arguments []string, io utils.Re
return model.StandardFormatStatusReplyParse(io)
case "ResponseTermination":
return model.ResponseTerminationParse(io)
+ case "LevelInformation":
+ return model.LevelInformationParse(io)
case "SALData":
applicationId, _ := model.ApplicationIdByName(arguments[0])
return model.SALDataParse(io, applicationId)
diff --git a/plc4go/protocols/cbus/readwrite/XmlParserHelper.go b/plc4go/protocols/cbus/readwrite/XmlParserHelper.go
index 0b5ae2192..69d4d0d2b 100644
--- a/plc4go/protocols/cbus/readwrite/XmlParserHelper.go
+++ b/plc4go/protocols/cbus/readwrite/XmlParserHelper.go
@@ -170,6 +170,8 @@ func (m CbusXmlParserHelper) Parse(typeName string, xmlString string, parserArgu
return model.StandardFormatStatusReplyParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
case "ResponseTermination":
return model.ResponseTerminationParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
+ case "LevelInformation":
+ return model.LevelInformationParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)))
case "SALData":
applicationId, _ := model.ApplicationIdByName(parserArguments[0])
return model.SALDataParse(utils.NewXmlReadBuffer(strings.NewReader(xmlString)), applicationId)
diff --git a/plc4go/protocols/cbus/readwrite/model/ExtendedFormatStatusReply.go b/plc4go/protocols/cbus/readwrite/model/ExtendedFormatStatusReply.go
index dd9f58bac..9314c2250 100644
--- a/plc4go/protocols/cbus/readwrite/model/ExtendedFormatStatusReply.go
+++ b/plc4go/protocols/cbus/readwrite/model/ExtendedFormatStatusReply.go
@@ -40,6 +40,12 @@ type ExtendedFormatStatusReply interface {
GetBlockStart() uint8
// GetStatusBytes returns StatusBytes (property field)
GetStatusBytes() []StatusByte
+ // GetLevelInformation returns LevelInformation (property field)
+ GetLevelInformation() []LevelInformation
+ // GetNumberOfStatusBytes returns NumberOfStatusBytes (virtual field)
+ GetNumberOfStatusBytes() uint8
+ // GetNumberOfLevelInformation returns NumberOfLevelInformation (virtual field)
+ GetNumberOfLevelInformation() uint8
}
// ExtendedFormatStatusReplyExactly can be used when we want exactly this type and not a type which fulfills ExtendedFormatStatusReply.
@@ -51,11 +57,12 @@ type ExtendedFormatStatusReplyExactly interface {
// _ExtendedFormatStatusReply is the data-structure of this message
type _ExtendedFormatStatusReply struct {
- StatusHeader ExtendedStatusHeader
- Coding StatusCoding
- Application ApplicationIdContainer
- BlockStart uint8
- StatusBytes []StatusByte
+ StatusHeader ExtendedStatusHeader
+ Coding StatusCoding
+ Application ApplicationIdContainer
+ BlockStart uint8
+ StatusBytes []StatusByte
+ LevelInformation []LevelInformation
}
///////////////////////////////////////////////////////////
@@ -83,14 +90,39 @@ func (m *_ExtendedFormatStatusReply) GetStatusBytes() []StatusByte {
return m.StatusBytes
}
+func (m *_ExtendedFormatStatusReply) GetLevelInformation() []LevelInformation {
+ return m.LevelInformation
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for virtual fields.
+///////////////////////
+
+func (m *_ExtendedFormatStatusReply) GetNumberOfStatusBytes() uint8 {
+ return uint8(utils.InlineIf(bool(bool(bool((m.GetCoding()) == (StatusCoding_BINARY_BY_THIS_SERIAL_INTERFACE))) || bool(bool((m.GetCoding()) == (StatusCoding_BINARY_BY_ELSEWHERE)))), func() interface{} {
+ return uint8(uint8(uint8(m.GetStatusHeader().GetNumberOfCharacterPairs()) - uint8(uint8(3))))
+ }, func() interface{} { return uint8(uint8(uint8(0))) }).(uint8))
+}
+
+func (m *_ExtendedFormatStatusReply) GetNumberOfLevelInformation() uint8 {
+ return uint8(utils.InlineIf(bool(bool(bool((m.GetCoding()) == (StatusCoding_LEVEL_BY_THIS_SERIAL_INTERFACE))) || bool(bool((m.GetCoding()) == (StatusCoding_LEVEL_BY_ELSEWHERE)))), func() interface{} {
+ return uint8(uint8(uint8(uint8(uint8(m.GetStatusHeader().GetNumberOfCharacterPairs())-uint8(uint8(3)))) / uint8(uint8(2))))
+ }, func() interface{} { return uint8(uint8(uint8(0))) }).(uint8))
+}
+
///////////////////////
///////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// NewExtendedFormatStatusReply factory function for _ExtendedFormatStatusReply
-func NewExtendedFormatStatusReply(statusHeader ExtendedStatusHeader, coding StatusCoding, application ApplicationIdContainer, blockStart uint8, statusBytes []StatusByte) *_ExtendedFormatStatusReply {
- return &_ExtendedFormatStatusReply{StatusHeader: statusHeader, Coding: coding, Application: application, BlockStart: blockStart, StatusBytes: statusBytes}
+func NewExtendedFormatStatusReply(statusHeader ExtendedStatusHeader, coding StatusCoding, application ApplicationIdContainer, blockStart uint8, statusBytes []StatusByte, levelInformation []LevelInformation) *_ExtendedFormatStatusReply {
+ return &_ExtendedFormatStatusReply{StatusHeader: statusHeader, Coding: coding, Application: application, BlockStart: blockStart, StatusBytes: statusBytes, LevelInformation: levelInformation}
}
// Deprecated: use the interface for direct cast
@@ -127,6 +159,10 @@ func (m *_ExtendedFormatStatusReply) GetLengthInBitsConditional(lastItem bool) u
// Simple field (blockStart)
lengthInBits += 8
+ // A virtual field doesn't have any in- or output.
+
+ // A virtual field doesn't have any in- or output.
+
// Array field
if len(m.StatusBytes) > 0 {
for i, element := range m.StatusBytes {
@@ -135,6 +171,14 @@ func (m *_ExtendedFormatStatusReply) GetLengthInBitsConditional(lastItem bool) u
}
}
+ // Array field
+ if len(m.LevelInformation) > 0 {
+ for i, element := range m.LevelInformation {
+ last := i == len(m.LevelInformation)-1
+ lengthInBits += element.(interface{ GetLengthInBitsConditional(bool) uint16 }).GetLengthInBitsConditional(last)
+ }
+ }
+
return lengthInBits
}
@@ -197,18 +241,32 @@ func ExtendedFormatStatusReplyParse(readBuffer utils.ReadBuffer) (ExtendedFormat
}
blockStart := _blockStart
+ // Virtual field
+ _numberOfStatusBytes := utils.InlineIf(bool(bool(bool((coding) == (StatusCoding_BINARY_BY_THIS_SERIAL_INTERFACE))) || bool(bool((coding) == (StatusCoding_BINARY_BY_ELSEWHERE)))), func() interface{} {
+ return uint8(uint8(uint8(statusHeader.GetNumberOfCharacterPairs()) - uint8(uint8(3))))
+ }, func() interface{} { return uint8(uint8(uint8(0))) }).(uint8)
+ numberOfStatusBytes := uint8(_numberOfStatusBytes)
+ _ = numberOfStatusBytes
+
+ // Virtual field
+ _numberOfLevelInformation := utils.InlineIf(bool(bool(bool((coding) == (StatusCoding_LEVEL_BY_THIS_SERIAL_INTERFACE))) || bool(bool((coding) == (StatusCoding_LEVEL_BY_ELSEWHERE)))), func() interface{} {
+ return uint8(uint8(uint8(uint8(uint8(statusHeader.GetNumberOfCharacterPairs())-uint8(uint8(3)))) / uint8(uint8(2))))
+ }, func() interface{} { return uint8(uint8(uint8(0))) }).(uint8)
+ numberOfLevelInformation := uint8(_numberOfLevelInformation)
+ _ = numberOfLevelInformation
+
// Array field (statusBytes)
if pullErr := readBuffer.PullContext("statusBytes", utils.WithRenderAsList(true)); pullErr != nil {
return nil, errors.Wrap(pullErr, "Error pulling for statusBytes")
}
// Count array
- statusBytes := make([]StatusByte, uint16(statusHeader.GetNumberOfCharacterPairs())-uint16(uint16(3)))
+ statusBytes := make([]StatusByte, numberOfStatusBytes)
// This happens when the size is set conditional to 0
if len(statusBytes) == 0 {
statusBytes = nil
}
{
- for curItem := uint16(0); curItem < uint16(uint16(statusHeader.GetNumberOfCharacterPairs())-uint16(uint16(3))); curItem++ {
+ for curItem := uint16(0); curItem < uint16(numberOfStatusBytes); curItem++ {
_item, _err := StatusByteParse(readBuffer)
if _err != nil {
return nil, errors.Wrap(_err, "Error parsing 'statusBytes' field of ExtendedFormatStatusReply")
@@ -220,12 +278,35 @@ func ExtendedFormatStatusReplyParse(readBuffer utils.ReadBuffer) (ExtendedFormat
return nil, errors.Wrap(closeErr, "Error closing for statusBytes")
}
+ // Array field (levelInformation)
+ if pullErr := readBuffer.PullContext("levelInformation", utils.WithRenderAsList(true)); pullErr != nil {
+ return nil, errors.Wrap(pullErr, "Error pulling for levelInformation")
+ }
+ // Count array
+ levelInformation := make([]LevelInformation, numberOfLevelInformation)
+ // This happens when the size is set conditional to 0
+ if len(levelInformation) == 0 {
+ levelInformation = nil
+ }
+ {
+ for curItem := uint16(0); curItem < uint16(numberOfLevelInformation); curItem++ {
+ _item, _err := LevelInformationParse(readBuffer)
+ if _err != nil {
+ return nil, errors.Wrap(_err, "Error parsing 'levelInformation' field of ExtendedFormatStatusReply")
+ }
+ levelInformation[curItem] = _item.(LevelInformation)
+ }
+ }
+ if closeErr := readBuffer.CloseContext("levelInformation", utils.WithRenderAsList(true)); closeErr != nil {
+ return nil, errors.Wrap(closeErr, "Error closing for levelInformation")
+ }
+
if closeErr := readBuffer.CloseContext("ExtendedFormatStatusReply"); closeErr != nil {
return nil, errors.Wrap(closeErr, "Error closing for ExtendedFormatStatusReply")
}
// Create the instance
- return NewExtendedFormatStatusReply(statusHeader, coding, application, blockStart, statusBytes), nil
+ return NewExtendedFormatStatusReply(statusHeader, coding, application, blockStart, statusBytes, levelInformation), nil
}
func (m *_ExtendedFormatStatusReply) Serialize(writeBuffer utils.WriteBuffer) error {
@@ -277,6 +358,14 @@ func (m *_ExtendedFormatStatusReply) Serialize(writeBuffer utils.WriteBuffer) er
if _blockStartErr != nil {
return errors.Wrap(_blockStartErr, "Error serializing 'blockStart' field")
}
+ // Virtual field
+ if _numberOfStatusBytesErr := writeBuffer.WriteVirtual("numberOfStatusBytes", m.GetNumberOfStatusBytes()); _numberOfStatusBytesErr != nil {
+ return errors.Wrap(_numberOfStatusBytesErr, "Error serializing 'numberOfStatusBytes' field")
+ }
+ // Virtual field
+ if _numberOfLevelInformationErr := writeBuffer.WriteVirtual("numberOfLevelInformation", m.GetNumberOfLevelInformation()); _numberOfLevelInformationErr != nil {
+ return errors.Wrap(_numberOfLevelInformationErr, "Error serializing 'numberOfLevelInformation' field")
+ }
// Array Field (statusBytes)
if pushErr := writeBuffer.PushContext("statusBytes", utils.WithRenderAsList(true)); pushErr != nil {
@@ -292,6 +381,20 @@ func (m *_ExtendedFormatStatusReply) Serialize(writeBuffer utils.WriteBuffer) er
return errors.Wrap(popErr, "Error popping for statusBytes")
}
+ // Array Field (levelInformation)
+ if pushErr := writeBuffer.PushContext("levelInformation", utils.WithRenderAsList(true)); pushErr != nil {
+ return errors.Wrap(pushErr, "Error pushing for levelInformation")
+ }
+ for _, _element := range m.GetLevelInformation() {
+ _elementErr := writeBuffer.WriteSerializable(_element)
+ if _elementErr != nil {
+ return errors.Wrap(_elementErr, "Error serializing 'levelInformation' field")
+ }
+ }
+ if popErr := writeBuffer.PopContext("levelInformation", utils.WithRenderAsList(true)); popErr != nil {
+ return errors.Wrap(popErr, "Error popping for levelInformation")
+ }
+
if popErr := writeBuffer.PopContext("ExtendedFormatStatusReply"); popErr != nil {
return errors.Wrap(popErr, "Error popping for ExtendedFormatStatusReply")
}
diff --git a/plc4go/protocols/cbus/readwrite/model/LevelInformation.go b/plc4go/protocols/cbus/readwrite/model/LevelInformation.go
new file mode 100644
index 000000000..725752b65
--- /dev/null
+++ b/plc4go/protocols/cbus/readwrite/model/LevelInformation.go
@@ -0,0 +1,344 @@
+/*
+ * 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"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// LevelInformation is the corresponding interface of LevelInformation
+type LevelInformation interface {
+ utils.LengthAware
+ utils.Serializable
+ // GetRaw returns Raw (property field)
+ GetRaw() uint16
+ // GetNibble1 returns Nibble1 (virtual field)
+ GetNibble1() uint8
+ // GetNibble2 returns Nibble2 (virtual field)
+ GetNibble2() uint8
+ // GetNibble3 returns Nibble3 (virtual field)
+ GetNibble3() uint8
+ // GetNibble4 returns Nibble4 (virtual field)
+ GetNibble4() uint8
+ // GetIsAbsent returns IsAbsent (virtual field)
+ GetIsAbsent() bool
+ // GetIsCorruptedByNoise returns IsCorruptedByNoise (virtual field)
+ GetIsCorruptedByNoise() bool
+ // GetIsCorruptedByNoiseOrLevelsDiffer returns IsCorruptedByNoiseOrLevelsDiffer (virtual field)
+ GetIsCorruptedByNoiseOrLevelsDiffer() bool
+ // GetIsCorrupted returns IsCorrupted (virtual field)
+ GetIsCorrupted() bool
+}
+
+// LevelInformationExactly can be used when we want exactly this type and not a type which fulfills LevelInformation.
+// This is useful for switch cases.
+type LevelInformationExactly interface {
+ LevelInformation
+ isLevelInformation() bool
+}
+
+// _LevelInformation is the data-structure of this message
+type _LevelInformation struct {
+ _LevelInformationChildRequirements
+ Raw uint16
+}
+
+type _LevelInformationChildRequirements interface {
+ utils.Serializable
+ GetLengthInBits() uint16
+ GetLengthInBitsConditional(lastItem bool) uint16
+}
+
+type LevelInformationParent interface {
+ SerializeParent(writeBuffer utils.WriteBuffer, child LevelInformation, serializeChildFunction func() error) error
+ GetTypeName() string
+}
+
+type LevelInformationChild interface {
+ utils.Serializable
+ InitializeParent(parent LevelInformation, raw uint16)
+ GetParent() *LevelInformation
+
+ GetTypeName() string
+ LevelInformation
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_LevelInformation) GetRaw() uint16 {
+ return m.Raw
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for virtual fields.
+///////////////////////
+
+func (m *_LevelInformation) GetNibble1() uint8 {
+ return uint8(uint8(m.GetRaw()&0xF000) >> uint8(12))
+}
+
+func (m *_LevelInformation) GetNibble2() uint8 {
+ return uint8(uint8(m.GetRaw()&0x0F00) >> uint8(8))
+}
+
+func (m *_LevelInformation) GetNibble3() uint8 {
+ return uint8(uint8(m.GetRaw()&0x00F0) >> uint8(4))
+}
+
+func (m *_LevelInformation) GetNibble4() uint8 {
+ return uint8(uint8(m.GetRaw()&0x000F) >> uint8(0))
+}
+
+func (m *_LevelInformation) GetIsAbsent() bool {
+ return bool(bool(bool(bool(bool((m.GetNibble1()) == (0x0))) && bool(bool((m.GetNibble2()) == (0x0)))) && bool(bool((m.GetNibble3()) == (0x0)))) && bool(bool((m.GetNibble4()) == (0x0))))
+}
+
+func (m *_LevelInformation) GetIsCorruptedByNoise() bool {
+ return bool(bool(!(m.GetIsAbsent())) && bool(bool(bool(bool(bool(bool(bool(bool(bool(bool((m.GetNibble1()) < (0x5)))) || bool(bool(bool((m.GetNibble1()) == (0x8))))) || bool(bool(bool((m.GetNibble1()) == (0xC)))))) || bool(bool(bool(bool(bool(bool((m.GetNibble2()) < (0x5)))) || bool(bool(bool((m.GetNibble2()) == (0x8))))) || bool(bool(bool((m.GetNibble2()) == (0xC))))))) || bool(bool(bool(bool(bool(bool((m.GetNibble3()) < (0x5)))) || bool(bool(bool((m.GetNibble3()) == (0x8))))) || bool( [...]
+}
+
+func (m *_LevelInformation) GetIsCorruptedByNoiseOrLevelsDiffer() bool {
+ return bool(bool(!(m.GetIsAbsent())) && bool(bool(bool(bool(bool(bool(bool(bool(bool(bool((m.GetNibble1()) == (0x7)))) || bool(bool(bool((m.GetNibble1()) == (0xB))))) || bool(bool(bool((m.GetNibble1()) > (0xC)))))) || bool(bool(bool(bool(bool(bool((m.GetNibble2()) == (0x7)))) || bool(bool(bool((m.GetNibble2()) == (0xB))))) || bool(bool(bool((m.GetNibble2()) > (0xC))))))) || bool(bool(bool(bool(bool(bool((m.GetNibble3()) == (0x7)))) || bool(bool(bool((m.GetNibble3()) == (0xB))))) || bool [...]
+}
+
+func (m *_LevelInformation) GetIsCorrupted() bool {
+ return bool(bool(m.GetIsCorruptedByNoise()) || bool(m.GetIsCorruptedByNoiseOrLevelsDiffer()))
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewLevelInformation factory function for _LevelInformation
+func NewLevelInformation(raw uint16) *_LevelInformation {
+ return &_LevelInformation{Raw: raw}
+}
+
+// Deprecated: use the interface for direct cast
+func CastLevelInformation(structType interface{}) LevelInformation {
+ if casted, ok := structType.(LevelInformation); ok {
+ return casted
+ }
+ if casted, ok := structType.(*LevelInformation); ok {
+ return *casted
+ }
+ return nil
+}
+
+func (m *_LevelInformation) GetTypeName() string {
+ return "LevelInformation"
+}
+
+func (m *_LevelInformation) GetParentLengthInBits() uint16 {
+ lengthInBits := uint16(0)
+
+ // A virtual field doesn't have any in- or output.
+
+ // A virtual field doesn't have any in- or output.
+
+ // A virtual field doesn't have any in- or output.
+
+ // A virtual field doesn't have any in- or output.
+
+ // A virtual field doesn't have any in- or output.
+
+ // A virtual field doesn't have any in- or output.
+
+ // A virtual field doesn't have any in- or output.
+
+ // A virtual field doesn't have any in- or output.
+
+ return lengthInBits
+}
+
+func (m *_LevelInformation) GetLengthInBytes() uint16 {
+ return m.GetLengthInBits() / 8
+}
+
+func LevelInformationParse(readBuffer utils.ReadBuffer) (LevelInformation, error) {
+ positionAware := readBuffer
+ _ = positionAware
+ if pullErr := readBuffer.PullContext("LevelInformation"); pullErr != nil {
+ return nil, errors.Wrap(pullErr, "Error pulling for LevelInformation")
+ }
+ currentPos := positionAware.GetPos()
+ _ = currentPos
+
+ // Peek Field (raw)
+ currentPos = positionAware.GetPos()
+ raw, _err := readBuffer.ReadUint16("raw", 16)
+ if _err != nil {
+ return nil, errors.Wrap(_err, "Error parsing 'raw' field of LevelInformation")
+ }
+
+ readBuffer.Reset(currentPos)
+
+ // Virtual field
+ _nibble1 := uint8(raw&0xF000) >> uint8(12)
+ nibble1 := uint8(_nibble1)
+ _ = nibble1
+
+ // Virtual field
+ _nibble2 := uint8(raw&0x0F00) >> uint8(8)
+ nibble2 := uint8(_nibble2)
+ _ = nibble2
+
+ // Virtual field
+ _nibble3 := uint8(raw&0x00F0) >> uint8(4)
+ nibble3 := uint8(_nibble3)
+ _ = nibble3
+
+ // Virtual field
+ _nibble4 := uint8(raw&0x000F) >> uint8(0)
+ nibble4 := uint8(_nibble4)
+ _ = nibble4
+
+ // Virtual field
+ _isAbsent := bool(bool(bool(bool((nibble1) == (0x0))) && bool(bool((nibble2) == (0x0)))) && bool(bool((nibble3) == (0x0)))) && bool(bool((nibble4) == (0x0)))
+ isAbsent := bool(_isAbsent)
+ _ = isAbsent
+
+ // Virtual field
+ _isCorruptedByNoise := bool(!(isAbsent)) && bool(bool(bool(bool(bool(bool(bool(bool(bool(bool((nibble1) < (0x5)))) || bool(bool(bool((nibble1) == (0x8))))) || bool(bool(bool((nibble1) == (0xC)))))) || bool(bool(bool(bool(bool(bool((nibble2) < (0x5)))) || bool(bool(bool((nibble2) == (0x8))))) || bool(bool(bool((nibble2) == (0xC))))))) || bool(bool(bool(bool(bool(bool((nibble3) < (0x5)))) || bool(bool(bool((nibble3) == (0x8))))) || bool(bool(bool((nibble3) == (0xC))))))) || bool(bool(bool [...]
+ isCorruptedByNoise := bool(_isCorruptedByNoise)
+ _ = isCorruptedByNoise
+
+ // Virtual field
+ _isCorruptedByNoiseOrLevelsDiffer := bool(!(isAbsent)) && bool(bool(bool(bool(bool(bool(bool(bool(bool(bool((nibble1) == (0x7)))) || bool(bool(bool((nibble1) == (0xB))))) || bool(bool(bool((nibble1) > (0xC)))))) || bool(bool(bool(bool(bool(bool((nibble2) == (0x7)))) || bool(bool(bool((nibble2) == (0xB))))) || bool(bool(bool((nibble2) > (0xC))))))) || bool(bool(bool(bool(bool(bool((nibble3) == (0x7)))) || bool(bool(bool((nibble3) == (0xB))))) || bool(bool(bool((nibble3) > (0xC))))))) || [...]
+ isCorruptedByNoiseOrLevelsDiffer := bool(_isCorruptedByNoiseOrLevelsDiffer)
+ _ = isCorruptedByNoiseOrLevelsDiffer
+
+ // Virtual field
+ _isCorrupted := bool(isCorruptedByNoise) || bool(isCorruptedByNoiseOrLevelsDiffer)
+ isCorrupted := bool(_isCorrupted)
+ _ = isCorrupted
+
+ // Switch Field (Depending on the discriminator values, passes the instantiation to a sub-type)
+ type LevelInformationChildSerializeRequirement interface {
+ LevelInformation
+ InitializeParent(LevelInformation, uint16)
+ GetParent() LevelInformation
+ }
+ var _childTemp interface{}
+ var _child LevelInformationChildSerializeRequirement
+ var typeSwitchError error
+ switch {
+ case isAbsent == bool(true): // LevelInformationAbsent
+ _childTemp, typeSwitchError = LevelInformationAbsentParse(readBuffer)
+ case 0 == 0 && isCorrupted == bool(true): // LevelInformationCorrupted
+ _childTemp, typeSwitchError = LevelInformationCorruptedParse(readBuffer)
+ case 0 == 0: // LevelInformationNormal
+ _childTemp, typeSwitchError = LevelInformationNormalParse(readBuffer)
+ default:
+ typeSwitchError = errors.Errorf("Unmapped type for parameters [isAbsent=%v, isCorrupted=%v]", isAbsent, isCorrupted)
+ }
+ if typeSwitchError != nil {
+ return nil, errors.Wrap(typeSwitchError, "Error parsing sub-type for type-switch of LevelInformation")
+ }
+ _child = _childTemp.(LevelInformationChildSerializeRequirement)
+
+ if closeErr := readBuffer.CloseContext("LevelInformation"); closeErr != nil {
+ return nil, errors.Wrap(closeErr, "Error closing for LevelInformation")
+ }
+
+ // Finish initializing
+ _child.InitializeParent(_child, raw)
+ return _child, nil
+}
+
+func (pm *_LevelInformation) SerializeParent(writeBuffer utils.WriteBuffer, child LevelInformation, serializeChildFunction func() error) error {
+ // We redirect all calls through client as some methods are only implemented there
+ m := child
+ _ = m
+ positionAware := writeBuffer
+ _ = positionAware
+ if pushErr := writeBuffer.PushContext("LevelInformation"); pushErr != nil {
+ return errors.Wrap(pushErr, "Error pushing for LevelInformation")
+ }
+ // Virtual field
+ if _nibble1Err := writeBuffer.WriteVirtual("nibble1", m.GetNibble1()); _nibble1Err != nil {
+ return errors.Wrap(_nibble1Err, "Error serializing 'nibble1' field")
+ }
+ // Virtual field
+ if _nibble2Err := writeBuffer.WriteVirtual("nibble2", m.GetNibble2()); _nibble2Err != nil {
+ return errors.Wrap(_nibble2Err, "Error serializing 'nibble2' field")
+ }
+ // Virtual field
+ if _nibble3Err := writeBuffer.WriteVirtual("nibble3", m.GetNibble3()); _nibble3Err != nil {
+ return errors.Wrap(_nibble3Err, "Error serializing 'nibble3' field")
+ }
+ // Virtual field
+ if _nibble4Err := writeBuffer.WriteVirtual("nibble4", m.GetNibble4()); _nibble4Err != nil {
+ return errors.Wrap(_nibble4Err, "Error serializing 'nibble4' field")
+ }
+ // Virtual field
+ if _isAbsentErr := writeBuffer.WriteVirtual("isAbsent", m.GetIsAbsent()); _isAbsentErr != nil {
+ return errors.Wrap(_isAbsentErr, "Error serializing 'isAbsent' field")
+ }
+ // Virtual field
+ if _isCorruptedByNoiseErr := writeBuffer.WriteVirtual("isCorruptedByNoise", m.GetIsCorruptedByNoise()); _isCorruptedByNoiseErr != nil {
+ return errors.Wrap(_isCorruptedByNoiseErr, "Error serializing 'isCorruptedByNoise' field")
+ }
+ // Virtual field
+ if _isCorruptedByNoiseOrLevelsDifferErr := writeBuffer.WriteVirtual("isCorruptedByNoiseOrLevelsDiffer", m.GetIsCorruptedByNoiseOrLevelsDiffer()); _isCorruptedByNoiseOrLevelsDifferErr != nil {
+ return errors.Wrap(_isCorruptedByNoiseOrLevelsDifferErr, "Error serializing 'isCorruptedByNoiseOrLevelsDiffer' field")
+ }
+ // Virtual field
+ if _isCorruptedErr := writeBuffer.WriteVirtual("isCorrupted", m.GetIsCorrupted()); _isCorruptedErr != nil {
+ return errors.Wrap(_isCorruptedErr, "Error serializing 'isCorrupted' field")
+ }
+
+ // Switch field (Depending on the discriminator values, passes the serialization to a sub-type)
+ if _typeSwitchErr := serializeChildFunction(); _typeSwitchErr != nil {
+ return errors.Wrap(_typeSwitchErr, "Error serializing sub-type field")
+ }
+
+ if popErr := writeBuffer.PopContext("LevelInformation"); popErr != nil {
+ return errors.Wrap(popErr, "Error popping for LevelInformation")
+ }
+ return nil
+}
+
+func (m *_LevelInformation) isLevelInformation() bool {
+ return true
+}
+
+func (m *_LevelInformation) 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/plc4go/protocols/cbus/readwrite/model/LevelInformationAbsent.go b/plc4go/protocols/cbus/readwrite/model/LevelInformationAbsent.go
new file mode 100644
index 000000000..21f605429
--- /dev/null
+++ b/plc4go/protocols/cbus/readwrite/model/LevelInformationAbsent.go
@@ -0,0 +1,180 @@
+/*
+ * 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.
+
+// LevelInformationAbsent is the corresponding interface of LevelInformationAbsent
+type LevelInformationAbsent interface {
+ utils.LengthAware
+ utils.Serializable
+ LevelInformation
+}
+
+// LevelInformationAbsentExactly can be used when we want exactly this type and not a type which fulfills LevelInformationAbsent.
+// This is useful for switch cases.
+type LevelInformationAbsentExactly interface {
+ LevelInformationAbsent
+ isLevelInformationAbsent() bool
+}
+
+// _LevelInformationAbsent is the data-structure of this message
+type _LevelInformationAbsent struct {
+ *_LevelInformation
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_LevelInformationAbsent) InitializeParent(parent LevelInformation, raw uint16) {
+ m.Raw = raw
+}
+
+func (m *_LevelInformationAbsent) GetParent() LevelInformation {
+ return m._LevelInformation
+}
+
+// NewLevelInformationAbsent factory function for _LevelInformationAbsent
+func NewLevelInformationAbsent(raw uint16) *_LevelInformationAbsent {
+ _result := &_LevelInformationAbsent{
+ _LevelInformation: NewLevelInformation(raw),
+ }
+ _result._LevelInformation._LevelInformationChildRequirements = _result
+ return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastLevelInformationAbsent(structType interface{}) LevelInformationAbsent {
+ if casted, ok := structType.(LevelInformationAbsent); ok {
+ return casted
+ }
+ if casted, ok := structType.(*LevelInformationAbsent); ok {
+ return *casted
+ }
+ return nil
+}
+
+func (m *_LevelInformationAbsent) GetTypeName() string {
+ return "LevelInformationAbsent"
+}
+
+func (m *_LevelInformationAbsent) GetLengthInBits() uint16 {
+ return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_LevelInformationAbsent) GetLengthInBitsConditional(lastItem bool) uint16 {
+ lengthInBits := uint16(m.GetParentLengthInBits())
+
+ // Reserved Field (reserved)
+ lengthInBits += 16
+
+ return lengthInBits
+}
+
+func (m *_LevelInformationAbsent) GetLengthInBytes() uint16 {
+ return m.GetLengthInBits() / 8
+}
+
+func LevelInformationAbsentParse(readBuffer utils.ReadBuffer) (LevelInformationAbsent, error) {
+ positionAware := readBuffer
+ _ = positionAware
+ if pullErr := readBuffer.PullContext("LevelInformationAbsent"); pullErr != nil {
+ return nil, errors.Wrap(pullErr, "Error pulling for LevelInformationAbsent")
+ }
+ currentPos := positionAware.GetPos()
+ _ = currentPos
+
+ // Reserved Field (Compartmentalized so the "reserved" variable can't leak)
+ {
+ reserved, _err := readBuffer.ReadUint16("reserved", 16)
+ if _err != nil {
+ return nil, errors.Wrap(_err, "Error parsing 'reserved' field of LevelInformationAbsent")
+ }
+ if reserved != uint16(0x0000) {
+ log.Info().Fields(map[string]interface{}{
+ "expected value": uint16(0x0000),
+ "got value": reserved,
+ }).Msg("Got unexpected response for reserved field.")
+ }
+ }
+
+ if closeErr := readBuffer.CloseContext("LevelInformationAbsent"); closeErr != nil {
+ return nil, errors.Wrap(closeErr, "Error closing for LevelInformationAbsent")
+ }
+
+ // Create a partially initialized instance
+ _child := &_LevelInformationAbsent{
+ _LevelInformation: &_LevelInformation{},
+ }
+ _child._LevelInformation._LevelInformationChildRequirements = _child
+ return _child, nil
+}
+
+func (m *_LevelInformationAbsent) Serialize(writeBuffer utils.WriteBuffer) error {
+ positionAware := writeBuffer
+ _ = positionAware
+ ser := func() error {
+ if pushErr := writeBuffer.PushContext("LevelInformationAbsent"); pushErr != nil {
+ return errors.Wrap(pushErr, "Error pushing for LevelInformationAbsent")
+ }
+
+ // Reserved Field (reserved)
+ {
+ _err := writeBuffer.WriteUint16("reserved", 16, uint16(0x0000))
+ if _err != nil {
+ return errors.Wrap(_err, "Error serializing 'reserved' field")
+ }
+ }
+
+ if popErr := writeBuffer.PopContext("LevelInformationAbsent"); popErr != nil {
+ return errors.Wrap(popErr, "Error popping for LevelInformationAbsent")
+ }
+ return nil
+ }
+ return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *_LevelInformationAbsent) isLevelInformationAbsent() bool {
+ return true
+}
+
+func (m *_LevelInformationAbsent) 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/plc4go/protocols/cbus/readwrite/model/LevelInformationCorrupted.go b/plc4go/protocols/cbus/readwrite/model/LevelInformationCorrupted.go
new file mode 100644
index 000000000..032c02237
--- /dev/null
+++ b/plc4go/protocols/cbus/readwrite/model/LevelInformationCorrupted.go
@@ -0,0 +1,268 @@
+/*
+ * 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"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// LevelInformationCorrupted is the corresponding interface of LevelInformationCorrupted
+type LevelInformationCorrupted interface {
+ utils.LengthAware
+ utils.Serializable
+ LevelInformation
+ // GetCorruptedNibble1 returns CorruptedNibble1 (property field)
+ GetCorruptedNibble1() uint8
+ // GetCorruptedNibble2 returns CorruptedNibble2 (property field)
+ GetCorruptedNibble2() uint8
+ // GetCorruptedNibble3 returns CorruptedNibble3 (property field)
+ GetCorruptedNibble3() uint8
+ // GetCorruptedNibble4 returns CorruptedNibble4 (property field)
+ GetCorruptedNibble4() uint8
+}
+
+// LevelInformationCorruptedExactly can be used when we want exactly this type and not a type which fulfills LevelInformationCorrupted.
+// This is useful for switch cases.
+type LevelInformationCorruptedExactly interface {
+ LevelInformationCorrupted
+ isLevelInformationCorrupted() bool
+}
+
+// _LevelInformationCorrupted is the data-structure of this message
+type _LevelInformationCorrupted struct {
+ *_LevelInformation
+ CorruptedNibble1 uint8
+ CorruptedNibble2 uint8
+ CorruptedNibble3 uint8
+ CorruptedNibble4 uint8
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_LevelInformationCorrupted) InitializeParent(parent LevelInformation, raw uint16) {
+ m.Raw = raw
+}
+
+func (m *_LevelInformationCorrupted) GetParent() LevelInformation {
+ return m._LevelInformation
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_LevelInformationCorrupted) GetCorruptedNibble1() uint8 {
+ return m.CorruptedNibble1
+}
+
+func (m *_LevelInformationCorrupted) GetCorruptedNibble2() uint8 {
+ return m.CorruptedNibble2
+}
+
+func (m *_LevelInformationCorrupted) GetCorruptedNibble3() uint8 {
+ return m.CorruptedNibble3
+}
+
+func (m *_LevelInformationCorrupted) GetCorruptedNibble4() uint8 {
+ return m.CorruptedNibble4
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewLevelInformationCorrupted factory function for _LevelInformationCorrupted
+func NewLevelInformationCorrupted(corruptedNibble1 uint8, corruptedNibble2 uint8, corruptedNibble3 uint8, corruptedNibble4 uint8, raw uint16) *_LevelInformationCorrupted {
+ _result := &_LevelInformationCorrupted{
+ CorruptedNibble1: corruptedNibble1,
+ CorruptedNibble2: corruptedNibble2,
+ CorruptedNibble3: corruptedNibble3,
+ CorruptedNibble4: corruptedNibble4,
+ _LevelInformation: NewLevelInformation(raw),
+ }
+ _result._LevelInformation._LevelInformationChildRequirements = _result
+ return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastLevelInformationCorrupted(structType interface{}) LevelInformationCorrupted {
+ if casted, ok := structType.(LevelInformationCorrupted); ok {
+ return casted
+ }
+ if casted, ok := structType.(*LevelInformationCorrupted); ok {
+ return *casted
+ }
+ return nil
+}
+
+func (m *_LevelInformationCorrupted) GetTypeName() string {
+ return "LevelInformationCorrupted"
+}
+
+func (m *_LevelInformationCorrupted) GetLengthInBits() uint16 {
+ return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_LevelInformationCorrupted) GetLengthInBitsConditional(lastItem bool) uint16 {
+ lengthInBits := uint16(m.GetParentLengthInBits())
+
+ // Simple field (corruptedNibble1)
+ lengthInBits += 4
+
+ // Simple field (corruptedNibble2)
+ lengthInBits += 4
+
+ // Simple field (corruptedNibble3)
+ lengthInBits += 4
+
+ // Simple field (corruptedNibble4)
+ lengthInBits += 4
+
+ return lengthInBits
+}
+
+func (m *_LevelInformationCorrupted) GetLengthInBytes() uint16 {
+ return m.GetLengthInBits() / 8
+}
+
+func LevelInformationCorruptedParse(readBuffer utils.ReadBuffer) (LevelInformationCorrupted, error) {
+ positionAware := readBuffer
+ _ = positionAware
+ if pullErr := readBuffer.PullContext("LevelInformationCorrupted"); pullErr != nil {
+ return nil, errors.Wrap(pullErr, "Error pulling for LevelInformationCorrupted")
+ }
+ currentPos := positionAware.GetPos()
+ _ = currentPos
+
+ // Simple Field (corruptedNibble1)
+ _corruptedNibble1, _corruptedNibble1Err := readBuffer.ReadUint8("corruptedNibble1", 4)
+ if _corruptedNibble1Err != nil {
+ return nil, errors.Wrap(_corruptedNibble1Err, "Error parsing 'corruptedNibble1' field of LevelInformationCorrupted")
+ }
+ corruptedNibble1 := _corruptedNibble1
+
+ // Simple Field (corruptedNibble2)
+ _corruptedNibble2, _corruptedNibble2Err := readBuffer.ReadUint8("corruptedNibble2", 4)
+ if _corruptedNibble2Err != nil {
+ return nil, errors.Wrap(_corruptedNibble2Err, "Error parsing 'corruptedNibble2' field of LevelInformationCorrupted")
+ }
+ corruptedNibble2 := _corruptedNibble2
+
+ // Simple Field (corruptedNibble3)
+ _corruptedNibble3, _corruptedNibble3Err := readBuffer.ReadUint8("corruptedNibble3", 4)
+ if _corruptedNibble3Err != nil {
+ return nil, errors.Wrap(_corruptedNibble3Err, "Error parsing 'corruptedNibble3' field of LevelInformationCorrupted")
+ }
+ corruptedNibble3 := _corruptedNibble3
+
+ // Simple Field (corruptedNibble4)
+ _corruptedNibble4, _corruptedNibble4Err := readBuffer.ReadUint8("corruptedNibble4", 4)
+ if _corruptedNibble4Err != nil {
+ return nil, errors.Wrap(_corruptedNibble4Err, "Error parsing 'corruptedNibble4' field of LevelInformationCorrupted")
+ }
+ corruptedNibble4 := _corruptedNibble4
+
+ if closeErr := readBuffer.CloseContext("LevelInformationCorrupted"); closeErr != nil {
+ return nil, errors.Wrap(closeErr, "Error closing for LevelInformationCorrupted")
+ }
+
+ // Create a partially initialized instance
+ _child := &_LevelInformationCorrupted{
+ CorruptedNibble1: corruptedNibble1,
+ CorruptedNibble2: corruptedNibble2,
+ CorruptedNibble3: corruptedNibble3,
+ CorruptedNibble4: corruptedNibble4,
+ _LevelInformation: &_LevelInformation{},
+ }
+ _child._LevelInformation._LevelInformationChildRequirements = _child
+ return _child, nil
+}
+
+func (m *_LevelInformationCorrupted) Serialize(writeBuffer utils.WriteBuffer) error {
+ positionAware := writeBuffer
+ _ = positionAware
+ ser := func() error {
+ if pushErr := writeBuffer.PushContext("LevelInformationCorrupted"); pushErr != nil {
+ return errors.Wrap(pushErr, "Error pushing for LevelInformationCorrupted")
+ }
+
+ // Simple Field (corruptedNibble1)
+ corruptedNibble1 := uint8(m.GetCorruptedNibble1())
+ _corruptedNibble1Err := writeBuffer.WriteUint8("corruptedNibble1", 4, (corruptedNibble1))
+ if _corruptedNibble1Err != nil {
+ return errors.Wrap(_corruptedNibble1Err, "Error serializing 'corruptedNibble1' field")
+ }
+
+ // Simple Field (corruptedNibble2)
+ corruptedNibble2 := uint8(m.GetCorruptedNibble2())
+ _corruptedNibble2Err := writeBuffer.WriteUint8("corruptedNibble2", 4, (corruptedNibble2))
+ if _corruptedNibble2Err != nil {
+ return errors.Wrap(_corruptedNibble2Err, "Error serializing 'corruptedNibble2' field")
+ }
+
+ // Simple Field (corruptedNibble3)
+ corruptedNibble3 := uint8(m.GetCorruptedNibble3())
+ _corruptedNibble3Err := writeBuffer.WriteUint8("corruptedNibble3", 4, (corruptedNibble3))
+ if _corruptedNibble3Err != nil {
+ return errors.Wrap(_corruptedNibble3Err, "Error serializing 'corruptedNibble3' field")
+ }
+
+ // Simple Field (corruptedNibble4)
+ corruptedNibble4 := uint8(m.GetCorruptedNibble4())
+ _corruptedNibble4Err := writeBuffer.WriteUint8("corruptedNibble4", 4, (corruptedNibble4))
+ if _corruptedNibble4Err != nil {
+ return errors.Wrap(_corruptedNibble4Err, "Error serializing 'corruptedNibble4' field")
+ }
+
+ if popErr := writeBuffer.PopContext("LevelInformationCorrupted"); popErr != nil {
+ return errors.Wrap(popErr, "Error popping for LevelInformationCorrupted")
+ }
+ return nil
+ }
+ return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *_LevelInformationCorrupted) isLevelInformationCorrupted() bool {
+ return true
+}
+
+func (m *_LevelInformationCorrupted) 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/plc4go/protocols/cbus/readwrite/model/LevelInformationNibblePair.go b/plc4go/protocols/cbus/readwrite/model/LevelInformationNibblePair.go
new file mode 100644
index 000000000..c922ac549
--- /dev/null
+++ b/plc4go/protocols/cbus/readwrite/model/LevelInformationNibblePair.go
@@ -0,0 +1,323 @@
+/*
+ * 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.
+
+// LevelInformationNibblePair is an enum
+type LevelInformationNibblePair uint8
+
+type ILevelInformationNibblePair interface {
+ NibbleValue() uint8
+ Serialize(writeBuffer utils.WriteBuffer) error
+}
+
+const (
+ LevelInformationNibblePair_Value_F LevelInformationNibblePair = 0x55
+ LevelInformationNibblePair_Value_E LevelInformationNibblePair = 0x56
+ LevelInformationNibblePair_Value_D LevelInformationNibblePair = 0x59
+ LevelInformationNibblePair_Value_C LevelInformationNibblePair = 0x5A
+ LevelInformationNibblePair_Value_B LevelInformationNibblePair = 0x65
+ LevelInformationNibblePair_Value_A LevelInformationNibblePair = 0x66
+ LevelInformationNibblePair_Value_9 LevelInformationNibblePair = 0x69
+ LevelInformationNibblePair_Value_8 LevelInformationNibblePair = 0x6A
+ LevelInformationNibblePair_Value_7 LevelInformationNibblePair = 0x95
+ LevelInformationNibblePair_Value_6 LevelInformationNibblePair = 0x96
+ LevelInformationNibblePair_Value_5 LevelInformationNibblePair = 0x99
+ LevelInformationNibblePair_Value_4 LevelInformationNibblePair = 0x9A
+ LevelInformationNibblePair_Value_3 LevelInformationNibblePair = 0xA5
+ LevelInformationNibblePair_Value_2 LevelInformationNibblePair = 0xA6
+ LevelInformationNibblePair_Value_1 LevelInformationNibblePair = 0xA9
+ LevelInformationNibblePair_Value_0 LevelInformationNibblePair = 0xAA
+)
+
+var LevelInformationNibblePairValues []LevelInformationNibblePair
+
+func init() {
+ _ = errors.New
+ LevelInformationNibblePairValues = []LevelInformationNibblePair{
+ LevelInformationNibblePair_Value_F,
+ LevelInformationNibblePair_Value_E,
+ LevelInformationNibblePair_Value_D,
+ LevelInformationNibblePair_Value_C,
+ LevelInformationNibblePair_Value_B,
+ LevelInformationNibblePair_Value_A,
+ LevelInformationNibblePair_Value_9,
+ LevelInformationNibblePair_Value_8,
+ LevelInformationNibblePair_Value_7,
+ LevelInformationNibblePair_Value_6,
+ LevelInformationNibblePair_Value_5,
+ LevelInformationNibblePair_Value_4,
+ LevelInformationNibblePair_Value_3,
+ LevelInformationNibblePair_Value_2,
+ LevelInformationNibblePair_Value_1,
+ LevelInformationNibblePair_Value_0,
+ }
+}
+
+func (e LevelInformationNibblePair) NibbleValue() uint8 {
+ switch e {
+ case 0x55:
+ { /* '0x55' */
+ return 0xF
+ }
+ case 0x56:
+ { /* '0x56' */
+ return 0xE
+ }
+ case 0x59:
+ { /* '0x59' */
+ return 0xD
+ }
+ case 0x5A:
+ { /* '0x5A' */
+ return 0xC
+ }
+ case 0x65:
+ { /* '0x65' */
+ return 0xB
+ }
+ case 0x66:
+ { /* '0x66' */
+ return 0xA
+ }
+ case 0x69:
+ { /* '0x69' */
+ return 0x9
+ }
+ case 0x6A:
+ { /* '0x6A' */
+ return 0x8
+ }
+ case 0x95:
+ { /* '0x95' */
+ return 0x7
+ }
+ case 0x96:
+ { /* '0x96' */
+ return 0x6
+ }
+ case 0x99:
+ { /* '0x99' */
+ return 0x5
+ }
+ case 0x9A:
+ { /* '0x9A' */
+ return 0x4
+ }
+ case 0xA5:
+ { /* '0xA5' */
+ return 0x3
+ }
+ case 0xA6:
+ { /* '0xA6' */
+ return 0x2
+ }
+ case 0xA9:
+ { /* '0xA9' */
+ return 0x1
+ }
+ case 0xAA:
+ { /* '0xAA' */
+ return 0x0
+ }
+ default:
+ {
+ return 0
+ }
+ }
+}
+
+func LevelInformationNibblePairFirstEnumForFieldNibbleValue(value uint8) (LevelInformationNibblePair, error) {
+ for _, sizeValue := range LevelInformationNibblePairValues {
+ if sizeValue.NibbleValue() == value {
+ return sizeValue, nil
+ }
+ }
+ return 0, errors.Errorf("enum for %v describing NibbleValue not found", value)
+}
+func LevelInformationNibblePairByValue(value uint8) (enum LevelInformationNibblePair, ok bool) {
+ switch value {
+ case 0x55:
+ return LevelInformationNibblePair_Value_F, true
+ case 0x56:
+ return LevelInformationNibblePair_Value_E, true
+ case 0x59:
+ return LevelInformationNibblePair_Value_D, true
+ case 0x5A:
+ return LevelInformationNibblePair_Value_C, true
+ case 0x65:
+ return LevelInformationNibblePair_Value_B, true
+ case 0x66:
+ return LevelInformationNibblePair_Value_A, true
+ case 0x69:
+ return LevelInformationNibblePair_Value_9, true
+ case 0x6A:
+ return LevelInformationNibblePair_Value_8, true
+ case 0x95:
+ return LevelInformationNibblePair_Value_7, true
+ case 0x96:
+ return LevelInformationNibblePair_Value_6, true
+ case 0x99:
+ return LevelInformationNibblePair_Value_5, true
+ case 0x9A:
+ return LevelInformationNibblePair_Value_4, true
+ case 0xA5:
+ return LevelInformationNibblePair_Value_3, true
+ case 0xA6:
+ return LevelInformationNibblePair_Value_2, true
+ case 0xA9:
+ return LevelInformationNibblePair_Value_1, true
+ case 0xAA:
+ return LevelInformationNibblePair_Value_0, true
+ }
+ return 0, false
+}
+
+func LevelInformationNibblePairByName(value string) (enum LevelInformationNibblePair, ok bool) {
+ switch value {
+ case "Value_F":
+ return LevelInformationNibblePair_Value_F, true
+ case "Value_E":
+ return LevelInformationNibblePair_Value_E, true
+ case "Value_D":
+ return LevelInformationNibblePair_Value_D, true
+ case "Value_C":
+ return LevelInformationNibblePair_Value_C, true
+ case "Value_B":
+ return LevelInformationNibblePair_Value_B, true
+ case "Value_A":
+ return LevelInformationNibblePair_Value_A, true
+ case "Value_9":
+ return LevelInformationNibblePair_Value_9, true
+ case "Value_8":
+ return LevelInformationNibblePair_Value_8, true
+ case "Value_7":
+ return LevelInformationNibblePair_Value_7, true
+ case "Value_6":
+ return LevelInformationNibblePair_Value_6, true
+ case "Value_5":
+ return LevelInformationNibblePair_Value_5, true
+ case "Value_4":
+ return LevelInformationNibblePair_Value_4, true
+ case "Value_3":
+ return LevelInformationNibblePair_Value_3, true
+ case "Value_2":
+ return LevelInformationNibblePair_Value_2, true
+ case "Value_1":
+ return LevelInformationNibblePair_Value_1, true
+ case "Value_0":
+ return LevelInformationNibblePair_Value_0, true
+ }
+ return 0, false
+}
+
+func LevelInformationNibblePairKnows(value uint8) bool {
+ for _, typeValue := range LevelInformationNibblePairValues {
+ if uint8(typeValue) == value {
+ return true
+ }
+ }
+ return false
+}
+
+func CastLevelInformationNibblePair(structType interface{}) LevelInformationNibblePair {
+ castFunc := func(typ interface{}) LevelInformationNibblePair {
+ if sLevelInformationNibblePair, ok := typ.(LevelInformationNibblePair); ok {
+ return sLevelInformationNibblePair
+ }
+ return 0
+ }
+ return castFunc(structType)
+}
+
+func (m LevelInformationNibblePair) GetLengthInBits() uint16 {
+ return 8
+}
+
+func (m LevelInformationNibblePair) GetLengthInBytes() uint16 {
+ return m.GetLengthInBits() / 8
+}
+
+func LevelInformationNibblePairParse(readBuffer utils.ReadBuffer) (LevelInformationNibblePair, error) {
+ val, err := readBuffer.ReadUint8("LevelInformationNibblePair", 8)
+ if err != nil {
+ return 0, errors.Wrap(err, "error reading LevelInformationNibblePair")
+ }
+ if enum, ok := LevelInformationNibblePairByValue(val); !ok {
+ log.Debug().Msgf("no value %x found for RequestType", val)
+ return LevelInformationNibblePair(val), nil
+ } else {
+ return enum, nil
+ }
+}
+
+func (e LevelInformationNibblePair) Serialize(writeBuffer utils.WriteBuffer) error {
+ return writeBuffer.WriteUint8("LevelInformationNibblePair", 8, uint8(e), utils.WithAdditionalStringRepresentation(e.PLC4XEnumName()))
+}
+
+// PLC4XEnumName returns the name that is used in code to identify this enum
+func (e LevelInformationNibblePair) PLC4XEnumName() string {
+ switch e {
+ case LevelInformationNibblePair_Value_F:
+ return "Value_F"
+ case LevelInformationNibblePair_Value_E:
+ return "Value_E"
+ case LevelInformationNibblePair_Value_D:
+ return "Value_D"
+ case LevelInformationNibblePair_Value_C:
+ return "Value_C"
+ case LevelInformationNibblePair_Value_B:
+ return "Value_B"
+ case LevelInformationNibblePair_Value_A:
+ return "Value_A"
+ case LevelInformationNibblePair_Value_9:
+ return "Value_9"
+ case LevelInformationNibblePair_Value_8:
+ return "Value_8"
+ case LevelInformationNibblePair_Value_7:
+ return "Value_7"
+ case LevelInformationNibblePair_Value_6:
+ return "Value_6"
+ case LevelInformationNibblePair_Value_5:
+ return "Value_5"
+ case LevelInformationNibblePair_Value_4:
+ return "Value_4"
+ case LevelInformationNibblePair_Value_3:
+ return "Value_3"
+ case LevelInformationNibblePair_Value_2:
+ return "Value_2"
+ case LevelInformationNibblePair_Value_1:
+ return "Value_1"
+ case LevelInformationNibblePair_Value_0:
+ return "Value_0"
+ }
+ return ""
+}
+
+func (e LevelInformationNibblePair) String() string {
+ return e.PLC4XEnumName()
+}
diff --git a/plc4go/protocols/cbus/readwrite/model/LevelInformationNormal.go b/plc4go/protocols/cbus/readwrite/model/LevelInformationNormal.go
new file mode 100644
index 000000000..491f8abdb
--- /dev/null
+++ b/plc4go/protocols/cbus/readwrite/model/LevelInformationNormal.go
@@ -0,0 +1,264 @@
+/*
+ * 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"
+)
+
+// Code generated by code-generation. DO NOT EDIT.
+
+// LevelInformationNormal is the corresponding interface of LevelInformationNormal
+type LevelInformationNormal interface {
+ utils.LengthAware
+ utils.Serializable
+ LevelInformation
+ // GetPair1 returns Pair1 (property field)
+ GetPair1() LevelInformationNibblePair
+ // GetPair2 returns Pair2 (property field)
+ GetPair2() LevelInformationNibblePair
+ // GetActualLevel returns ActualLevel (virtual field)
+ GetActualLevel() uint8
+}
+
+// LevelInformationNormalExactly can be used when we want exactly this type and not a type which fulfills LevelInformationNormal.
+// This is useful for switch cases.
+type LevelInformationNormalExactly interface {
+ LevelInformationNormal
+ isLevelInformationNormal() bool
+}
+
+// _LevelInformationNormal is the data-structure of this message
+type _LevelInformationNormal struct {
+ *_LevelInformation
+ Pair1 LevelInformationNibblePair
+ Pair2 LevelInformationNibblePair
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for discriminator values.
+///////////////////////
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+func (m *_LevelInformationNormal) InitializeParent(parent LevelInformation, raw uint16) {
+ m.Raw = raw
+}
+
+func (m *_LevelInformationNormal) GetParent() LevelInformation {
+ return m._LevelInformation
+}
+
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for property fields.
+///////////////////////
+
+func (m *_LevelInformationNormal) GetPair1() LevelInformationNibblePair {
+ return m.Pair1
+}
+
+func (m *_LevelInformationNormal) GetPair2() LevelInformationNibblePair {
+ return m.Pair2
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+/////////////////////// Accessors for virtual fields.
+///////////////////////
+
+func (m *_LevelInformationNormal) GetActualLevel() uint8 {
+ return uint8(m.GetPair2().NibbleValue()<<uint8(4) | m.GetPair1().NibbleValue())
+}
+
+///////////////////////
+///////////////////////
+///////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////
+
+// NewLevelInformationNormal factory function for _LevelInformationNormal
+func NewLevelInformationNormal(pair1 LevelInformationNibblePair, pair2 LevelInformationNibblePair, raw uint16) *_LevelInformationNormal {
+ _result := &_LevelInformationNormal{
+ Pair1: pair1,
+ Pair2: pair2,
+ _LevelInformation: NewLevelInformation(raw),
+ }
+ _result._LevelInformation._LevelInformationChildRequirements = _result
+ return _result
+}
+
+// Deprecated: use the interface for direct cast
+func CastLevelInformationNormal(structType interface{}) LevelInformationNormal {
+ if casted, ok := structType.(LevelInformationNormal); ok {
+ return casted
+ }
+ if casted, ok := structType.(*LevelInformationNormal); ok {
+ return *casted
+ }
+ return nil
+}
+
+func (m *_LevelInformationNormal) GetTypeName() string {
+ return "LevelInformationNormal"
+}
+
+func (m *_LevelInformationNormal) GetLengthInBits() uint16 {
+ return m.GetLengthInBitsConditional(false)
+}
+
+func (m *_LevelInformationNormal) GetLengthInBitsConditional(lastItem bool) uint16 {
+ lengthInBits := uint16(m.GetParentLengthInBits())
+
+ // Simple field (pair1)
+ lengthInBits += 8
+
+ // Simple field (pair2)
+ lengthInBits += 8
+
+ // A virtual field doesn't have any in- or output.
+
+ return lengthInBits
+}
+
+func (m *_LevelInformationNormal) GetLengthInBytes() uint16 {
+ return m.GetLengthInBits() / 8
+}
+
+func LevelInformationNormalParse(readBuffer utils.ReadBuffer) (LevelInformationNormal, error) {
+ positionAware := readBuffer
+ _ = positionAware
+ if pullErr := readBuffer.PullContext("LevelInformationNormal"); pullErr != nil {
+ return nil, errors.Wrap(pullErr, "Error pulling for LevelInformationNormal")
+ }
+ currentPos := positionAware.GetPos()
+ _ = currentPos
+
+ // Simple Field (pair1)
+ if pullErr := readBuffer.PullContext("pair1"); pullErr != nil {
+ return nil, errors.Wrap(pullErr, "Error pulling for pair1")
+ }
+ _pair1, _pair1Err := LevelInformationNibblePairParse(readBuffer)
+ if _pair1Err != nil {
+ return nil, errors.Wrap(_pair1Err, "Error parsing 'pair1' field of LevelInformationNormal")
+ }
+ pair1 := _pair1
+ if closeErr := readBuffer.CloseContext("pair1"); closeErr != nil {
+ return nil, errors.Wrap(closeErr, "Error closing for pair1")
+ }
+
+ // Simple Field (pair2)
+ if pullErr := readBuffer.PullContext("pair2"); pullErr != nil {
+ return nil, errors.Wrap(pullErr, "Error pulling for pair2")
+ }
+ _pair2, _pair2Err := LevelInformationNibblePairParse(readBuffer)
+ if _pair2Err != nil {
+ return nil, errors.Wrap(_pair2Err, "Error parsing 'pair2' field of LevelInformationNormal")
+ }
+ pair2 := _pair2
+ if closeErr := readBuffer.CloseContext("pair2"); closeErr != nil {
+ return nil, errors.Wrap(closeErr, "Error closing for pair2")
+ }
+
+ // Virtual field
+ _actualLevel := pair2.NibbleValue()<<uint8(4) | pair1.NibbleValue()
+ actualLevel := uint8(_actualLevel)
+ _ = actualLevel
+
+ if closeErr := readBuffer.CloseContext("LevelInformationNormal"); closeErr != nil {
+ return nil, errors.Wrap(closeErr, "Error closing for LevelInformationNormal")
+ }
+
+ // Create a partially initialized instance
+ _child := &_LevelInformationNormal{
+ Pair1: pair1,
+ Pair2: pair2,
+ _LevelInformation: &_LevelInformation{},
+ }
+ _child._LevelInformation._LevelInformationChildRequirements = _child
+ return _child, nil
+}
+
+func (m *_LevelInformationNormal) Serialize(writeBuffer utils.WriteBuffer) error {
+ positionAware := writeBuffer
+ _ = positionAware
+ ser := func() error {
+ if pushErr := writeBuffer.PushContext("LevelInformationNormal"); pushErr != nil {
+ return errors.Wrap(pushErr, "Error pushing for LevelInformationNormal")
+ }
+
+ // Simple Field (pair1)
+ if pushErr := writeBuffer.PushContext("pair1"); pushErr != nil {
+ return errors.Wrap(pushErr, "Error pushing for pair1")
+ }
+ _pair1Err := writeBuffer.WriteSerializable(m.GetPair1())
+ if popErr := writeBuffer.PopContext("pair1"); popErr != nil {
+ return errors.Wrap(popErr, "Error popping for pair1")
+ }
+ if _pair1Err != nil {
+ return errors.Wrap(_pair1Err, "Error serializing 'pair1' field")
+ }
+
+ // Simple Field (pair2)
+ if pushErr := writeBuffer.PushContext("pair2"); pushErr != nil {
+ return errors.Wrap(pushErr, "Error pushing for pair2")
+ }
+ _pair2Err := writeBuffer.WriteSerializable(m.GetPair2())
+ if popErr := writeBuffer.PopContext("pair2"); popErr != nil {
+ return errors.Wrap(popErr, "Error popping for pair2")
+ }
+ if _pair2Err != nil {
+ return errors.Wrap(_pair2Err, "Error serializing 'pair2' field")
+ }
+ // Virtual field
+ if _actualLevelErr := writeBuffer.WriteVirtual("actualLevel", m.GetActualLevel()); _actualLevelErr != nil {
+ return errors.Wrap(_actualLevelErr, "Error serializing 'actualLevel' field")
+ }
+
+ if popErr := writeBuffer.PopContext("LevelInformationNormal"); popErr != nil {
+ return errors.Wrap(popErr, "Error popping for LevelInformationNormal")
+ }
+ return nil
+ }
+ return m.SerializeParent(writeBuffer, m, ser)
+}
+
+func (m *_LevelInformationNormal) isLevelInformationNormal() bool {
+ return true
+}
+
+func (m *_LevelInformationNormal) 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/ReferenceTest.java b/plc4j/drivers/c-bus/src/test/java/org/apache/plc4x/java/cbus/ReferenceTest.java
index 2c285be48..f05ce16a5 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
@@ -387,7 +387,7 @@ public class ReferenceTest {
// 7.4
@Test
void ExtendedFormatStatusReply1() throws Exception {
- byte[] bytes = "F9073800AAAA000095990000000005555000000000005555555548\r\n".getBytes(StandardCharsets.UTF_8);
+ byte[] bytes = "F9073800AAAA000095990000000055550000000000005555555548\r\n".getBytes(StandardCharsets.UTF_8);
ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
requestContext = new RequestContext(false, true, false);
cBusOptions = new CBusOptions(false, false, false, true, false, false, false, false, true);
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 a8d48cd66..da627a0b1 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
@@ -1555,10 +1555,16 @@
[simple ApplicationIdContainer
application ]
[simple uint 8 blockStart ]
+ [virtual uint 5 numberOfStatusBytes '(coding == StatusCoding.BINARY_BY_THIS_SERIAL_INTERFACE || coding == StatusCoding.BINARY_BY_ELSEWHERE)?(statusHeader.numberOfCharacterPairs - 3):(0)']
+ [virtual uint 5 numberOfLevelInformation '(coding == StatusCoding.LEVEL_BY_THIS_SERIAL_INTERFACE || coding == StatusCoding.LEVEL_BY_ELSEWHERE)?((statusHeader.numberOfCharacterPairs - 3) / 2):(0)']
[array StatusByte
statusBytes
- count
- 'statusHeader.numberOfCharacterPairs - 3' ]
+ count
+ 'numberOfStatusBytes' ]
+ [array LevelInformation
+ levelInformation
+ count
+ 'numberOfLevelInformation' ]
]
[type ExtendedStatusHeader
@@ -1580,6 +1586,53 @@
[simple GAVState gav0 ]
]
+[type LevelInformation
+ [peek uint 16 raw ]
+ [virtual uint 4 nibble1 '(raw & 0xF000) >> 12' ]
+ [virtual uint 4 nibble2 '(raw & 0x0F00) >> 8' ]
+ [virtual uint 4 nibble3 '(raw & 0x00F0) >> 4' ]
+ [virtual uint 4 nibble4 '(raw & 0x000F) >> 0' ]
+ [virtual bit isAbsent 'nibble1 == 0x0 && nibble2 == 0x0 && nibble3 == 0x0 && nibble4 == 0x0']
+ [virtual bit isCorruptedByNoise '!isAbsent && (((nibble1 < 0x5) || (nibble1 == 0x8) || (nibble1 == 0xC)) || ((nibble2 < 0x5) || (nibble2 == 0x8) || (nibble2 == 0xC)) || ((nibble3 < 0x5) || (nibble3 == 0x8) || (nibble3 == 0xC)) || ((nibble4 < 0x5) || (nibble4 == 0x8) || (nibble4 == 0xC)))']
+ [virtual bit isCorruptedByNoiseOrLevelsDiffer '!isAbsent && (((nibble1 == 0x7) || (nibble1 == 0xB) || (nibble1 > 0xC)) || ((nibble2 == 0x7) || (nibble2 == 0xB) || (nibble2 > 0xC)) || ((nibble3 == 0x7) || (nibble3 == 0xB) || (nibble3 > 0xC)) || ((nibble4 == 0x7) || (nibble4 == 0xB) || (nibble4 > 0xC)))']
+ [virtual bit isCorrupted 'isCorruptedByNoise || isCorruptedByNoiseOrLevelsDiffer']
+ [typeSwitch isAbsent, isCorrupted
+ ['true' *Absent
+ [reserved uint 16 '0x0000' ]
+ ]
+ [*, 'true' *Corrupted
+ [simple uint 4 corruptedNibble1]
+ [simple uint 4 corruptedNibble2]
+ [simple uint 4 corruptedNibble3]
+ [simple uint 4 corruptedNibble4]
+ ]
+ [* *Normal
+ [simple LevelInformationNibblePair pair1 ]
+ [simple LevelInformationNibblePair pair2 ]
+ [virtual uint 8 actualLevel 'pair2.nibbleValue << 4 | pair1.nibbleValue']
+ ]
+ ]
+]
+
+[enum uint 8 LevelInformationNibblePair(uint 4 nibbleValue)
+ ['0x55' Value_F ['0xF']]
+ ['0x56' Value_E ['0xE']]
+ ['0x59' Value_D ['0xD']]
+ ['0x5A' Value_C ['0xC']]
+ ['0x65' Value_B ['0xB']]
+ ['0x66' Value_A ['0xA']]
+ ['0x69' Value_9 ['0x9']]
+ ['0x6A' Value_8 ['0x8']]
+ ['0x95' Value_7 ['0x7']]
+ ['0x96' Value_6 ['0x6']]
+ ['0x99' Value_5 ['0x5']]
+ ['0x9A' Value_4 ['0x4']]
+ ['0xA5' Value_3 ['0x3']]
+ ['0xA6' Value_2 ['0x2']]
+ ['0xA9' Value_1 ['0x1']]
+ ['0xAA' Value_0 ['0x0']]
+]
+
[enum uint 2 GAVState
['0' DOES_NOT_EXIST ]
['1' ON ]
diff --git a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/cbus/protocol/CBusServerAdapter.java b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/cbus/protocol/CBusServerAdapter.java
index 48a5f6d46..199dc3ce2 100644
--- a/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/cbus/protocol/CBusServerAdapter.java
+++ b/sandbox/plc-simulator/src/main/java/org/apache/plc4x/simulator/server/cbus/protocol/CBusServerAdapter.java
@@ -108,12 +108,12 @@ public class CBusServerAdapter extends ChannelInboundHandlerAdapter {
}
if (statusRequest instanceof StatusRequestLevel) {
StatusRequestLevel statusRequestLevel = (StatusRequestLevel) statusRequest;
- ExtendedStatusHeader statusHeader = new ExtendedStatusHeader((short) (3 + 1)); // 2 we have always + 1 as we got one status byte
+ ExtendedStatusHeader statusHeader = new ExtendedStatusHeader((short) (3 + 2)); // 3 we have always (coding is extra opposed to the standard) + 2 as we got one level information
StatusCoding coding = StatusCoding.LEVEL_BY_THIS_SERIAL_INTERFACE;
// TODO: map actuall values from simulator
byte blockStart = statusRequestLevel.getStartingGroupAddressLabel();
- List<StatusByte> statusBytes = List.of(new StatusByte(GAVState.ON, GAVState.ERROR, GAVState.OFF, GAVState.DOES_NOT_EXIST));
- ExtendedFormatStatusReply extendedFormatStatusReply = new ExtendedFormatStatusReply(statusHeader, coding, statusRequestLevel.getApplication(), blockStart, statusBytes);
+ List<LevelInformation> levelInformations = List.of(new LevelInformationNormal(0x5555, LevelInformationNibblePair.Value_F, LevelInformationNibblePair.Value_F));
+ ExtendedFormatStatusReply extendedFormatStatusReply = new ExtendedFormatStatusReply(statusHeader, coding, statusRequestLevel.getApplication(), blockStart, null, levelInformations);
EncodedReply encodedReply = new EncodedReplyExtendedFormatStatusReply((byte) 0xC0, extendedFormatStatusReply, cBusOptions, requestContext);
ReplyEncodedReply replyEncodedReply = new ReplyEncodedReply((byte) 0xC0, encodedReply, null, cBusOptions, requestContext);
ReplyOrConfirmation replyOrConfirmation = new ReplyOrConfirmationReply((byte) 0xFF, replyEncodedReply, new ResponseTermination(), cBusOptions, requestContext);
@@ -130,7 +130,7 @@ public class CBusServerAdapter extends ChannelInboundHandlerAdapter {
// TODO: handle this
return;
}
- if (command instanceof CBusPointToMultiPointCommandNormal) {
+ if (command instanceof CBusPointToMultiPointCommandNormal) {
CBusPointToMultiPointCommandNormal cBusPointToMultiPointCommandNormal = (CBusPointToMultiPointCommandNormal) command;
LOGGER.info("Handling CBusPointToMultiPointCommandNormal\n{}", cBusPointToMultiPointCommandNormal);
return;