You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2021/03/03 15:27:35 UTC

[plc4x] branch develop updated: - Added an example for subscriptions in KNX - Fixed the code in KNX subscriptions to work if no datatype was provided

This is an automated email from the ASF dual-hosted git repository.

cdutz 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 ae74837  - Added an example for subscriptions in KNX - Fixed the code in KNX subscriptions to work if no datatype was provided
ae74837 is described below

commit ae748376f1b580f2a06c64237da26fe2942f36ff
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Wed Mar 3 16:25:27 2021 +0100

    - Added an example for subscriptions in KNX
    - Fixed the code in KNX subscriptions to work if no datatype was provided
---
 .../discovery/hello_world_plc4go_knx_discovery.go  |  4 +--
 .../hello_world_plc4go_knx_read_group_address.go   |  4 ++-
 .../hello_world_plc4go_knx_subscription.go}        | 34 ++++++++++----------
 plc4go/internal/plc4go/knxnetip/KnxNetIpBrowser.go | 36 +++++-----------------
 .../internal/plc4go/knxnetip/KnxNetIpSubscriber.go | 36 +++++++++++++++++-----
 plc4go/internal/plc4go/spi/values/PlcList.go       |  2 +-
 6 files changed, 57 insertions(+), 59 deletions(-)

diff --git a/plc4go/examples/knx/discovery/hello_world_plc4go_knx_discovery.go b/plc4go/examples/knx/discovery/hello_world_plc4go_knx_discovery.go
index d81a2b0..6cd1147 100644
--- a/plc4go/examples/knx/discovery/hello_world_plc4go_knx_discovery.go
+++ b/plc4go/examples/knx/discovery/hello_world_plc4go_knx_discovery.go
@@ -55,8 +55,8 @@ func main() {
 		// Try to find all KNX devices on the current network
 		browseRequestBuilder := connection.BrowseRequestBuilder()
 		//browseRequestBuilder.AddItem("allDevices", "[1-15].[1-15].[0-255]")
-		browseRequestBuilder.AddItem("allMyDevices", "[1-3].[1-6].[0-60]")
-		//browseRequestBuilder.AddItem("onlyOneDevice", "1.1.5")
+		//browseRequestBuilder.AddItem("allMyDevices", "[1-3].[1-6].[0-60]")
+		browseRequestBuilder.AddItem("onlyOneDevice", "1.1.20")
 		browseRequest, err := browseRequestBuilder.Build()
 		if err != nil {
 			log.Errorf("error creating browse request: %s", err.Error())
diff --git a/plc4go/examples/knx/groupAddressRead/hello_world_plc4go_knx_read_group_address.go b/plc4go/examples/knx/groupAddressRead/hello_world_plc4go_knx_read_group_address.go
index 99ddf9d..c922c27 100644
--- a/plc4go/examples/knx/groupAddressRead/hello_world_plc4go_knx_read_group_address.go
+++ b/plc4go/examples/knx/groupAddressRead/hello_world_plc4go_knx_read_group_address.go
@@ -73,7 +73,9 @@ func main() {
 		}
 
 		value := rrr.Response.GetValue(fieldName)
-		if value.GetStruct() != nil {
+		if value != nil {
+			fmt.Printf("Got nil for field %s\n", fieldName)
+		} else if value.GetStruct() != nil {
 			for address, structValue := range value.GetStruct() {
 				fmt.Printf("Got result for field %s with address: %s: %s °C\n", fieldName, address, structValue.GetString())
 			}
diff --git a/plc4go/examples/knx/groupAddressRead/hello_world_plc4go_knx_read_group_address.go b/plc4go/examples/knx/subscribe/hello_world_plc4go_knx_subscription.go
similarity index 72%
copy from plc4go/examples/knx/groupAddressRead/hello_world_plc4go_knx_read_group_address.go
copy to plc4go/examples/knx/subscribe/hello_world_plc4go_knx_subscription.go
index 99ddf9d..6b9b645 100644
--- a/plc4go/examples/knx/groupAddressRead/hello_world_plc4go_knx_read_group_address.go
+++ b/plc4go/examples/knx/subscribe/hello_world_plc4go_knx_subscription.go
@@ -24,6 +24,7 @@ import (
 	"github.com/apache/plc4x/plc4go/pkg/plc4go/drivers"
 	"github.com/apache/plc4x/plc4go/pkg/plc4go/model"
 	"github.com/apache/plc4x/plc4go/pkg/plc4go/transports"
+	"time"
 )
 
 func main() {
@@ -45,23 +46,27 @@ func main() {
 	// Make sure the connection is closed at the end
 	defer connection.BlockingClose()
 
-	// Prepare a read-request
-	rrb := connection.ReadRequestBuilder()
-	rrb.AddQuery("firstFlorTemperatures", "2/[1,2,4,6]/10:DPT_Value_Temp")
-	rrb.AddQuery("secondFlorTemperatures", "3/[2,3,4,6]/10:DPT_Value_Temp")
-	readRequest, err := rrb.Build()
+	// Prepare a subscription-request
+	srb := connection.SubscriptionRequestBuilder()
+	//	srb.AddChangeOfStateQuery("all", "*/*/*")
+	srb.AddChangeOfStateQuery("firstFlorTemperatures", "2/[1,2,4,6]/10:DPT_Value_Temp")
+	srb.AddChangeOfStateQuery("secondFlorTemperatures", "3/[2,3,4,6]/10:DPT_Value_Temp")
+	srb.AddItemHandler(func(event model.PlcSubscriptionEvent) {
+		fmt.Printf("Got event %v\n", event)
+	})
+	subscriptionRequest, err := srb.Build()
 	if err != nil {
-		fmt.Printf("error preparing read-request: %s", connectionResult.Err.Error())
+		fmt.Printf("error preparing subscription-request: %s", connectionResult.Err.Error())
 		return
 	}
 
-	// Execute a read-request
-	rrc := readRequest.Execute()
+	// Execute a subscription-request
+	rrc := subscriptionRequest.Execute()
 
 	// Wait for the response to finish
 	rrr := <-rrc
 	if rrr.Err != nil {
-		fmt.Printf("error executing read-request: %s", rrr.Err.Error())
+		fmt.Printf("error executing subscription-request: %s", rrr.Err.Error())
 		return
 	}
 
@@ -71,14 +76,7 @@ func main() {
 			fmt.Printf("error an non-ok return code for field %s: %s\n", fieldName, rrr.Response.GetResponseCode(fieldName).GetName())
 			continue
 		}
-
-		value := rrr.Response.GetValue(fieldName)
-		if value.GetStruct() != nil {
-			for address, structValue := range value.GetStruct() {
-				fmt.Printf("Got result for field %s with address: %s: %s °C\n", fieldName, address, structValue.GetString())
-			}
-		} else {
-			fmt.Printf("Got result for field %s: %s °C\n", fieldName, value.GetString())
-		}
 	}
+
+	time.Sleep(time.Minute * 5)
 }
diff --git a/plc4go/internal/plc4go/knxnetip/KnxNetIpBrowser.go b/plc4go/internal/plc4go/knxnetip/KnxNetIpBrowser.go
index b8e49d2..96b204a 100644
--- a/plc4go/internal/plc4go/knxnetip/KnxNetIpBrowser.go
+++ b/plc4go/internal/plc4go/knxnetip/KnxNetIpBrowser.go
@@ -504,32 +504,6 @@ func (b KnxNetIpBrowser) executeCommunicationObjectQuery(field KnxNetIpCommunica
 				})
 			}
 		}
-		// da 0700
-		// 0:07db1300 1:07dc4300 2:07dd1300 3:07de1300 4:07df1300
-		// 5:07e01300 6:07e11300 7:07e21300 8:07e31300 9:07e40b0a
-		// 10: 07e81700 07e91300 07ea1300 07eb1300 07ec1300
-		// 07ed1307 07ee1307 07ef4307 07f04300 07f11308
-		// 07f31300 07f44308 07f64300 07f71300 07
-		//
-		/*
-		   106: 856177
-		   184: 8B0177
-		   36: 86170
-		   166: 89C170
-		   132: 874177
-		   80: 838177
-		   88: 842170
-		   158: 892177
-		   210: 8CE177
-		   62: 824170
-		   10: 7E8170
-		   192: 8BA170
-		   114: 860170
-		   28: 7FC177
-		   140: 87E170
-		   54: 81A177
-
-		*/
 	} else {
 		readRequestBuilder = b.connection.ReadRequestBuilder()
 		readRequestBuilder.AddQuery("comObjectTableAddress", fmt.Sprintf("%s#3/7", knxAddressString))
@@ -692,18 +666,22 @@ func (m KnxNetIpBrowser) getFieldTypeForValueType(valueType driverModel.ComObjec
 	case driverModel.ComObjectValueType_BYTE1:
 		return driverModel.KnxDatapointType_USINT
 	case driverModel.ComObjectValueType_BYTE2:
-		return driverModel.KnxDatapointType_USINT
+		return driverModel.KnxDatapointType_UINT
 	case driverModel.ComObjectValueType_BYTE3:
-		return driverModel.KnxDatapointType_USINT
+		return driverModel.KnxDatapointType_UDINT
 	case driverModel.ComObjectValueType_BYTE4:
 		return driverModel.KnxDatapointType_UDINT
 	case driverModel.ComObjectValueType_BYTE6:
+		// Will be an array
 		return driverModel.KnxDatapointType_USINT
 	case driverModel.ComObjectValueType_BYTE8:
-		return driverModel.KnxDatapointType_ULINT
+		// Will be an array
+		return driverModel.KnxDatapointType_USINT
 	case driverModel.ComObjectValueType_BYTE10:
+		// Will be an array
 		return driverModel.KnxDatapointType_USINT
 	case driverModel.ComObjectValueType_BYTE14:
+		// Will be an array
 		return driverModel.KnxDatapointType_USINT
 	}
 	// Just return "byte" in any other case.
diff --git a/plc4go/internal/plc4go/knxnetip/KnxNetIpSubscriber.go b/plc4go/internal/plc4go/knxnetip/KnxNetIpSubscriber.go
index 4a530de..2b39375 100644
--- a/plc4go/internal/plc4go/knxnetip/KnxNetIpSubscriber.go
+++ b/plc4go/internal/plc4go/knxnetip/KnxNetIpSubscriber.go
@@ -23,6 +23,7 @@ import (
 	"github.com/apache/plc4x/plc4go/internal/plc4go/spi"
 	internalModel "github.com/apache/plc4x/plc4go/internal/plc4go/spi/model"
 	"github.com/apache/plc4x/plc4go/internal/plc4go/spi/utils"
+	values2 "github.com/apache/plc4x/plc4go/internal/plc4go/spi/values"
 	apiModel "github.com/apache/plc4x/plc4go/pkg/plc4go/model"
 	"github.com/apache/plc4x/plc4go/pkg/plc4go/values"
 	"time"
@@ -120,18 +121,37 @@ func (m *KnxNetIpSubscriber) handleValueChange(destinationAddress []int8, payloa
 						if groupAddressField.GetFieldType().LengthInBits() > 6 {
 							_, _ = rb.ReadUint8(8)
 						}
-						plcValue, err2 := driverModel.KnxDatapointParse(rb, *groupAddressField.GetFieldType())
+						elementType := *groupAddressField.GetFieldType()
+						numElements := groupAddressField.GetQuantity()
+						if elementType == driverModel.KnxDatapointType_DPT_UNKNOWN {
+							elementType = driverModel.KnxDatapointType_BYTE
+							numElements = uint16(rb.GetTotalBytes()) - rb.GetPos()
+						}
+
 						fields[fieldName] = field
 						types[fieldName] = subscriptionRequest.GetType(fieldName)
 						intervals[fieldName] = subscriptionRequest.GetInterval(fieldName)
 						addresses[fieldName] = destinationAddress
-						if err2 == nil {
-							responseCodes[fieldName] = apiModel.PlcResponseCode_OK
-							plcValues[fieldName] = plcValue
-						} else {
-							// TODO: Do a little more here ...
-							responseCodes[fieldName] = apiModel.PlcResponseCode_INTERNAL_ERROR
-							plcValues[fieldName] = nil
+
+						var values []values.PlcValue
+						responseCode := apiModel.PlcResponseCode_OK
+						for i := uint16(0); i < numElements; i++ {
+							plcValue, err2 := driverModel.KnxDatapointParse(rb, elementType)
+							if err2 == nil {
+								values = append(values, plcValue)
+							} else {
+								// TODO: Do a little more here ...
+								responseCode = apiModel.PlcResponseCode_INTERNAL_ERROR
+								break
+							}
+						}
+						responseCodes[fieldName] = responseCode
+						if responseCode == apiModel.PlcResponseCode_OK {
+							if len(values) == 1 {
+								plcValues[fieldName] = values[0]
+							} else {
+								plcValues[fieldName] = values2.NewPlcList(values)
+							}
 						}
 					}
 				}
diff --git a/plc4go/internal/plc4go/spi/values/PlcList.go b/plc4go/internal/plc4go/spi/values/PlcList.go
index bfe4dbf..afcebaa 100644
--- a/plc4go/internal/plc4go/spi/values/PlcList.go
+++ b/plc4go/internal/plc4go/spi/values/PlcList.go
@@ -28,7 +28,7 @@ type PlcList struct {
 	PlcValueAdapter
 }
 
-func NewPlcList(values []api.PlcValue) PlcList {
+func NewPlcList(values []api.PlcValue) api.PlcValue {
 	return PlcList{
 		Values: values,
 	}