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/08/08 10:45:38 UTC
[plc4x] 01/02: feat(plc4go/cbus): added new info field for browse
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 456ba1d50889e7b9c52621caff3a7eb824fa2a40
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Mon Aug 8 12:45:04 2022 +0200
feat(plc4go/cbus): added new info field for browse
---
plc4go/internal/cbus/Field.go | 99 ++++++++++++++++++++++++++++++--
plc4go/internal/cbus/FieldHandler.go | 60 ++++++++++++++++++-
plc4go/internal/cbus/fieldtype_string.go | 5 +-
3 files changed, 156 insertions(+), 8 deletions(-)
diff --git a/plc4go/internal/cbus/Field.go b/plc4go/internal/cbus/Field.go
index c6bfebdc9..66145fb56 100644
--- a/plc4go/internal/cbus/Field.go
+++ b/plc4go/internal/cbus/Field.go
@@ -33,6 +33,16 @@ const (
StatusRequestTypeLevel
)
+func (s StatusRequestType) String() string {
+ switch s {
+ case StatusRequestTypeBinaryState:
+ return "StatusRequestTypeBinaryState"
+ case StatusRequestTypeLevel:
+ return "StatusRequestTypeLevel"
+ }
+ return ""
+}
+
// StatusField can be used to query status using a P-to-MP-StatusRequest command
type StatusField interface {
model.PlcField
@@ -51,9 +61,14 @@ func NewStatusField(statusRequestType StatusRequestType, startingGroupAddressLab
}
}
+type CalField interface {
+ GetUnitAddress() readWriteModel.UnitAddress
+}
+
// CALRecallField can be used to get device/network management fields
type CALRecallField interface {
model.PlcField
+ CalField
GetParameter() readWriteModel.Parameter
GetCount() uint8
}
@@ -71,6 +86,7 @@ func NewCALRecallField(unitAddress readWriteModel.UnitAddress, parameter readWri
// CALIdentifyField can be used to get device/network management fields
type CALIdentifyField interface {
model.PlcField
+ CalField
GetAttribute() readWriteModel.Attribute
}
@@ -86,6 +102,7 @@ func NewCALIdentifyField(unitAddress readWriteModel.UnitAddress, attribute readW
// CALGetstatusField can be used to get device/network management fields
type CALGetstatusField interface {
model.PlcField
+ CalField
GetParameter() readWriteModel.Parameter
GetCount() uint8
}
@@ -119,6 +136,7 @@ func NewSALMonitorField(unitAddress readWriteModel.UnitAddress, application read
// MMIMonitorField can be used to monitor mmi fields
type MMIMonitorField interface {
model.PlcField
+ CalField
GetUnitAddress() readWriteModel.UnitAddress
GetApplication() readWriteModel.ApplicationIdContainer
}
@@ -132,6 +150,22 @@ func NewMMIMonitorField(unitAddress readWriteModel.UnitAddress, application read
}
}
+// UnitInfoField can be used to get information about unit(s)
+type UnitInfoField interface {
+ model.PlcField
+ GetUnitAddress() *readWriteModel.UnitAddress
+ GetAttribute() *readWriteModel.Attribute
+}
+
+func NewUnitInfoField(unitAddress *readWriteModel.UnitAddress, attribute *readWriteModel.Attribute, numElements uint16) UnitInfoField {
+ return &unitInfoField{
+ unitAddress: unitAddress,
+ fieldType: UNIT_INFO,
+ attribute: attribute,
+ numElements: numElements,
+ }
+}
+
///////////////////////////////////////
///////////////////////////////////////
//
@@ -187,6 +221,13 @@ type mmiMonitorField struct {
numElements uint16
}
+type unitInfoField struct {
+ fieldType FieldType
+ unitAddress *readWriteModel.UnitAddress
+ attribute *readWriteModel.Attribute
+ numElements uint16
+}
+
//
// Internal section
//
@@ -222,8 +263,7 @@ func (m statusField) Serialize(writeBuffer utils.WriteBuffer) error {
return err
}
- // TODO: add string representation
- if err := writeBuffer.WriteUint8("statusRequestType", 8, uint8(m.statusRequestType)); err != nil {
+ if err := writeBuffer.WriteUint8("statusRequestType", 8, uint8(m.statusRequestType), utils.WithAdditionalStringRepresentation(m.statusRequestType.String())); err != nil {
return err
}
if m.startingGroupAddressLabel != nil {
@@ -241,6 +281,10 @@ func (m statusField) Serialize(writeBuffer utils.WriteBuffer) error {
return nil
}
+func (m calField) GetUnitAddress() readWriteModel.UnitAddress {
+ return m.unitAddress
+}
+
func (m calField) Serialize(writeBuffer utils.WriteBuffer) error {
return m.unitAddress.Serialize(writeBuffer)
}
@@ -274,9 +318,10 @@ func (m calRecallField) Serialize(writeBuffer utils.WriteBuffer) error {
return err
}
- if err := writeBuffer.WriteUint8("parameter", 8, uint8(m.parameter), utils.WithAdditionalStringRepresentation(m.parameter.String())); err != nil {
+ if err := m.parameter.Serialize(writeBuffer); err != nil {
return err
}
+
if err := writeBuffer.WriteUint8("count", 8, m.count); err != nil {
return err
}
@@ -312,7 +357,7 @@ func (c calIdentifyField) Serialize(writeBuffer utils.WriteBuffer) error {
return err
}
- if err := writeBuffer.WriteUint8("attribute", 8, uint8(c.attribute), utils.WithAdditionalStringRepresentation(c.attribute.String())); err != nil {
+ if err := c.attribute.Serialize(writeBuffer); err != nil {
return err
}
@@ -351,9 +396,10 @@ func (c calGetstatusField) Serialize(writeBuffer utils.WriteBuffer) error {
return err
}
- if err := writeBuffer.WriteUint8("parameter", 8, uint8(c.parameter), utils.WithAdditionalStringRepresentation(c.parameter.String())); err != nil {
+ if err := c.parameter.Serialize(writeBuffer); err != nil {
return err
}
+
if err := writeBuffer.WriteUint8("count", 8, c.count); err != nil {
return err
}
@@ -439,3 +485,46 @@ func (m mmiMonitorField) Serialize(writeBuffer utils.WriteBuffer) error {
}
return nil
}
+
+func (u unitInfoField) GetUnitAddress() *readWriteModel.UnitAddress {
+ return u.unitAddress
+}
+
+func (u unitInfoField) GetAttribute() *readWriteModel.Attribute {
+ return u.attribute
+}
+
+func (u unitInfoField) GetAddressString() string {
+ return fmt.Sprintf("%d[%d]", u.fieldType, u.numElements)
+}
+
+func (u unitInfoField) GetTypeName() string {
+ return u.fieldType.GetName()
+}
+
+func (u unitInfoField) GetQuantity() uint16 {
+ return u.numElements
+}
+
+func (u unitInfoField) Serialize(writeBuffer utils.WriteBuffer) error {
+ if err := writeBuffer.PushContext(u.fieldType.GetName()); err != nil {
+ return err
+ }
+
+ if unitAddress := u.unitAddress; unitAddress != nil {
+ if err := (*unitAddress).Serialize(writeBuffer); err != nil {
+ return err
+ }
+ }
+
+ if attribute := u.attribute; attribute != nil {
+ if err := (*attribute).Serialize(writeBuffer); err != nil {
+ return err
+ }
+ }
+
+ if err := writeBuffer.PopContext(u.fieldType.GetName()); err != nil {
+ return err
+ }
+ return nil
+}
diff --git a/plc4go/internal/cbus/FieldHandler.go b/plc4go/internal/cbus/FieldHandler.go
index ece7035b4..c62cb7a8f 100644
--- a/plc4go/internal/cbus/FieldHandler.go
+++ b/plc4go/internal/cbus/FieldHandler.go
@@ -40,6 +40,7 @@ const (
CAL_GETSTATUS
SAL_MONITOR
MMI_STATUS_MONITOR
+ UNIT_INFO
)
func (i FieldType) GetName() string {
@@ -51,14 +52,16 @@ type FieldHandler struct {
calPattern *regexp.Regexp
salMonitorPattern *regexp.Regexp
mmiMonitorPattern *regexp.Regexp
+ unityQuery *regexp.Regexp
}
func NewFieldHandler() FieldHandler {
return FieldHandler{
statusRequestPattern: regexp.MustCompile(`^status/(?P<statusRequestType>(?P<binary>binary)|level=0x(?P<startingGroupAddressLabel>00|20|40|60|80|A0|C0|E0))/(?P<application>.*)`),
- calPattern: regexp.MustCompile(`^cal/(?P<unitAddress>.*)/(?P<calType>recall=\[(?P<recallParamNo>[\w\d]+), ?(?P<recallCount>\d+)]|identify=\[(?P<identifyAttribute>[\w\d]+)]|getstatus=\[(?P<getstatusParamNo>[\w\d]+), ?(?P<getstatusCount>\d+)])`),
+ calPattern: regexp.MustCompile(`^cal/(?P<unitAddress>.*)/(?P<calType>recall=\[(?P<recallParamNo>\w+), ?(?P<recallCount>\d+)]|identify=(?P<identifyAttribute>\w+)|getstatus=(?P<getstatusParamNo>\w+), ?(?P<getstatusCount>\d+))`),
salMonitorPattern: regexp.MustCompile(`^salmonitor/(?P<unitAddress>.*)/(?P<application>.*)`),
mmiMonitorPattern: regexp.MustCompile(`^mmimonitor/(?P<unitAddress>.*)/(?P<application>.*)`),
+ unityQuery: regexp.MustCompile(`^info/(?P<unitAddress>.*)/(?P<identifyAttribute>\w+)`),
}
}
@@ -275,6 +278,61 @@ func (m FieldHandler) ParseQuery(query string) (model.PlcField, error) {
}
return NewMMIMonitorField(unitAddress, application, 1), nil
+ } else if match := utils.GetSubgroupMatches(m.unityQuery, query); match != nil {
+ var unitAddress *readWriteModel.UnitAddress
+ unitAddressArgument := match["unitAddress"]
+ if unitAddressArgument == "*" {
+ unitAddress = nil
+ } else if strings.HasPrefix(unitAddressArgument, "0x") {
+ decodedHex, err := hex.DecodeString(unitAddressArgument[2:])
+ if err != nil {
+ return nil, errors.Wrap(err, "Not a valid hex")
+ }
+ if len(decodedHex) != 1 {
+ return nil, errors.Errorf("Hex must be exatly one byte")
+ }
+ var unitAddressVar readWriteModel.UnitAddress
+ unitAddressVar = readWriteModel.NewUnitAddress(decodedHex[0])
+ unitAddress = &unitAddressVar
+ } else {
+ atoi, err := strconv.ParseUint(unitAddressArgument, 10, 8)
+ if err != nil {
+ return nil, errors.Errorf("Unknown unit address %s", unitAddressArgument)
+ }
+ var unitAddressVar readWriteModel.UnitAddress
+ unitAddressVar = readWriteModel.NewUnitAddress(byte(atoi))
+ unitAddress = &unitAddressVar
+ }
+
+ var attribute *readWriteModel.Attribute
+ attributeArgument := match["identifyAttribute"]
+ if strings.HasPrefix(attributeArgument, "0x") {
+ decodedHex, err := hex.DecodeString(attributeArgument[2:])
+ if err != nil {
+ return nil, errors.Wrap(err, "Not a valid hex")
+ }
+ if len(decodedHex) != 1 {
+ return nil, errors.Errorf("Hex must be exatly one byte")
+ }
+ var attributeVar readWriteModel.Attribute
+ attributeVar = readWriteModel.Attribute(decodedHex[0])
+ attribute = &attributeVar
+ } else {
+ if atoi, err := strconv.ParseUint(attributeArgument, 10, 8); err == nil {
+ var attributeVar readWriteModel.Attribute
+ attributeVar = readWriteModel.Attribute(atoi)
+ attribute = &attributeVar
+ } else {
+ parameterByName, ok := readWriteModel.AttributeByName(attributeArgument)
+ if !ok {
+ return nil, errors.Errorf("Unknown attributeArgument %s", attributeArgument)
+ }
+ var attributeVar readWriteModel.Attribute
+ attributeVar = parameterByName
+ attribute = &attributeVar
+ }
+ }
+ return NewUnitInfoField(unitAddress, attribute, 1), nil
} else {
return nil, errors.Errorf("Unable to parse %s", query)
}
diff --git a/plc4go/internal/cbus/fieldtype_string.go b/plc4go/internal/cbus/fieldtype_string.go
index dd663f49a..0456cc67d 100644
--- a/plc4go/internal/cbus/fieldtype_string.go
+++ b/plc4go/internal/cbus/fieldtype_string.go
@@ -31,11 +31,12 @@ func _() {
_ = x[CAL_GETSTATUS-3]
_ = x[SAL_MONITOR-4]
_ = x[MMI_STATUS_MONITOR-5]
+ _ = x[UNIT_INFO-6]
}
-const _FieldType_name = "STATUSCAL_RECALLCAL_IDENTIFYCAL_GETSTATUSSAL_MONITORMMI_STATUS_MONITOR"
+const _FieldType_name = "STATUSCAL_RECALLCAL_IDENTIFYCAL_GETSTATUSSAL_MONITORMMI_STATUS_MONITORUNIT_INFO"
-var _FieldType_index = [...]uint8{0, 6, 16, 28, 41, 52, 70}
+var _FieldType_index = [...]uint8{0, 6, 16, 28, 41, 52, 70, 79}
func (i FieldType) String() string {
if i >= FieldType(len(_FieldType_index)-1) {