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/09/06 15:53:36 UTC

[plc4x] branch develop updated: fix(plc4go/cbus): try to catch installation mmi with offset 0

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 de9799660 fix(plc4go/cbus): try to catch installation mmi with offset 0
de9799660 is described below

commit de979966092ac2a82eb7e6b29ea3ad52b9d69c04
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Tue Sep 6 17:53:24 2022 +0200

    fix(plc4go/cbus): try to catch installation mmi with offset 0
    
    + this can happen sometimes so we ensure in case our read fails that we receive it via subscription
---
 plc4go/internal/cbus/Browser.go | 83 +++++++++++++++++++++++------------------
 1 file changed, 47 insertions(+), 36 deletions(-)

diff --git a/plc4go/internal/cbus/Browser.go b/plc4go/internal/cbus/Browser.go
index 7ab329db4..ea554108c 100644
--- a/plc4go/internal/cbus/Browser.go
+++ b/plc4go/internal/cbus/Browser.go
@@ -180,6 +180,8 @@ func (m Browser) getInstalledUnitAddressBytes(ctx context.Context) (map[byte]any
 		return nil, errors.Wrap(err, "Error getting the subscription handle")
 	}
 
+	blockOffset0Received := false
+	blockOffset0ReceivedChan := make(chan any, 100) // We only expect one, but we make it a bit bigger to no clog up
 	blockOffset88Received := false
 	blockOffset88ReceivedChan := make(chan any, 100) // We only expect one, but we make it a bit bigger to no clog up
 	blockOffset176Received := false
@@ -219,8 +221,10 @@ func (m Browser) getInstalledUnitAddressBytes(ctx context.Context) (map[byte]any
 			default:
 			}
 		case 0:
