This is an automated email from the ASF dual-hosted git repository.
sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/develop by this push:
new 3ec51ecc82 feat(plc4go/cbus): implemented bridge support in message
mapper
3ec51ecc82 is described below
commit 3ec51ecc82acbbd4ec974a446d00a362d40d6078
Author: Sebastian Rühl <[email protected]>
AuthorDate: Fri Mar 24 18:03:47 2023 +0100
feat(plc4go/cbus): implemented bridge support in message mapper
---
plc4go/internal/cbus/CBusMessageMapper.go | 77 +++++++++++++++++++++++++------
plc4go/internal/cbus/Tag.go | 65 +++++++++++++++++++++-----
plc4go/internal/cbus/TagHandler.go | 8 +++-
3 files changed, 123 insertions(+), 27 deletions(-)
diff --git a/plc4go/internal/cbus/CBusMessageMapper.go
b/plc4go/internal/cbus/CBusMessageMapper.go
index 901c75cf43..b295b8958e 100644
--- a/plc4go/internal/cbus/CBusMessageMapper.go
+++ b/plc4go/internal/cbus/CBusMessageMapper.go
@@ -46,18 +46,33 @@ func TagToCBusMessage(tag apiModel.PlcTag, value
apiValues.PlcValue, alphaGenera
case StatusRequestTypeLevel:
statusRequest =
readWriteModel.NewStatusRequestLevel(tagType.application,
*tagType.startingGroupAddressLabel, 0x73)
}
- //TODO: we need support for bridged commands
- 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)
+ 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:])
+ }
+ 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)
+ }
request := readWriteModel.NewRequestCommand(cbusCommand, nil,
readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()),
readWriteModel.RequestType_REQUEST_COMMAND, nil, nil,
readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(),
cbusOptions)
cBusMessage, supportsRead, supportsSubscribe =
readWriteModel.NewCBusMessageToServer(request, requestContext, cbusOptions),
true, true
return
case *calRecallTag:
calData := readWriteModel.NewCALDataRecall(tagType.parameter,
tagType.count, readWriteModel.CALCommandTypeContainer_CALCommandRecall, nil,
requestContext)
- //TODO: we need support for bridged commands
- command :=
readWriteModel.NewCBusPointToPointCommandDirect(tagType.unitAddress, 0x0000,
calData, cbusOptions)
+ var command readWriteModel.CBusPointToPointCommand
+ command, err = producePointToPointCommand(tagType.unitAddress,
tagType.bridgeAddresses, calData, cbusOptions)
+ if err != nil {
+ return nil, false, false, false, errors.Wrap(err,
"error producing cal command")
+ }
header :=
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0,
readWriteModel.DestinationAddressType_PointToPoint)
cbusCommand :=
readWriteModel.NewCBusCommandPointToPoint(command, header, cbusOptions)
request := readWriteModel.NewRequestCommand(cbusCommand, nil,
readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()),
readWriteModel.RequestType_REQUEST_COMMAND, nil, nil,
readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(),
cbusOptions)
@@ -66,8 +81,11 @@ func TagToCBusMessage(tag apiModel.PlcTag, value
apiValues.PlcValue, alphaGenera
return
case *calIdentifyTag:
calData := readWriteModel.NewCALDataIdentify(tagType.attribute,
readWriteModel.CALCommandTypeContainer_CALCommandIdentify, nil, requestContext)
- //TODO: we need support for bridged commands
- command :=
readWriteModel.NewCBusPointToPointCommandDirect(tagType.unitAddress, 0x0000,
calData, cbusOptions)
+ var command readWriteModel.CBusPointToPointCommand
+ command, err = producePointToPointCommand(tagType.unitAddress,
tagType.bridgeAddresses, calData, cbusOptions)
+ if err != nil {
+ return nil, false, false, false, errors.Wrap(err,
"error producing cal command")
+ }
header :=
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0,
readWriteModel.DestinationAddressType_PointToPoint)
cbusCommand :=
readWriteModel.NewCBusCommandPointToPoint(command, header, cbusOptions)
request := readWriteModel.NewRequestCommand(cbusCommand, nil,
readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()),
readWriteModel.RequestType_REQUEST_COMMAND, nil, nil,
readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(),
cbusOptions)
@@ -76,8 +94,11 @@ func TagToCBusMessage(tag apiModel.PlcTag, value
apiValues.PlcValue, alphaGenera
return
case *calGetStatusTag:
calData :=
readWriteModel.NewCALDataGetStatus(tagType.parameter, tagType.count,
readWriteModel.CALCommandTypeContainer_CALCommandGetStatus, nil, requestContext)
- //TODO: we need support for bridged commands
- command :=
readWriteModel.NewCBusPointToPointCommandDirect(tagType.unitAddress, 0x0000,
calData, cbusOptions)
+ var command readWriteModel.CBusPointToPointCommand
+ command, err = producePointToPointCommand(tagType.unitAddress,
tagType.bridgeAddresses, calData, cbusOptions)
+ if err == nil {
+ return nil, false, false, false, errors.Wrap(err,
"error producing cal command")
+ }
header :=
readWriteModel.NewCBusHeader(readWriteModel.PriorityClass_Class4, false, 0,
readWriteModel.DestinationAddressType_PointToPoint)
cbusCommand :=
readWriteModel.NewCBusCommandPointToPoint(command, header, cbusOptions)
request := readWriteModel.NewRequestCommand(cbusCommand, nil,
readWriteModel.NewAlpha(alphaGenerator.getAndIncrement()),
readWriteModel.RequestType_REQUEST_COMMAND, nil, nil,
readWriteModel.RequestType_EMPTY, readWriteModel.NewRequestTermination(),
cbusOptions)
@@ -194,10 +215,22 @@ func TagToCBusMessage(tag apiModel.PlcTag, value
apiValues.PlcValue, alphaGenera
default:
return nil, false, false, false, errors.Errorf("No
support for %s", tagType.application)
}
- //TODO: we need support for bridged commands
- 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)
+ 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:])
+ }
+ 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)
+ }
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)
return
@@ -206,6 +239,22 @@ func TagToCBusMessage(tag apiModel.PlcTag, value
apiValues.PlcValue, alphaGenera
}
}
+func producePointToPointCommand(unitAddress readWriteModel.UnitAddress,
bridgeAddresses []readWriteModel.BridgeAddress, calData readWriteModel.CALData,
cbusOptions readWriteModel.CBusOptions)
(readWriteModel.CBusPointToPointCommand, error) {
+ 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
readWriteModel.NewCBusPointToPointCommandIndirect(bridgeAddresses[0],
networkRoute, unitAddress, 0x0000, calData, cbusOptions), nil
+ }
+
+ return readWriteModel.NewCBusPointToPointCommandDirect(unitAddress,
0x0000, calData, cbusOptions), nil
+}
+
func MapEncodedReply(transaction *spi.RequestTransaction, encodedReply
readWriteModel.EncodedReply, tagName string, addResponseCode func(name string,
responseCode apiModel.PlcResponseCode), addPlcValue func(name string, plcValue
apiValues.PlcValue)) error {
switch reply := encodedReply.(type) {
case readWriteModel.EncodedReplyCALReplyExactly:
diff --git a/plc4go/internal/cbus/Tag.go b/plc4go/internal/cbus/Tag.go
index 373fc5bd73..0f3965d89f 100644
--- a/plc4go/internal/cbus/Tag.go
+++ b/plc4go/internal/cbus/Tag.go
@@ -58,13 +58,15 @@ type Tag interface {
type StatusTag interface {
Tag
+ GetBridgeAddresses() []readWriteModel.BridgeAddress
GetStatusRequestType() StatusRequestType
GetStartingGroupAddressLabel() *byte
GetApplication() readWriteModel.ApplicationIdContainer
}
-func NewStatusTag(statusRequestType StatusRequestType,
startingGroupAddressLabel *byte, application
readWriteModel.ApplicationIdContainer, numElements uint16) StatusTag {
+func NewStatusTag(bridgeAddresses []readWriteModel.BridgeAddress,
statusRequestType StatusRequestType, startingGroupAddressLabel *byte,
application readWriteModel.ApplicationIdContainer, numElements uint16)
StatusTag {
return &statusTag{
+ bridgeAddresses: bridgeAddresses,
tagType: STATUS,
startingGroupAddressLabel: startingGroupAddressLabel,
statusRequestType: statusRequestType,
@@ -137,16 +139,18 @@ func NewCALGetStatusTag(unitAddress
readWriteModel.UnitAddress, bridgeAddresses
type SALTag interface {
Tag
+ GetBridgeAddresses() []readWriteModel.BridgeAddress
GetApplication() readWriteModel.ApplicationIdContainer
GetSALCommand() string
}
-func NewSALTag(application readWriteModel.ApplicationIdContainer, salCommand
string, numElements uint16) SALTag {
+func NewSALTag(bridgeAddresses []readWriteModel.BridgeAddress, application
readWriteModel.ApplicationIdContainer, salCommand string, numElements uint16)
SALTag {
return &salTag{
- tagType: SAL,
- application: application,
- salCommand: salCommand,
- numElements: numElements,
+ bridgeAddresses: bridgeAddresses,
+ tagType: SAL,
+ application: application,
+ salCommand: salCommand,
+ numElements: numElements,
}
}
@@ -191,6 +195,7 @@ func NewMMIMonitorTag(unitAddress
*readWriteModel.UnitAddress, application *read
//
type statusTag struct {
+ bridgeAddresses []readWriteModel.BridgeAddress
tagType TagType
statusRequestType StatusRequestType
startingGroupAddressLabel *byte
@@ -227,11 +232,13 @@ type calGetStatusTag struct {
}
type salTag struct {
- tagType TagType
- application readWriteModel.ApplicationIdContainer
- salCommand string
- numElements uint16
+ bridgeAddresses []readWriteModel.BridgeAddress
+ tagType TagType
+ application readWriteModel.ApplicationIdContainer
+ salCommand string
+ numElements uint16
}
+
type salMonitorTag struct {
tagType TagType
unitAddress *readWriteModel.UnitAddress
@@ -252,6 +259,10 @@ type mmiMonitorTag struct {
///////////////////////////////////////
///////////////////////////////////////
+func (s statusTag) GetBridgeAddresses() []readWriteModel.BridgeAddress {
+ return s.bridgeAddresses
+}
+
func (s statusTag) GetAddressString() string {
statusRequestType := ""
switch s.statusRequestType {
@@ -304,11 +315,25 @@ func (s statusTag) Serialize() ([]byte, error) {
return wb.GetBytes(), nil
}
-func (s statusTag) SerializeWithWriteBuffer(_ context.Context, writeBuffer
utils.WriteBuffer) error {
+func (s statusTag) SerializeWithWriteBuffer(ctx context.Context, writeBuffer
utils.WriteBuffer) error {
if err := writeBuffer.PushContext(s.tagType.GetName()); err != nil {
return err
}
+ if len(s.bridgeAddresses) > 0 {
+ if err := writeBuffer.PushContext("bridgeAddresses"); err !=
nil {
+ return err
+ }
+ for _, address := range s.bridgeAddresses {
+ if err := address.SerializeWithWriteBuffer(ctx,
writeBuffer); err != nil {
+ return err
+ }
+ }
+ if err := writeBuffer.PopContext("bridgeAddresses"); err != nil
{
+ return err
+ }
+ }
+
if err := writeBuffer.WriteUint8("statusRequestType", 8,
uint8(s.statusRequestType),
utils.WithAdditionalStringRepresentation(s.statusRequestType.String())); err !=
nil {
return err
}
@@ -584,6 +609,10 @@ func (c calGetStatusTag) String() string {
return writeBuffer.GetBox().String()
}
+func (s salTag) GetBridgeAddresses() []readWriteModel.BridgeAddress {
+ return s.bridgeAddresses
+}
+
func (s salTag) GetApplication() readWriteModel.ApplicationIdContainer {
return s.application
}
@@ -629,6 +658,20 @@ func (s salTag) SerializeWithWriteBuffer(ctx
context.Context, writeBuffer utils.
return err
}
+ if len(s.bridgeAddresses) > 0 {
+ if err := writeBuffer.PushContext("bridgeAddresses"); err !=
nil {
+ return err
+ }
+ for _, address := range s.bridgeAddresses {
+ if err := address.SerializeWithWriteBuffer(ctx,
writeBuffer); err != nil {
+ return err
+ }
+ }
+ if err := writeBuffer.PopContext("bridgeAddresses"); err != nil
{
+ return err
+ }
+ }
+
if err := s.application.SerializeWithWriteBuffer(ctx, writeBuffer); err
!= nil {
return err
}
diff --git a/plc4go/internal/cbus/TagHandler.go
b/plc4go/internal/cbus/TagHandler.go
index f6d4900f07..70510ae1ca 100644
--- a/plc4go/internal/cbus/TagHandler.go
+++ b/plc4go/internal/cbus/TagHandler.go
@@ -137,6 +137,8 @@ func (m TagHandler) ParseQuery(query string)
(model.PlcQuery, error) {
}
func (m TagHandler) handleStatusRequestPattern(match map[string]string)
(model.PlcTag, error) {
+ var bridgeAddresses []readWriteModel.BridgeAddress
+ // TODO: extract bridge addresses
var startingGroupAddressLabel *byte
var statusRequestType StatusRequestType
statusRequestArgument := match["statusRequestType"]
@@ -159,7 +161,7 @@ func (m TagHandler) handleStatusRequestPattern(match
map[string]string) (model.P
if err != nil {
return nil, errors.Wrap(err, "Error getting application id from
argument")
}
- return NewStatusTag(statusRequestType, startingGroupAddressLabel,
application, 1), nil
+ return NewStatusTag(bridgeAddresses, statusRequestType,
startingGroupAddressLabel, application, 1), nil
}
func (m TagHandler) handleCalPattern(match map[string]string) (model.PlcTag,
error) {
@@ -289,6 +291,8 @@ func (m TagHandler) handleCalPattern(match
map[string]string) (model.PlcTag, err
}
func (m TagHandler) handleSALPattern(match map[string]string) (model.PlcTag,
error) {
+ var bridgeAddresses []readWriteModel.BridgeAddress
+ // TODO: extract bridge addresses
application, err := applicationIdFromArgument(match["application"])
if err != nil {
return nil, errors.Wrap(err, "Error getting application id from
argument")
@@ -309,7 +313,7 @@ func (m TagHandler) handleSALPattern(match
map[string]string) (model.PlcTag, err
if !isValid {
return nil, errors.Errorf("Invalid sal command %s for %s.
Allowed requests: %s", salCommand, application,
PossibleSalCommands[application.ApplicationId()])
}
- return NewSALTag(application, salCommand, numElements), nil
+ return NewSALTag(bridgeAddresses, application, salCommand,
numElements), nil
}
func (m TagHandler) handleSALMonitorPattern(match map[string]string)
(model.PlcTag, error) {