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/28 15:46:39 UTC

[plc4x] 03/03: feat(plc4go/cbus): properly map binary and level status responses to plcValue

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 2bd067a5eaf90753db364c2331b874a899aa6bbd
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Thu Jul 28 17:46:08 2022 +0200

    feat(plc4go/cbus): properly map binary and level status responses to plcValue
---
 plc4go/internal/cbus/Reader.go                     | 54 ++++++++++++++++------
 plc4go/internal/spi/values/BINT.go                 |  1 +
 plc4go/internal/spi/values/PlcList.go              |  9 ++++
 .../tests/drivers/tests/manual_cbus_driver_test.go |  4 +-
 4 files changed, 51 insertions(+), 17 deletions(-)

diff --git a/plc4go/internal/cbus/Reader.go b/plc4go/internal/cbus/Reader.go
index ccab01381..d54b4f7b9 100644
--- a/plc4go/internal/cbus/Reader.go
+++ b/plc4go/internal/cbus/Reader.go
@@ -22,8 +22,8 @@ package cbus
 import (
 	"fmt"
 	"github.com/apache/plc4x/plc4go/internal/spi"
-	plc4goModel "github.com/apache/plc4x/plc4go/internal/spi/model"
-	values2 "github.com/apache/plc4x/plc4go/internal/spi/values"
+	spiModel "github.com/apache/plc4x/plc4go/internal/spi/model"
+	spiValues "github.com/apache/plc4x/plc4go/internal/spi/values"
 	"github.com/apache/plc4x/plc4go/pkg/api/model"
 	"github.com/apache/plc4x/plc4go/pkg/api/values"
 	readWriteModel "github.com/apache/plc4x/plc4go/protocols/cbus/readwrite/model"
@@ -53,7 +53,7 @@ func (m *Reader) Read(readRequest model.PlcReadRequest) <-chan model.PlcReadRequ
 	go func() {
 		numFields := len(readRequest.GetFieldNames())
 		if numFields > 20 {
-			result <- &plc4goModel.DefaultPlcReadRequestResult{
+			result <- &spiModel.DefaultPlcReadRequestResult{
 				Request:  readRequest,
 				Response: nil,
 				Err:      errors.New("Only 20 fields can be handled at once"),
@@ -65,7 +65,7 @@ func (m *Reader) Read(readRequest model.PlcReadRequest) <-chan model.PlcReadRequ
 			field := readRequest.GetField(fieldName)
 			message, err := m.fieldToCBusMessage(field)
 			if err != nil {
-				result <- &plc4goModel.DefaultPlcReadRequestResult{
+				result <- &spiModel.DefaultPlcReadRequestResult{
 					Request:  readRequest,
 					Response: nil,
 					Err:      errors.Wrapf(err, "Error encoding cbus message for field %s", fieldName),
@@ -83,10 +83,10 @@ func (m *Reader) Read(readRequest model.PlcReadRequest) <-chan model.PlcReadRequ
 		}
 		valueMu := sync.Mutex{}
 		plcValues := map[string]values.PlcValue{}
-		addPlcValue := func(name string, responseCode values.PlcValue) {
+		addPlcValue := func(name string, plcValue values.PlcValue) {
 			valueMu.Lock()
 			defer valueMu.Unlock()
-			plcValues[name] = responseCode
+			plcValues[name] = plcValue
 		}
 		for fieldName, messageToSend := range messages {
 			fieldNameCopy := fieldName
@@ -151,8 +151,14 @@ func (m *Reader) Read(readRequest model.PlcReadRequest) <-chan model.PlcReadRequ
 							_ = blockStart
 							statusBytes := reply.GetReply().GetStatusBytes()
 							addResponseCode(fieldNameCopy, model.PlcResponseCode_OK)
-							// TODO: how should we serialize that???
-							addPlcValue(fieldNameCopy, values2.NewPlcSTRING(fmt.Sprintf("%s", statusBytes)))
+							plcListValues := make([]values.PlcValue, len(statusBytes)*4)
+							for i, statusByte := range statusBytes {
+								plcListValues[i*4+0] = spiValues.NewPlcSTRING(statusByte.GetGav0().String())
+								plcListValues[i*4+1] = spiValues.NewPlcSTRING(statusByte.GetGav1().String())
+								plcListValues[i*4+2] = spiValues.NewPlcSTRING(statusByte.GetGav2().String())
+								plcListValues[i*4+3] = spiValues.NewPlcSTRING(statusByte.GetGav3().String())
+							}
+							addPlcValue(fieldNameCopy, spiValues.NewPlcList(plcListValues))
 						case readWriteModel.EncodedReplyExtendedFormatStatusReplyExactly:
 							coding := reply.GetReply().GetCoding()
 							// TODO: verify coding... this should be the same
@@ -169,21 +175,39 @@ func (m *Reader) Read(readRequest model.PlcReadRequest) <-chan model.PlcReadRequ
 							case readWriteModel.StatusCoding_BINARY_BY_ELSEWHERE:
 								statusBytes := reply.GetReply().GetStatusBytes()
 								addResponseCode(fieldNameCopy, model.PlcResponseCode_OK)
-								// TODO: how should we serialize that???
-								addPlcValue(fieldNameCopy, values2.NewPlcSTRING(fmt.Sprintf("%s", statusBytes)))
+								plcListValues := make([]values.PlcValue, len(statusBytes)*4)
+								for i, statusByte := range statusBytes {
+									plcListValues[i*4+0] = spiValues.NewPlcSTRING(statusByte.GetGav0().String())
+									plcListValues[i*4+1] = spiValues.NewPlcSTRING(statusByte.GetGav1().String())
+									plcListValues[i*4+2] = spiValues.NewPlcSTRING(statusByte.GetGav2().String())
+									plcListValues[i*4+3] = spiValues.NewPlcSTRING(statusByte.GetGav3().String())
+								}
+								addPlcValue(fieldNameCopy, spiValues.NewPlcList(plcListValues))
 							case readWriteModel.StatusCoding_LEVEL_BY_THIS_SERIAL_INTERFACE:
 								fallthrough
 							case readWriteModel.StatusCoding_LEVEL_BY_ELSEWHERE:
 								levelInformation := reply.GetReply().GetLevelInformation()
 								addResponseCode(fieldNameCopy, model.PlcResponseCode_OK)
-								// TODO: how should we serialize that???
-								addPlcValue(fieldNameCopy, values2.NewPlcSTRING(fmt.Sprintf("%s", levelInformation)))
+								plcListValues := make([]values.PlcValue, len(levelInformation))
+								for i, levelInformation := range levelInformation {
+									switch levelInformation := levelInformation.(type) {
+									case readWriteModel.LevelInformationAbsentExactly:
+										plcListValues[i] = spiValues.NewPlcSTRING("is absent")
+									case readWriteModel.LevelInformationCorruptedExactly:
+										plcListValues[i] = spiValues.NewPlcSTRING("corrupted")
+									case readWriteModel.LevelInformationNormalExactly:
+										plcListValues[i] = spiValues.NewPlcUSINT(levelInformation.GetActualLevel())
+									default:
+										panic("Impossible case")
+									}
+								}
+								addPlcValue(fieldNameCopy, spiValues.NewPlcList(plcListValues))
 							}
 						case readWriteModel.EncodedReplyCALReplyExactly:
 							calData := reply.GetCalReply().GetCalData()
 							addResponseCode(fieldNameCopy, model.PlcResponseCode_OK)
 							// TODO: how should we serialize that???
-							addPlcValue(fieldNameCopy, values2.NewPlcSTRING(fmt.Sprintf("%s", calData)))
+							addPlcValue(fieldNameCopy, spiValues.NewPlcSTRING(fmt.Sprintf("%s", calData)))
 						}
 						requestWasOk <- true
 						return transaction.EndRequest()
@@ -207,8 +231,8 @@ func (m *Reader) Read(readRequest model.PlcReadRequest) <-chan model.PlcReadRequ
 				break
 			}
 		}
-		readResponse := plc4goModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues)
-		result <- &plc4goModel.DefaultPlcReadRequestResult{
+		readResponse := spiModel.NewDefaultPlcReadResponse(readRequest, responseCodes, plcValues)
+		result <- &spiModel.DefaultPlcReadRequestResult{
 			Request:  readRequest,
 			Response: readResponse,
 		}
diff --git a/plc4go/internal/spi/values/BINT.go b/plc4go/internal/spi/values/BINT.go
index 2d6587399..522ddadc5 100644
--- a/plc4go/internal/spi/values/BINT.go
+++ b/plc4go/internal/spi/values/BINT.go
@@ -125,6 +125,7 @@ func (m PlcBINT) GetFloat64() float64 {
 func (m PlcBINT) GetString() string {
 	return strconv.Itoa(int(m.GetInt64()))
 }
+
 func (m PlcBINT) isZero() bool {
 	return m.value.Cmp(big.NewInt(0)) == 0
 }
diff --git a/plc4go/internal/spi/values/PlcList.go b/plc4go/internal/spi/values/PlcList.go
index e561b5053..bdbe9dbb5 100644
--- a/plc4go/internal/spi/values/PlcList.go
+++ b/plc4go/internal/spi/values/PlcList.go
@@ -23,6 +23,7 @@ import (
 	"github.com/apache/plc4x/plc4go/internal/spi/utils"
 	"github.com/apache/plc4x/plc4go/pkg/api/values"
 	"github.com/pkg/errors"
+	"strings"
 )
 
 type PlcList struct {
@@ -58,6 +59,14 @@ func (m PlcList) GetList() []values.PlcValue {
 	return m.Values
 }
 
+func (m PlcList) GetString() string {
+	stringValues := make([]string, len(m.Values))
+	for i, v := range m.Values {
+		stringValues[i] = v.GetString()
+	}
+	return strings.Join(stringValues, ", ")
+}
+
 func (m PlcList) Serialize(writeBuffer utils.WriteBuffer) error {
 	if err := writeBuffer.PushContext("PlcList"); err != nil {
 		return err
diff --git a/plc4go/tests/drivers/tests/manual_cbus_driver_test.go b/plc4go/tests/drivers/tests/manual_cbus_driver_test.go
index 153568410..00100d227 100644
--- a/plc4go/tests/drivers/tests/manual_cbus_driver_test.go
+++ b/plc4go/tests/drivers/tests/manual_cbus_driver_test.go
@@ -37,8 +37,8 @@ func TestManualCBusDriver(t *testing.T) {
 	transports.RegisterTcpTransport(driverManager)
 	test := testutils.NewManualTestSuite(connectionString, driverManager, t)
 
-	test.AddTestCase("status/binary/0x04", true)
-	test.AddTestCase("status/level=0x40/0x04", true)
+	test.AddTestCase("status/binary/0x04", "DOES_NOT_EXIST, OFF, ERROR, ON")
+	test.AddTestCase("status/level=0x40/0x04", 255)
 	//test.AddTestCase("cal/0/recall=[INTERFACE_OPTIONS_1, 1]", true)
 	//test.AddTestCase("cal/0/identify=[FirmwareVersion]", true)
 	//test.AddTestCase("cal/0/gestatus=[0xFF, 1]", true)