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/10 14:20:34 UTC

[plc4x] 03/03: feat(plc4go/cbus): added interceptor to browser

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 78cd30b6cef6ba0f266b0be411f16aacb59b727e
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Wed Aug 10 16:18:21 2022 +0200

    feat(plc4go/cbus): added interceptor to browser
---
 plc4go/internal/cbus/Browser.go                    | 22 ++++-
 plc4go/internal/cbus/Field.go                      | 96 +++++++++++++++++-----
 plc4go/internal/cbus/Reader.go                     |  2 +-
 plc4go/internal/spi/model/DefaultPlcBrowseEvent.go | 64 ++++++++++++++-
 plc4go/pkg/api/model/plc_response_code.go          |  4 +
 .../tests/drivers/tests/manual_cbus_driver_test.go | 18 ++--
 plc4go/tools/plc4xbrowser/ui/commands.go           |  6 +-
 7 files changed, 179 insertions(+), 33 deletions(-)

diff --git a/plc4go/internal/cbus/Browser.go b/plc4go/internal/cbus/Browser.go
index d3ca94512..de095f882 100644
--- a/plc4go/internal/cbus/Browser.go
+++ b/plc4go/internal/cbus/Browser.go
@@ -111,21 +111,37 @@ func (m Browser) BrowseWithInterceptor(browseRequest apiModel.PlcBrowseRequest,
 							}
 							continue unitLoop
 						}
-						queryResults = append(queryResults, &model.DefaultPlcBrowseQueryResult{
+						response := requestResult.GetResponse()
+						if code := response.GetResponseCode(readFieldName); code != apiModel.PlcResponseCode_OK {
+							event.Msgf("unit %d: error reading field %s. Code %s", unitAddress, attribute, code)
+							continue unitLoop
+						}
+						queryResult := &model.DefaultPlcBrowseQueryResult{
 							Field:        NewCALIdentifyField(unit, attribute, 1),
 							Name:         fieldName,
 							Readable:     true,
 							Writable:     false,
 							Subscribable: false,
 							Attributes: map[string]values.PlcValue{
-								"CurrentValue": requestResult.GetResponse().GetValue(readFieldName),
+								"CurrentValue": response.GetValue(readFieldName),
 							},
-						})
+						}
+						if interceptor != nil {
+							interceptor(&model.DefaultPlcBrowseEvent{
+								Request:   browseRequest,
+								FieldName: readFieldName,
+								Result:    queryResult,
+								Err:       nil,
+							})
+						}
+						queryResults = append(queryResults, queryResult)
 					}
 				}
+				responseCodes[fieldName] = apiModel.PlcResponseCode_OK
 			default:
 				responseCodes[fieldName] = apiModel.PlcResponseCode_INTERNAL_ERROR
 			}
