Skip to content

Commit

Permalink
fix(plc4go/cbus): fix bridge addressing
Browse files Browse the repository at this point in the history
  • Loading branch information
sruehl committed Mar 27, 2023
1 parent a5902a6 commit c045c60
Show file tree
Hide file tree
Showing 2 changed files with 280 additions and 62 deletions.
39 changes: 18 additions & 21 deletions plc4go/internal/cbus/CBusMessageMapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,18 @@ func TagToCBusMessage(tag apiModel.PlcTag, value apiValues.PlcValue, alphaGenera
var cbusCommand readWriteModel.CBusCommand
bridgeAddresses := tagType.bridgeAddresses
numberOfBridgeAddresses := len(bridgeAddresses)
if numberOfBridgeAddresses <= 0 {
command := readWriteModel.NewCBusPointToMultiPointCommandStatus(statusRequest, byte(tagType.application), cbusOptions)
header := readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToMultiPoint)
cbusCommand = readWriteModel.NewCBusCommandPointToMultiPoint(command, header, cbusOptions)
} else {
var networkRoute readWriteModel.NetworkRoute
if numberOfBridgeAddresses > 1 {
networkRoute = readWriteModel.NewNetworkRoute(readWriteModel.NewNetworkProtocolControlInformation(uint8(numberOfBridgeAddresses), uint8(numberOfBridgeAddresses)), bridgeAddresses[1:])
if numberOfBridgeAddresses > 0 {
if numberOfBridgeAddresses > 6 {
return nil, false, false, false, errors.Errorf("Can't have a path longer than 6. Actuall path length = %d", numberOfBridgeAddresses)
}
networkRoute := readWriteModel.NewNetworkRoute(readWriteModel.NewNetworkProtocolControlInformation(uint8(numberOfBridgeAddresses), uint8(numberOfBridgeAddresses)), bridgeAddresses[1:])
command := readWriteModel.NewCBusPointToPointToMultiPointCommandStatus(statusRequest, bridgeAddresses[0], networkRoute, byte(tagType.application), cbusOptions)
header := readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPointToMultiPoint)
cbusCommand = readWriteModel.NewCBusCommandPointToPointToMultiPoint(command, header, cbusOptions)
} else {
command := readWriteModel.NewCBusPointToMultiPointCommandStatus(statusRequest, byte(tagType.application), cbusOptions)
header := readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToMultiPoint)
cbusCommand = readWriteModel.NewCBusCommandPointToMultiPoint(command, header, cbusOptions)
}
request := readWriteModel.NewRequestCommand(cbusCommand, nil, readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()), readWriteModel.RequestType_REQUEST_COMMAND, nil, nil, readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(), cbusOptions)

