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/26 12:39:07 UTC
[plc4x] branch develop updated: feat(plc4go/cbus): progress on field handling
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 38a8bdf4e feat(plc4go/cbus): progress on field handling
38a8bdf4e is described below
commit 38a8bdf4ec03b7e0705ec183c33108faaba6f0b0
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Tue Jul 26 14:38:46 2022 +0200
feat(plc4go/cbus): progress on field handling
---
plc4go/internal/cbus/Field.go | 87 +++++++++++++++++-----
plc4go/internal/cbus/FieldHandler.go | 74 +++++++++++++++++-
plc4go/internal/cbus/fieldtype_string.go | 7 +-
.../drivers/tests/manual_cbus_driver_test.go} | 37 +++++----
.../apache/plc4x/java/cbus/RandomPackagesTest.java | 10 +--
5 files changed, 162 insertions(+), 53 deletions(-)
diff --git a/plc4go/internal/cbus/Field.go b/plc4go/internal/cbus/Field.go
index a846ceb08..619b0c067 100644
--- a/plc4go/internal/cbus/Field.go
+++ b/plc4go/internal/cbus/Field.go
@@ -22,47 +22,96 @@ package cbus
import (
"fmt"
"github.com/apache/plc4x/plc4go/internal/spi/utils"
+ "github.com/apache/plc4x/plc4go/pkg/api/model"
readWriteModel "github.com/apache/plc4x/plc4go/protocols/cbus/readwrite/model"
)
-type PlcField interface {
+type StatusRequestType uint8
+
+const (
+ StatusRequestTypeBinaryState StatusRequestType = iota
+ StatusRequestTypeLevel
+)
+
+// StatusField can be used to query status using a P-to-MP-StatusRequest command
+type StatusField interface {
+ model.PlcField
+ GetStatusRequestType() StatusRequestType
GetApplicationId() readWriteModel.ApplicationId
}
-type plcField struct {
- NumElements uint16
+func NewStatusField(statusRequestType StatusRequestType, level *byte, applicationId readWriteModel.ApplicationId, numElements uint16) StatusField {
+ return &statusField{
+ fieldType: STATUS,
+ statusRequestType: statusRequestType,
+ applicationId: applicationId,
+ numElements: numElements,
+ }
}
-func NewField(numElements uint16) PlcField {
- return &plcField{
- NumElements: numElements,
+// CALField can be used to get device/network management fields
+type CALField interface {
+ model.PlcField
+}
+
+func NewCALField(numElements uint16) CALField {
+ return &calField{
+ fieldType: CAL,
+ numElements: numElements,
}
}
-func (m plcField) GetAddressString() string {
- // TODO: implement me
- return fmt.Sprintf("TODO[%d]", m.NumElements)
+type statusField struct {
+ fieldType FieldType
+ statusRequestType StatusRequestType
+ level *byte
+ applicationId readWriteModel.ApplicationId
+ numElements uint16
+}
+
+func (m statusField) GetAddressString() string {
+ return fmt.Sprintf("%d[%d]", m.fieldType, m.numElements)
+}
+
+func (m statusField) GetStatusRequestType() StatusRequestType {
+ return m.statusRequestType
+}
+
+func (m statusField) GetApplicationId() readWriteModel.ApplicationId {
+ return m.applicationId
+}
+
+func (m statusField) GetTypeName() string {
+ return STATUS.GetName()
+}
+
+func (m statusField) GetQuantity() uint16 {
+ return m.numElements
+}
+
+type calField struct {
+ fieldType FieldType
+ numElements uint16
}
-func (m plcField) GetTypeName() string {
- return "TODO"
+func (m calField) GetAddressString() string {
+ return fmt.Sprintf("%d[%d]", m.fieldType, m.numElements)
}
-func (m plcField) GetApplicationId() readWriteModel.ApplicationId {
- //TODO implement me
- panic("implement me")
+func (m calField) GetTypeName() string {
+ return CAL.GetName()
}
-func (m plcField) GetQuantity() uint16 {
- return m.NumElements
+func (m calField) GetQuantity() uint16 {
+ return m.numElements
}
-func (m plcField) Serialize(writeBuffer utils.WriteBuffer) error {
- if err := writeBuffer.PushContext("TODO"); err != nil {
+func (m calField) Serialize(writeBuffer utils.WriteBuffer) error {
+ if err := writeBuffer.PushContext(m.fieldType.GetName()); err != nil {
return err
}
- if err := writeBuffer.PopContext("TODO"); err != nil {
+ if err := writeBuffer.PopContext(m.fieldType.GetName()); err != nil {
return err
}
return nil
diff --git a/plc4go/internal/cbus/FieldHandler.go b/plc4go/internal/cbus/FieldHandler.go
index 5b7751823..5e79ea2e8 100644
--- a/plc4go/internal/cbus/FieldHandler.go
+++ b/plc4go/internal/cbus/FieldHandler.go
@@ -20,15 +20,22 @@
package cbus
import (
+ "encoding/hex"
+ "github.com/apache/plc4x/plc4go/internal/spi/utils"
"github.com/apache/plc4x/plc4go/pkg/api/model"
+ readWriteModel "github.com/apache/plc4x/plc4go/protocols/cbus/readwrite/model"
"github.com/pkg/errors"
+ "regexp"
+ "strconv"
+ "strings"
)
type FieldType uint8
//go:generate stringer -type FieldType
const (
- TODO FieldType = 0x00
+ STATUS FieldType = iota
+ CAL
)
func (i FieldType) GetName() string {
@@ -36,12 +43,73 @@ func (i FieldType) GetName() string {
}
type FieldHandler struct {
+ statusRequestPattern *regexp.Regexp
+ calPattern *regexp.Regexp
}
func NewFieldHandler() FieldHandler {
- return FieldHandler{}
+ return FieldHandler{
+ statusRequestPattern: regexp.MustCompile(`^status/(?P<statusRequestType>(?P<binary>binary)|level=0x(?P<level>00|20|40|60|80|A0|C0|E0))/(?P<applicationId>.*)`),
+ calPattern: regexp.MustCompile(`^cal/(?P<calType>recall=\[(?P<recallParamNo>[\w\d]+),(?P<recallCount>\d+)]|identify=\[(?P<identifyAttribute>[\w\d]+)]|getstatus=\[(?P<getstatusParamNo>[\w\d]+),(?P<getstatusCount>\d+)])`),
+ }
}
func (m FieldHandler) ParseQuery(query string) (model.PlcField, error) {
- return nil, errors.Errorf("Unable to parse %s", query)
+ if match := utils.GetSubgroupMatches(m.statusRequestPattern, query); match != nil {
+ var level *byte
+ var statusRequestType StatusRequestType
+ statusRequestArgument := match["statusRequestType"]
+ if statusRequestArgument != "" {
+ if match["binary"] != "" {
+ statusRequestType = StatusRequestTypeBinaryState
+ } else if levelArgument := match["level"]; levelArgument != "" {
+ statusRequestType = StatusRequestTypeLevel
+ decodedHex, _ := hex.DecodeString(match["level"])
+ if len(decodedHex) != 1 {
+ panic("invalid state. Should have exactly 1")
+ }
+ level = &decodedHex[0]
+ } else {
+ return nil, errors.Errorf("Unknown statusRequestType%s", statusRequestArgument)
+ }
+ }
+ var applicationId readWriteModel.ApplicationId
+ applicationIdArgument := match["applicationId"]
+ if strings.HasPrefix(applicationIdArgument, "0x") {
+ decodedHex, err := hex.DecodeString(applicationIdArgument[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")
+ }
+ applicationId = readWriteModel.ApplicationId(decodedHex[0])
+ } else {
+ atoi, err := strconv.ParseUint(applicationIdArgument, 10, 8)
+ if err != nil {
+ applicationId = readWriteModel.ApplicationId(atoi)
+ } else {
+ applicationIdByName, ok := readWriteModel.ApplicationIdByName(applicationIdArgument)
+ if !ok {
+ return nil, errors.Errorf("Unknown applicationId%s", applicationIdArgument)
+ }
+ applicationId = applicationIdByName
+ }
+ }
+ return NewStatusField(statusRequestType, level, applicationId, 1), nil
+ } else if match := utils.GetSubgroupMatches(m.calPattern, query); match != nil {
+ calTypeArgument := match["calType"]
+ switch {
+ case strings.HasPrefix(calTypeArgument, "recall="):
+ panic("Implement me ")
+ case strings.HasPrefix(calTypeArgument, "identify="):
+ panic("Implement me ")
+ case strings.HasPrefix(calTypeArgument, "getstatus="):
+ panic("Implement me ")
+ default:
+ return nil, errors.Errorf("Invalid cal type %s", calTypeArgument)
+ }
+ } 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 fbbc9d338..4c555467a 100644
--- a/plc4go/internal/cbus/fieldtype_string.go
+++ b/plc4go/internal/cbus/fieldtype_string.go
@@ -25,12 +25,13 @@ func _() {
// An "invalid array index" compiler error signifies that the constant values have changed.
// Re-run the stringer command to generate them again.
var x [1]struct{}
- _ = x[TODO-0]
+ _ = x[STATUS-0]
+ _ = x[CAL-1]
}
-const _FieldType_name = "TODO"
+const _FieldType_name = "STATUSCAL"
-var _FieldType_index = [...]uint8{0, 4}
+var _FieldType_index = [...]uint8{0, 6, 9}
func (i FieldType) String() string {
if i >= FieldType(len(_FieldType_index)-1) {
diff --git a/plc4go/internal/cbus/FieldHandler.go b/plc4go/tests/drivers/tests/manual_cbus_driver_test.go
similarity index 53%
copy from plc4go/internal/cbus/FieldHandler.go
copy to plc4go/tests/drivers/tests/manual_cbus_driver_test.go
index 5b7751823..d2a1e70da 100644
--- a/plc4go/internal/cbus/FieldHandler.go
+++ b/plc4go/tests/drivers/tests/manual_cbus_driver_test.go
@@ -17,31 +17,28 @@
* under the License.
*/
-package cbus
+package tests
import (
- "github.com/apache/plc4x/plc4go/pkg/api/model"
- "github.com/pkg/errors"
+ "github.com/apache/plc4x/plc4go/internal/cbus"
+ "github.com/apache/plc4x/plc4go/internal/spi/testutils"
+ "github.com/apache/plc4x/plc4go/pkg/api"
+ "github.com/apache/plc4x/plc4go/pkg/api/transports"
+ _ "github.com/apache/plc4x/plc4go/tests/initializetest"
+ "testing"
)
-type FieldType uint8
+func TestManualCBusDriver(t *testing.T) {
+ t.Skip()
-//go:generate stringer -type FieldType
-const (
- TODO FieldType = 0x00
-)
-
-func (i FieldType) GetName() string {
- return i.String()
-}
+ connectionString := "c-bus://192.168.178.101"
+ driverManager := plc4go.NewPlcDriverManager()
+ driverManager.RegisterDriver(cbus.NewDriver())
+ transports.RegisterTcpTransport(driverManager)
+ test := testutils.NewManualTestSuite(connectionString, driverManager, t)
-type FieldHandler struct {
-}
-
-func NewFieldHandler() FieldHandler {
- return FieldHandler{}
-}
+ test.AddTestCase("status/binary/0x04", true)
+ test.AddTestCase("status/level=0x40/0x04", true)
-func (m FieldHandler) ParseQuery(query string) (model.PlcField, error) {
- return nil, errors.Errorf("Unable to parse %s", query)
+ test.Run()
}
diff --git a/plc4j/drivers/c-bus/src/test/java/org/apache/plc4x/java/cbus/RandomPackagesTest.java b/plc4j/drivers/c-bus/src/test/java/org/apache/plc4x/java/cbus/RandomPackagesTest.java
index 3fd6ce295..7fae9f6f4 100644
--- a/plc4j/drivers/c-bus/src/test/java/org/apache/plc4x/java/cbus/RandomPackagesTest.java
+++ b/plc4j/drivers/c-bus/src/test/java/org/apache/plc4x/java/cbus/RandomPackagesTest.java
@@ -47,7 +47,6 @@ public class RandomPackagesTest {
void whatEverThisIs() throws Exception {
byte[] bytes = "\\3436303230303231303167\r".getBytes(StandardCharsets.UTF_8);
ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
- cBusOptions = C_BUS_OPTIONS_WITH_SRCHK;
CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, false, requestContext, cBusOptions, bytes.length);
assertThat(msg).isNotNull();
System.out.println(msg);
@@ -244,19 +243,14 @@ public class RandomPackagesTest {
void wat() throws Exception {
byte[] bytes = "D8FF0024000002000000000000000008000000000000000000\r\n".getBytes(StandardCharsets.UTF_8);
ReadBufferByteBased readBufferByteBased = new ReadBufferByteBased(bytes);
- cBusOptions = C_BUS_OPTIONS_WITH_SRCHK;
requestContext = new RequestContext(true, false, false);
CBusMessage msg = CBusMessage.staticParse(readBufferByteBased, true, requestContext, cBusOptions, bytes.length);
assertThat(msg).isNotNull();
System.out.println(msg);
CBusMessageToClient messageToClient = (CBusMessageToClient) msg;
ReplyOrConfirmationReply reply = (ReplyOrConfirmationReply) messageToClient.getReply();
- /*
- MonitoredSALReply monitoredSALReply = (MonitoredSALReply) reply.getReply();
- System.out.println(monitoredSALReply.getMonitoredSAL());
- */
- EncodedReplyCALReply encodedReplyCALReply = (EncodedReplyCALReply) ((ReplyEncodedReply) reply.getReply()).getEncodedReply();
- System.out.println(encodedReplyCALReply.getCalReply());
+ EncodedReplyStandardFormatStatusReply encodedReplyCALReply = (EncodedReplyStandardFormatStatusReply) ((ReplyEncodedReply) reply.getReply()).getEncodedReply();
+ System.out.println(encodedReplyCALReply.getReply());
assertMessageMatches(bytes, msg);
}