Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Python] Add lookup dictionaries for clusters and attributes #26121

Merged
merged 8 commits into from
May 5, 2023
32 changes: 32 additions & 0 deletions src/controller/python/chip/clusters/ClusterObjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,12 @@ def must_use_timed_invoke(cls) -> bool:
return False


# The below dictionaries will be filled dynamically
# and are used for quick lookup/mapping from cluster/attribute id to the correct class
ALL_CLUSTERS = {}
ALL_ATTRIBUTES = {}


class Cluster(ClusterObject):
'''
When send read requests with returnClusterObject=True, we will set the data_version property of the object.
Expand All @@ -228,6 +234,18 @@ class Cluster(ClusterObject):
especially the TLV decoding logic. Also ThreadNetworkDiagnostics has an attribute with the same name so we
picked data_version as its name.
'''

def __init_subclass__(cls, *args, **kwargs) -> None:
"""Register a subclass."""
super().__init_subclass__(*args, **kwargs)
# register this cluster in the ALL_CLUSTERS dict for quick lookups
try:
ALL_CLUSTERS[cls.id] = cls
except NotImplementedError:
# handle case where the Cluster class is not (fully) subclassed
# and accessing the id property throws a NotImplementedError.
pass

@property
def data_version(self) -> int:
return self._data_version
Expand All @@ -254,6 +272,20 @@ class ClusterAttributeDescriptor:

The implementation of this functions is quite tricky, it will create a cluster object on-the-fly, and use it for actual encode / decode routine to save lines of code.
'''

def __init_subclass__(cls, *args, **kwargs) -> None:
"""Register a subclass."""
super().__init_subclass__(*args, **kwargs)
try:
if cls.cluster_id not in ALL_ATTRIBUTES:
ALL_ATTRIBUTES[cls.cluster_id] = {}
# register this clusterattribute in the ALL_ATTRIBUTES dict for quick lookups
ALL_ATTRIBUTES[cls.cluster_id][cls.attribute_id] = cls
except NotImplementedError:
# handle case where the ClusterAttribute class is not (fully) subclassed
# and accessing the id property throws a NotImplementedError.
pass
bzbarsky-apple marked this conversation as resolved.
Show resolved Hide resolved

@classmethod
def ToTLV(cls, tag: Union[int, None], value):
writer = tlv.TLVWriter()
Expand Down