Skip to content

Commit

Permalink
python: Add direct attribute paths to Read
Browse files Browse the repository at this point in the history
Supports one particular use case: read one or all endpoints,
all clusters, specific (global) attribute. See spec 8.9.2.4. This
is an allowed wildcard construct that is not currently expressable
in the API.

Test: Used on wildcard read for matter_testing_support. This is
      therefore tested on any test using that decorator - switch
      and timesync.
  • Loading branch information
cecille committed Aug 7, 2024
1 parent 7d9a332 commit a60ad8b
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 4 deletions.
18 changes: 15 additions & 3 deletions src/controller/python/chip/ChipDeviceCtrl.py
Original file line number Diff line number Diff line change
Expand Up @@ -1351,8 +1351,12 @@ def _parseAttributePathTuple(self, pathTuple: typing.Union[
# Wildcard attribute id
typing.Tuple[int, typing.Type[ClusterObjects.Cluster]],
# Concrete path
typing.Tuple[int, typing.Type[ClusterObjects.ClusterAttributeDescriptor]]
typing.Tuple[int, typing.Type[ClusterObjects.ClusterAttributeDescriptor]],
# Directly specified attribute path
ClusterAttribute.AttributePath
]):
if isinstance(pathTuple, ClusterAttribute.AttributePath):
return pathTuple
if pathTuple == ('*') or pathTuple == ():
# Wildcard
return ClusterAttribute.AttributePath()
Expand Down Expand Up @@ -1437,7 +1441,9 @@ async def Read(self, nodeid: int, attributes: typing.Optional[typing.List[typing
# Wildcard attribute id
typing.Tuple[int, typing.Type[ClusterObjects.Cluster]],
# Concrete path
typing.Tuple[int, typing.Type[ClusterObjects.ClusterAttributeDescriptor]]
typing.Tuple[int, typing.Type[ClusterObjects.ClusterAttributeDescriptor]],
# Directly specified attribute path
ClusterAttribute.AttributePath
]]] = None,
dataVersionFilters: typing.Optional[typing.List[typing.Tuple[int, typing.Type[ClusterObjects.Cluster], int]]] = None, events: typing.Optional[typing.List[
typing.Union[
Expand Down Expand Up @@ -1476,6 +1482,8 @@ async def Read(self, nodeid: int, attributes: typing.Optional[typing.List[typing
ReadAttribute(1, [ Clusters.BasicInformation ] ) -- case 5 above.
ReadAttribute(1, [ (1, Clusters.BasicInformation.Attributes.Location ] ) -- case 1 above.
An AttributePath can also be specified directly by [chip.cluster.Attribute.AttributePath(...)]
dataVersionFilters: A list of tuples of (endpoint, cluster, data version).
events: A list of tuples of varying types depending on the type of read being requested:
Expand Down Expand Up @@ -1543,7 +1551,9 @@ async def ReadAttribute(self, nodeid: int, attributes: typing.Optional[typing.Li
# Wildcard attribute id
typing.Tuple[int, typing.Type[ClusterObjects.Cluster]],
# Concrete path
typing.Tuple[int, typing.Type[ClusterObjects.ClusterAttributeDescriptor]]
typing.Tuple[int, typing.Type[ClusterObjects.ClusterAttributeDescriptor]],
# Directly specified attribute path
ClusterAttribute.AttributePath
]]], dataVersionFilters: typing.Optional[typing.List[typing.Tuple[int, typing.Type[ClusterObjects.Cluster], int]]] = None,
returnClusterObject: bool = False,
reportInterval: typing.Optional[typing.Tuple[int, int]] = None,
Expand All @@ -1568,6 +1578,8 @@ async def ReadAttribute(self, nodeid: int, attributes: typing.Optional[typing.Li
ReadAttribute(1, [ Clusters.BasicInformation ] ) -- case 5 above.
ReadAttribute(1, [ (1, Clusters.BasicInformation.Attributes.Location ] ) -- case 1 above.
An AttributePath can also be specified directly by [chip.cluster.Attribute.AttributePath(...)]
returnClusterObject: This returns the data as consolidated cluster objects, with all attributes for a cluster inside
a single cluster-wide cluster object.
Expand Down
3 changes: 2 additions & 1 deletion src/python_testing/matter_testing_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@

# isort: on
import chip.clusters as Clusters
from chip.clusters import Attribute
import chip.logging
import chip.native
from chip import discovery
Expand Down Expand Up @@ -1863,7 +1864,7 @@ async def get_accepted_endpoints_for_test(self: MatterBaseTest, accept_function:
Returns a list of endpoints on which the test should be run given the accept_function for the test.
"""
wildcard = await self.default_controller.Read(self.dut_node_id, [()])
wildcard = await self.default_controller.Read(self.dut_node_id, [(Clusters.Descriptor), Attribute.AttributePath(None, None, GlobalAttributeIds.ATTRIBUTE_LIST_ID), Attribute.AttributePath(None, None, GlobalAttributeIds.FEATURE_MAP_ID), Attribute.AttributePath(None, None, GlobalAttributeIds.ACCEPTED_COMMAND_LIST_ID)])
return [e for e in wildcard.attributes.keys() if accept_function(wildcard, e)]


Expand Down

0 comments on commit a60ad8b

Please sign in to comment.