+			results[fieldName] = queryResults
 		}
 		result <- &model.DefaultPlcBrowseRequestResult{
 			Request:  browseRequest,
diff --git a/plc4go/internal/cbus/Field.go b/plc4go/internal/cbus/Field.go
index 66145fb56..16a271506 100644
--- a/plc4go/internal/cbus/Field.go
+++ b/plc4go/internal/cbus/Field.go
@@ -281,57 +281,73 @@ func (m statusField) Serialize(writeBuffer utils.WriteBuffer) error {
 	return nil
 }
 
-func (m calField) GetUnitAddress() readWriteModel.UnitAddress {
-	return m.unitAddress
+func (c calField) GetUnitAddress() readWriteModel.UnitAddress {
+	return c.unitAddress
 }
 
-func (m calField) Serialize(writeBuffer utils.WriteBuffer) error {
-	return m.unitAddress.Serialize(writeBuffer)
+func (c calField) Serialize(writeBuffer utils.WriteBuffer) error {
+	return c.unitAddress.Serialize(writeBuffer)
 }
 
-func (m calRecallField) GetParameter() readWriteModel.Parameter {
-	return m.parameter
+func (c calField) String() string {
+	writeBuffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(c); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
 }
 
-func (m calRecallField) GetCount() uint8 {
-	return m.count
+func (c calRecallField) GetParameter() readWriteModel.Parameter {
+	return c.parameter
 }
 
-func (m calRecallField) GetAddressString() string {
-	return fmt.Sprintf("%d[%d]", m.fieldType, m.numElements)
+func (c calRecallField) GetCount() uint8 {
+	return c.count
 }
 
-func (m calRecallField) GetTypeName() string {
-	return m.fieldType.GetName()
+func (c calRecallField) GetAddressString() string {
+	return fmt.Sprintf("%d[%d]", c.fieldType, c.numElements)
 }
 
-func (m calRecallField) GetQuantity() uint16 {
-	return m.numElements
+func (c calRecallField) GetTypeName() string {
+	return c.fieldType.GetName()
 }
 
-func (m calRecallField) Serialize(writeBuffer utils.WriteBuffer) error {
-	if err := writeBuffer.PushContext(m.fieldType.GetName()); err != nil {
+func (c calRecallField) GetQuantity() uint16 {
+	return c.numElements
+}
+
+func (c calRecallField) Serialize(writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext(c.fieldType.GetName()); err != nil {
 		return err
 	}
 
-	if err := m.calField.Serialize(writeBuffer); err != nil {
+	if err := c.calField.Serialize(writeBuffer); err != nil {
 		return err
 	}
 
-	if err := m.parameter.Serialize(writeBuffer); err != nil {
+	if err := c.parameter.Serialize(writeBuffer); err != nil {
 		return err
 	}
 
-	if err := writeBuffer.WriteUint8("count", 8, m.count); err != nil {
+	if err := writeBuffer.WriteUint8("count", 8, c.count); err != nil {
 		return err
 	}
 
-	if err := writeBuffer.PopContext(m.fieldType.GetName()); err != nil {
+	if err := writeBuffer.PopContext(c.fieldType.GetName()); err != nil {
 		return err
 	}
 	return nil
 }
 
+func (c calRecallField) String() string {
+	writeBuffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(c); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
+
 func (c calIdentifyField) GetAttribute() readWriteModel.Attribute {
 	return c.attribute
 }
@@ -367,6 +383,14 @@ func (c calIdentifyField) Serialize(writeBuffer utils.WriteBuffer) error {
 	return nil
 }
 
+func (c calIdentifyField) String() string {
+	writeBuffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(c); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
+
 func (c calGetstatusField) GetParameter() readWriteModel.Parameter {
 	return c.parameter
 }
@@ -410,6 +434,14 @@ func (c calGetstatusField) Serialize(writeBuffer utils.WriteBuffer) error {
 	return nil
 }
 
+func (c calGetstatusField) String() string {
+	writeBuffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(c); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
+
 func (s salMonitorField) GetAddressString() string {
 	return fmt.Sprintf("%d/%s%s[%d]", s.fieldType, s.unitAddress, s.application, s.numElements)
 }
@@ -448,6 +480,14 @@ func (s salMonitorField) Serialize(writeBuffer utils.WriteBuffer) error {
 	return nil
 }
 
+func (s salMonitorField) String() string {
+	writeBuffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(s); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
+
 func (m mmiMonitorField) GetAddressString() string {
 	return fmt.Sprintf("%d/%s%s[%d]", m.fieldType, m.unitAddress, m.application, m.numElements)
 }
@@ -486,6 +526,14 @@ func (m mmiMonitorField) Serialize(writeBuffer utils.WriteBuffer) error {
 	return nil
 }
 
+func (m mmiMonitorField) String() string {
+	writeBuffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(m); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
+
 func (u unitInfoField) GetUnitAddress() *readWriteModel.UnitAddress {
 	return u.unitAddress
 }
@@ -528,3 +576,11 @@ func (u unitInfoField) Serialize(writeBuffer utils.WriteBuffer) error {
 	}
 	return nil
 }
+
+func (u unitInfoField) String() string {
+	writeBuffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(u); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/internal/cbus/Reader.go b/plc4go/internal/cbus/Reader.go
index 0778cdeb9..954463e09 100644
--- a/plc4go/internal/cbus/Reader.go
+++ b/plc4go/internal/cbus/Reader.go
@@ -126,7 +126,7 @@ func (m *Reader) Read(readRequest model.PlcReadRequest) <-chan model.PlcReadRequ
 						cbusMessage := receivedMessage.(readWriteModel.CBusMessage)
 						messageToClient := cbusMessage.(readWriteModel.CBusMessageToClient)
 						if _, ok := messageToClient.GetReply().(readWriteModel.ServerErrorReplyExactly); ok {
-							log.Debug().Msg("We got a server failure")
+							log.Trace().Msg("We got a server failure")
 							addResponseCode(fieldNameCopy, model.PlcResponseCode_INVALID_DATA)
 							requestWasOk <- false
 							return transaction.EndRequest()
diff --git a/plc4go/internal/spi/model/DefaultPlcBrowseEvent.go b/plc4go/internal/spi/model/DefaultPlcBrowseEvent.go
index 004ed32df..1c6864fe0 100644
--- a/plc4go/internal/spi/model/DefaultPlcBrowseEvent.go
+++ b/plc4go/internal/spi/model/DefaultPlcBrowseEvent.go
@@ -19,7 +19,11 @@
 
 package model
 
-import "github.com/apache/plc4x/plc4go/pkg/api/model"
+import (
+	"github.com/apache/plc4x/plc4go/internal/spi/utils"
+	"github.com/apache/plc4x/plc4go/pkg/api/model"
+	"github.com/pkg/errors"
+)
 
 type DefaultPlcBrowseEvent struct {
 	Request   model.PlcBrowseRequest
@@ -43,3 +47,61 @@ func (d *DefaultPlcBrowseEvent) GetResult() model.PlcBrowseFoundField {
 func (d *DefaultPlcBrowseEvent) GetErr() error {
 	return d.Err
 }
+
+func (d *DefaultPlcBrowseEvent) Serialize(writeBuffer utils.WriteBuffer) error {
+	if err := writeBuffer.PushContext("PlcBrowseEvent"); err != nil {
+		return err
+	}
+
+	if d.Request != nil {
+		if err := writeBuffer.PushContext("Request"); err != nil {
+			return err
+		}
+		if serializableField, ok := d.Request.(utils.Serializable); ok {
+			if err := serializableField.Serialize(writeBuffer); err != nil {
+				return err
+			}
+		} else {
+			return errors.Errorf("Error serializing. Field %T doesn't implement Serializable", d.Request)
+		}
+		if err := writeBuffer.PopContext("Request"); err != nil {
+			return err
+		}
+	}
+	if err := writeBuffer.WriteString("fieldName", uint32(len(d.FieldName)*8), "UTF-8", d.FieldName); err != nil {
+		return err
+	}
+	if d.Result != nil {
+		if err := writeBuffer.PushContext("Result"); err != nil {
+			return err
+		}
+		if serializableField, ok := d.Result.(utils.Serializable); ok {
+			if err := serializableField.Serialize(writeBuffer); err != nil {
+				return err
+			}
+		} else {
+			return errors.Errorf("Error serializing. Field %T doesn't implement Serializable", d.Result)
+		}
+		if err := writeBuffer.PopContext("Result"); err != nil {
+			return err
+		}
+	}
+	if d.Err != nil {
+		if err := writeBuffer.WriteString("err", uint32(len(d.Err.Error())*8), "UTF-8", d.Err.Error()); err != nil {
+			return err
+		}
+	}
+
+	if err := writeBuffer.PopContext("PlcBrowseEvent"); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d *DefaultPlcBrowseEvent) String() string {
+	writeBuffer := utils.NewBoxedWriteBufferWithOptions(true, true)
+	if err := writeBuffer.WriteSerializable(d); err != nil {
+		return err.Error()
+	}
+	return writeBuffer.GetBox().String()
+}
diff --git a/plc4go/pkg/api/model/plc_response_code.go b/plc4go/pkg/api/model/plc_response_code.go
index 63f187887..d3daa11d7 100644
--- a/plc4go/pkg/api/model/plc_response_code.go
+++ b/plc4go/pkg/api/model/plc_response_code.go
@@ -66,3 +66,7 @@ func (m PlcResponseCode) GetName() string {
 		return ""
 	}
 }
+
+func (m PlcResponseCode) String() string {
+	return m.GetName()
+}
diff --git a/plc4go/tests/drivers/tests/manual_cbus_driver_test.go b/plc4go/tests/drivers/tests/manual_cbus_driver_test.go
index 9e54c83e7..5242fed86 100644
--- a/plc4go/tests/drivers/tests/manual_cbus_driver_test.go
+++ b/plc4go/tests/drivers/tests/manual_cbus_driver_test.go
@@ -98,10 +98,10 @@ func TestManualCBusBrowse(t *testing.T) {
 	log.Logger = log.
 		With().Caller().Logger().
 		Output(zerolog.ConsoleWriter{Out: os.Stderr}).
-		Level(zerolog.TraceLevel)
-	config.TraceTransactionManagerWorkers = true
-	config.TraceTransactionManagerTransactions = true
-	config.TraceDefaultMessageCodecWorker = true
+		Level(zerolog.InfoLevel)
+	config.TraceTransactionManagerWorkers = false
+	config.TraceTransactionManagerTransactions = false
+	config.TraceDefaultMessageCodecWorker = false
 	t.Skip()
 
 	connectionString := "c-bus://192.168.178.101?Monitor=false&MonitoredApplication1=0x00&MonitoredApplication2=0x00"
@@ -110,7 +110,8 @@ func TestManualCBusBrowse(t *testing.T) {
 	transports.RegisterTcpTransport(driverManager)
 	connectionResult := <-driverManager.GetConnection(connectionString)
 	if err := connectionResult.GetErr(); err != nil {
-		panic(err)
+		t.Error(err)
+		t.FailNow()
 	}
 	connection := connectionResult.GetConnection()
 	defer connection.Close()
@@ -120,6 +121,9 @@ func TestManualCBusBrowse(t *testing.T) {
 	if err != nil {
 		panic(err)
 	}
-	browseRequestResult := <-browseRequest.Execute()
-	fmt.Printf("%s", browseRequestResult)
+	browseRequestResult := <-browseRequest.ExecuteWithInterceptor(func(result model.PlcBrowseEvent) bool {
+		fmt.Printf("%s", result)
+		return true
+	})
+	fmt.Printf("%s", browseRequestResult.GetResponse())
 }
diff --git a/plc4go/tools/plc4xbrowser/ui/commands.go b/plc4go/tools/plc4xbrowser/ui/commands.go
index 26fb8c191..648b61894 100644
--- a/plc4go/tools/plc4xbrowser/ui/commands.go
+++ b/plc4go/tools/plc4xbrowser/ui/commands.go
@@ -269,7 +269,11 @@ var rootCommand = Command{
 					if err != nil {
 						return errors.Wrapf(err, "%s can't browse", connectionsString)
 					}
-					browseRequestResult := <-browseRequest.Execute()
+					browseRequestResult := <-browseRequest.ExecuteWithInterceptor(func(result model.PlcBrowseEvent) bool {
+						numberOfMessagesReceived++
+						messageReceived(numberOfMessagesReceived, time.Now(), browseRequest)
+						return true
+					})
 					if err := browseRequestResult.GetErr(); err != nil {
 						return errors.Wrapf(err, "%s can't browse", connectionsString)
 					}