-			log.Debug().Msgf("We ignore 0 as we handle it with the read request below\n%v", event)
-			return
+			select {
+			case blockOffset0ReceivedChan <- true:
+			default:
+			}
 		}
 
 		if plcListValue := rootStruct["values"]; plcListValue == nil || !plcListValue.IsList() {
@@ -259,51 +263,58 @@ func (m Browser) getInstalledUnitAddressBytes(ctx context.Context) (map[byte]any
 	if err := readRequestResult.GetErr(); err != nil {
 		return nil, errors.Wrap(err, "Error reading the mmi")
 	}
-	if responseCode := readRequestResult.GetResponse().GetResponseCode("installationMMI"); responseCode != apiModel.PlcResponseCode_OK {
-		return nil, errors.Errorf("Got %s", responseCode)
-	}
-	rootValue := readRequestResult.GetResponse().GetValue("installationMMI")
-	if !rootValue.IsStruct() {
-		return nil, errors.Errorf("%v should be a struct", rootValue)
-	}
-	rootStruct := rootValue.GetStruct()
-	if applicationValue := rootStruct["application"]; applicationValue == nil || !applicationValue.IsString() || applicationValue.GetString() != "NETWORK_CONTROL" {
-		return nil, errors.Errorf("%v should contain a application field of type string with value NETWORK_CONTROL", rootStruct)
-	}
-	var blockStart int
-	if blockStartValue := rootStruct["blockStart"]; blockStartValue == nil || !blockStartValue.IsByte() || blockStartValue.GetByte() != 0 {
-		return nil, errors.Errorf("%v should contain a blockStart field of type byte with value 0", rootStruct)
-	} else {
-		blockStart = int(blockStartValue.GetByte())
-	}
+	if responseCode := readRequestResult.GetResponse().GetResponseCode("installationMMI"); responseCode == apiModel.PlcResponseCode_OK {
+		rootValue := readRequestResult.GetResponse().GetValue("installationMMI")
+		if !rootValue.IsStruct() {
+			return nil, errors.Errorf("%v should be a struct", rootValue)
+		}
+		rootStruct := rootValue.GetStruct()
+		if applicationValue := rootStruct["application"]; applicationValue == nil || !applicationValue.IsString() || applicationValue.GetString() != "NETWORK_CONTROL" {
+			return nil, errors.Errorf("%v should contain a application field of type string with value NETWORK_CONTROL", rootStruct)
+		}
+		var blockStart int
+		if blockStartValue := rootStruct["blockStart"]; blockStartValue == nil || !blockStartValue.IsByte() || blockStartValue.GetByte() != 0 {
+			return nil, errors.Errorf("%v should contain a blockStart field of type byte with value 0", rootStruct)
+		} else {
+			blockStart = int(blockStartValue.GetByte())
+		}
 
-	if plcListValue := rootStruct["values"]; plcListValue == nil || !plcListValue.IsList() {
-		return nil, errors.Errorf("%v should contain a values field of type list", rootStruct)
-	} else {
-		for unitByteAddress, plcValue := range plcListValue.GetList() {
-			unitByteAddress = blockStart + unitByteAddress
-			if !plcValue.IsString() {
-				return nil, errors.Errorf("%v at %d should be a string", plcValue, unitByteAddress)
-			}
-			switch plcValue.GetString() {
-			case readWriteModel.GAVState_ON.PLC4XEnumName(), readWriteModel.GAVState_OFF.PLC4XEnumName():
-				log.Debug().Msgf("unit %d does exists", unitByteAddress)
-				result[byte(unitByteAddress)] = true
-			case readWriteModel.GAVState_DOES_NOT_EXIST.PLC4XEnumName():
-				log.Debug().Msgf("unit %d does not exists", unitByteAddress)
-			case readWriteModel.GAVState_ERROR.PLC4XEnumName():
-				log.Warn().Msgf("unit %d is in error state", unitByteAddress)
+		if plcListValue := rootStruct["values"]; plcListValue == nil || !plcListValue.IsList() {
+			return nil, errors.Errorf("%v should contain a values field of type list", rootStruct)
+		} else {
+			for unitByteAddress, plcValue := range plcListValue.GetList() {
+				unitByteAddress = blockStart + unitByteAddress
+				if !plcValue.IsString() {
+					return nil, errors.Errorf("%v at %d should be a string", plcValue, unitByteAddress)
+				}
+				switch plcValue.GetString() {
+				case readWriteModel.GAVState_ON.PLC4XEnumName(), readWriteModel.GAVState_OFF.PLC4XEnumName():
+					log.Debug().Msgf("unit %d does exists", unitByteAddress)
+					result[byte(unitByteAddress)] = true
+				case readWriteModel.GAVState_DOES_NOT_EXIST.PLC4XEnumName():
+					log.Debug().Msgf("unit %d does not exists", unitByteAddress)
+				case readWriteModel.GAVState_ERROR.PLC4XEnumName():
+					log.Warn().Msgf("unit %d is in error state", unitByteAddress)
+				}
 			}
 		}
+		blockOffset0Received = true
+	} else {
+		log.Warn().Msgf("We got %s as response code for installation mmi so we rely on getting it via subscription", responseCode)
 	}
 
 	syncCtx, syncCtxCancel := context.WithTimeout(ctx, time.Second*2)
 	defer syncCtxCancel()
-	for !blockOffset88Received || !blockOffset176Received {
+	for !blockOffset0Received || !blockOffset88Received || !blockOffset176Received {
 		select {
+		case <-blockOffset0ReceivedChan:
+			log.Trace().Msg("Offset 0 received")
+			blockOffset0Received = true
 		case <-blockOffset88ReceivedChan:
+			log.Trace().Msg("Offset 88 received")
 			blockOffset88Received = true
 		case <-blockOffset176ReceivedChan:
+			log.Trace().Msg("Offset 176 received")
 			blockOffset176Received = true
 		case <-syncCtx.Done():
 			return nil, errors.Wrap(err, "error waiting for other offsets")