Expand Down Expand Up @@ -218,18 +218,18 @@ func TagToCBusMessage(tag apiModel.PlcTag, value apiValues.PlcValue, alphaGenera
var cbusCommand readWriteModel.CBusCommand
bridgeAddresses := tagType.bridgeAddresses
numberOfBridgeAddresses := len(bridgeAddresses)
if numberOfBridgeAddresses <= 0 {
command := readWriteModel.NewCBusPointToMultiPointCommandNormal(tagType.application, salData, 0x00, cbusOptions)
header := readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint)
cbusCommand = readWriteModel.NewCBusCommandPointToMultiPoint(command, header, cbusOptions)
} else {
var networkRoute readWriteModel.NetworkRoute
if numberOfBridgeAddresses > 1 {
networkRoute = readWriteModel.NewNetworkRoute(readWriteModel.NewNetworkProtocolControlInformation(uint8(numberOfBridgeAddresses), uint8(numberOfBridgeAddresses)), bridgeAddresses[1:])
if numberOfBridgeAddresses > 0 {
if numberOfBridgeAddresses > 6 {
return nil, false, false, false, errors.Errorf("Can't have a path longer than 6. Actuall path length = %d", numberOfBridgeAddresses)
}
networkRoute := readWriteModel.NewNetworkRoute(readWriteModel.NewNetworkProtocolControlInformation(uint8(numberOfBridgeAddresses), uint8(numberOfBridgeAddresses)), bridgeAddresses[1:])
command := readWriteModel.NewCBusPointToPointToMultiPointCommandNormal(tagType.application, salData, bridgeAddresses[0], networkRoute, byte(tagType.application), cbusOptions)
header := readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPointToMultiPoint)
cbusCommand = readWriteModel.NewCBusCommandPointToPointToMultiPoint(command, header, cbusOptions)
} else {
command := readWriteModel.NewCBusPointToMultiPointCommandNormal(tagType.application, salData, 0x00, cbusOptions)
header := readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPoint)
cbusCommand = readWriteModel.NewCBusCommandPointToMultiPoint(command, header, cbusOptions)
}
request := readWriteModel.NewRequestCommand(cbusCommand, nil, readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()), readWriteModel.RequestType_REQUEST_COMMAND, nil, nil, readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(), cbusOptions)
cBusMessage = readWriteModel.NewCBusMessageToServer(request, requestContext, cbusOptions)
Expand All @@ -243,12 +243,9 @@ func producePointToPointCommand(unitAddress readWriteModel.UnitAddress, bridgeAd
numberOfBridgeAddresses := len(bridgeAddresses)
if numberOfBridgeAddresses > 0 {
if numberOfBridgeAddresses > 6 {
return nil, errors.Errorf("invalid number of bridge addresses %d. Max 6 allowed", numberOfBridgeAddresses)
}
var networkRoute readWriteModel.NetworkRoute
if numberOfBridgeAddresses > 1 {
networkRoute = readWriteModel.NewNetworkRoute(readWriteModel.NewNetworkProtocolControlInformation(uint8(numberOfBridgeAddresses), uint8(numberOfBridgeAddresses)), bridgeAddresses[1:])
return nil, errors.Errorf("Can't have a path longer than 6. Actuall path length = %d", numberOfBridgeAddresses)
}
networkRoute := readWriteModel.NewNetworkRoute(readWriteModel.NewNetworkProtocolControlInformation(uint8(numberOfBridgeAddresses), uint8(numberOfBridgeAddresses)), bridgeAddresses[1:])
return readWriteModel.NewCBusPointToPointCommandIndirect(bridgeAddresses[0], networkRoute, unitAddress, 0x0000, calData, cbusOptions), nil
}

Expand Down
303 changes: 262 additions & 41 deletions plc4go/internal/cbus/CBusMessageMapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,272 @@ import (
apiValues "github.com/apache/plc4x/plc4go/pkg/api/values"
readWriteModel "github.com/apache/plc4x/plc4go/protocols/cbus/readwrite/model"
"github.com/apache/plc4x/plc4go/spi"
"github.com/apache/plc4x/plc4go/spi/utils"
"reflect"
"testing"
)

func TestTagToCBusMessage(t *testing.T) {
type args struct {
tag apiModel.PlcTag
value apiValues.PlcValue
alphaGenerator *AlphaGenerator
messageCodec *MessageCodec
}
cbusOptions := readWriteModel.NewCBusOptions(false, false, false, false, false, false, false, false, true)
requestContext := readWriteModel.NewRequestContext(false)
tests := []struct {
name string
args args
wantCBusMessage readWriteModel.CBusMessage
wantSupportsRead bool
wantSupportsWrite bool
wantSupportsSubscribe bool
wantErr bool
}{
{
name: "direct status binary",
args: args{
tag: NewStatusTag(nil, StatusRequestTypeBinaryState, nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusPointToMultiPointCommandStatus(
readWriteModel.NewStatusRequestBinaryState(
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
122,
),
58,
cbusOptions,
),
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToMultiPoint),
cbusOptions,
),
nil,
readWriteModel.NewAlpha(0),
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
),
requestContext,
cbusOptions,
),
wantSupportsRead: true,
wantSupportsSubscribe: true,
},
{
name: "direct status level",
args: args{
tag: NewStatusTag(nil, StatusRequestTypeLevel, func() *byte {
var b byte = 13
return &b
}(), readWriteModel.ApplicationIdContainer_LIGHTING_3A, 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.NewCBusCommandPointToMultiPoint(
readWriteModel.NewCBusPointToMultiPointCommandStatus(
readWriteModel.NewStatusRequestLevel(
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
13,
115,
),
58,
cbusOptions,
),
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToMultiPoint),
cbusOptions,
),
nil,
readWriteModel.NewAlpha(0),
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
),
requestContext,
cbusOptions,
),
wantSupportsRead: true,
wantSupportsSubscribe: true,
},
{
name: "direct status binary bridged one bridge",
args: args{
tag: NewStatusTag([]readWriteModel.BridgeAddress{readWriteModel.NewBridgeAddress(12)}, StatusRequestTypeBinaryState, nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.NewCBusCommandPointToPointToMultiPoint(
readWriteModel.NewCBusPointToPointToMultiPointCommandStatus(
readWriteModel.NewStatusRequestBinaryState(
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
122,
),
readWriteModel.NewBridgeAddress(12),
readWriteModel.NewNetworkRoute(readWriteModel.NewNetworkProtocolControlInformation(1, 1), []readWriteModel.BridgeAddress{}),
58,
cbusOptions,
),
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPointToMultiPoint),
cbusOptions,
),
nil,
readWriteModel.NewAlpha(0),
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
),
requestContext,
cbusOptions,
),
wantSupportsRead: true,
wantSupportsSubscribe: true,
},
{
name: "direct status binary bridged two bridges",
args: args{
tag: NewStatusTag([]readWriteModel.BridgeAddress{readWriteModel.NewBridgeAddress(12), readWriteModel.NewBridgeAddress(13)}, StatusRequestTypeBinaryState, nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.NewCBusCommandPointToPointToMultiPoint(
readWriteModel.NewCBusPointToPointToMultiPointCommandStatus(
readWriteModel.NewStatusRequestBinaryState(
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
122,
),
readWriteModel.NewBridgeAddress(12),
readWriteModel.NewNetworkRoute(readWriteModel.NewNetworkProtocolControlInformation(2, 2), []readWriteModel.BridgeAddress{readWriteModel.NewBridgeAddress(13)}),
58,
cbusOptions,
),
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPointToMultiPoint),
cbusOptions,
),
nil,
readWriteModel.NewAlpha(0),
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
),
requestContext,
cbusOptions,
),
wantSupportsRead: true,
wantSupportsSubscribe: true,
},
{
name: "direct status binary bridged 6 bridges",
args: args{
tag: NewStatusTag([]readWriteModel.BridgeAddress{readWriteModel.NewBridgeAddress(12), readWriteModel.NewBridgeAddress(13), readWriteModel.NewBridgeAddress(14), readWriteModel.NewBridgeAddress(15), readWriteModel.NewBridgeAddress(16), readWriteModel.NewBridgeAddress(17)}, StatusRequestTypeBinaryState, nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantCBusMessage: readWriteModel.NewCBusMessageToServer(
readWriteModel.NewRequestCommand(
readWriteModel.NewCBusCommandPointToPointToMultiPoint(
readWriteModel.NewCBusPointToPointToMultiPointCommandStatus(
readWriteModel.NewStatusRequestBinaryState(
readWriteModel.ApplicationIdContainer_LIGHTING_3A,
122,
),
readWriteModel.NewBridgeAddress(12),
readWriteModel.NewNetworkRoute(readWriteModel.NewNetworkProtocolControlInformation(6, 6), []readWriteModel.BridgeAddress{readWriteModel.NewBridgeAddress(13), readWriteModel.NewBridgeAddress(14), readWriteModel.NewBridgeAddress(15), readWriteModel.NewBridgeAddress(16), readWriteModel.NewBridgeAddress(17)}),
58,
cbusOptions,
),
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0, readWriteModel.DestinationAddressType_PointToPointToMultiPoint),
cbusOptions,
),
nil,
readWriteModel.NewAlpha(0),
readWriteModel.RequestType_REQUEST_COMMAND,
nil,
nil,
readWriteModel.RequestType_EMPTY,
readWriteModel.NewRequestTermination(),
cbusOptions,
),
requestContext,
cbusOptions,
),
wantSupportsRead: true,
wantSupportsSubscribe: true,
},
{
name: "direct status binary bridged 7 bridges",
args: args{
tag: NewStatusTag([]readWriteModel.BridgeAddress{readWriteModel.NewBridgeAddress(12), readWriteModel.NewBridgeAddress(13), readWriteModel.NewBridgeAddress(14), readWriteModel.NewBridgeAddress(15), readWriteModel.NewBridgeAddress(16), readWriteModel.NewBridgeAddress(17), readWriteModel.NewBridgeAddress(18)}, StatusRequestTypeBinaryState, nil, readWriteModel.ApplicationIdContainer_LIGHTING_3A, 1),
alphaGenerator: &AlphaGenerator{},
messageCodec: &MessageCodec{
cbusOptions: cbusOptions,
requestContext: requestContext,
},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotCBusMessage, gotSupportsRead, gotSupportsWrite, gotSupportsSubscribe, err := TagToCBusMessage(tt.args.tag, tt.args.value, tt.args.alphaGenerator, tt.args.messageCodec)
if (err != nil) != tt.wantErr {
t.Errorf("TagToCBusMessage() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(gotCBusMessage, tt.wantCBusMessage) {
gotBox := utils.BoxAnything("got", gotCBusMessage, 120)
wantBox := utils.BoxAnything("want", tt.wantCBusMessage, 120)
t.Errorf("TagToCBusMessage():\n%s", utils.NewAsciiBoxWriter().BoxSideBySide(gotBox, wantBox))
}
if gotSupportsRead != tt.wantSupportsRead {
t.Errorf("TagToCBusMessage() gotSupportsRead = %v, want %v", gotSupportsRead, tt.wantSupportsRead)
}
if gotSupportsWrite != tt.wantSupportsWrite {
t.Errorf("TagToCBusMessage() gotSupportsWrite = %v, want %v", gotSupportsWrite, tt.wantSupportsWrite)
}
if gotSupportsSubscribe != tt.wantSupportsSubscribe {
t.Errorf("TagToCBusMessage() gotSupportsSubscribe = %v, want %v", gotSupportsSubscribe, tt.wantSupportsSubscribe)
}
})
}
}

func TestMapEncodedReply(t *testing.T) {
type args struct {
transaction *spi.RequestTransaction
Expand Down Expand Up @@ -92,44 +354,3 @@ func TestMapEncodedReply(t *testing.T) {
})
}
}

func TestTagToCBusMessage(t *testing.T) {
type args struct {
tag apiModel.PlcTag
value apiValues.PlcValue
alphaGenerator *AlphaGenerator
messageCodec *MessageCodec
}
tests := []struct {
name string
args args
wantCBusMessage readWriteModel.CBusMessage
wantSupportsRead bool
wantSupportsWrite bool
wantSupportsSubscribe bool
wantErr bool
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotCBusMessage, gotSupportsRead, gotSupportsWrite, gotSupportsSubscribe, err := TagToCBusMessage(tt.args.tag, tt.args.value, tt.args.alphaGenerator, tt.args.messageCodec)
if (err != nil) != tt.wantErr {
t.Errorf("TagToCBusMessage() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(gotCBusMessage, tt.wantCBusMessage) {
t.Errorf("TagToCBusMessage() gotCBusMessage = %v, want %v", gotCBusMessage, tt.wantCBusMessage)
}
if gotSupportsRead != tt.wantSupportsRead {
t.Errorf("TagToCBusMessage() gotSupportsRead = %v, want %v", gotSupportsRead, tt.wantSupportsRead)
}
if gotSupportsWrite != tt.wantSupportsWrite {
t.Errorf("TagToCBusMessage() gotSupportsWrite = %v, want %v", gotSupportsWrite, tt.wantSupportsWrite)
}
if gotSupportsSubscribe != tt.wantSupportsSubscribe {
t.Errorf("TagToCBusMessage() gotSupportsSubscribe = %v, want %v", gotSupportsSubscribe, tt.wantSupportsSubscribe)
}
})
}
}

0 comments on commit c045c60

Please sign in to comment.