From b121f0773f6e22d3cea64c11d97cf8c91095493c Mon Sep 17 00:00:00 2001 From: cecille Date: Wed, 18 Sep 2024 15:46:45 -0400 Subject: [PATCH 1/4] add an ALL_EVENTS --- .../python/chip/clusters/ClusterObjects.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/controller/python/chip/clusters/ClusterObjects.py b/src/controller/python/chip/clusters/ClusterObjects.py index ddafe87bf2c89d..c6316e07cb19c6 100644 --- a/src/controller/python/chip/clusters/ClusterObjects.py +++ b/src/controller/python/chip/clusters/ClusterObjects.py @@ -214,6 +214,7 @@ def descriptor(cls): # These need to be separate because there can be overlap in command ids for commands and responses. ALL_ACCEPTED_COMMANDS: typing.Dict = {} ALL_GENERATED_COMMANDS: typing.Dict = {} +ALL_EVENTS: typing.Dict = {} class ClusterCommand(ClusterObject): @@ -369,6 +370,19 @@ def _cluster_object(cls) -> ClusterObject: class ClusterEvent(ClusterObject): + def __init_subclass__(cls, *args, **kwargs) -> None: + """Register a subclass.""" + super().__init_subclass__(*args, **kwargs) + try: + if cls.event_id not in ALL_EVENTS: + ALL_EVENTS[cls.event_id] = {} + # register this clusterattribute in the ALL_ATTRIBUTES dict for quick lookups + ALL_EVENTS[cls.cluster_id][cls.event_id] = cls + except NotImplementedError: + # handle case where the ClusterAttribute class is not (fully) subclassed + # and accessing the id property throws a NotImplementedError. + pass + @ChipUtility.classproperty def cluster_id(self) -> int: raise NotImplementedError() From 3e564bf705720c7646506fd795b38814d193bc3a Mon Sep 17 00:00:00 2001 From: cecille Date: Mon, 7 Oct 2024 13:22:35 -0400 Subject: [PATCH 2/4] But do it correctly --- src/controller/python/chip/clusters/ClusterObjects.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/controller/python/chip/clusters/ClusterObjects.py b/src/controller/python/chip/clusters/ClusterObjects.py index c6316e07cb19c6..c0a0adec1ccacb 100644 --- a/src/controller/python/chip/clusters/ClusterObjects.py +++ b/src/controller/python/chip/clusters/ClusterObjects.py @@ -374,8 +374,8 @@ def __init_subclass__(cls, *args, **kwargs) -> None: """Register a subclass.""" super().__init_subclass__(*args, **kwargs) try: - if cls.event_id not in ALL_EVENTS: - ALL_EVENTS[cls.event_id] = {} + if cls.cluster_id not in ALL_EVENTS: + ALL_EVENTS[cls.cluster_id] = {} # register this clusterattribute in the ALL_ATTRIBUTES dict for quick lookups ALL_EVENTS[cls.cluster_id][cls.event_id] = cls except NotImplementedError: From c6eda61d4893c3a4d5611c72ab93fb5ce7866b81 Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Fri, 18 Oct 2024 13:41:46 -0400 Subject: [PATCH 3/4] Remove try: except: and let badly subclassed items fail --- .../python/chip/clusters/ClusterObjects.py | 36 ++++++------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/src/controller/python/chip/clusters/ClusterObjects.py b/src/controller/python/chip/clusters/ClusterObjects.py index c0a0adec1ccacb..beb490c631ab50 100644 --- a/src/controller/python/chip/clusters/ClusterObjects.py +++ b/src/controller/python/chip/clusters/ClusterObjects.py @@ -262,12 +262,7 @@ 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 + ALL_CLUSTERS[cls.id] = cls @property def data_version(self) -> int: @@ -301,16 +296,11 @@ class ClusterAttributeDescriptor: def __init_subclass__(cls, *args, **kwargs) -> None: """Register a subclass.""" super().__init_subclass__(*args, **kwargs) - try: - if cls.standard_attribute: - 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 + if cls.standard_attribute: + 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 @classmethod def ToTLV(cls, tag: Union[int, None], value): @@ -373,15 +363,11 @@ class ClusterEvent(ClusterObject): def __init_subclass__(cls, *args, **kwargs) -> None: """Register a subclass.""" super().__init_subclass__(*args, **kwargs) - try: - if cls.cluster_id not in ALL_EVENTS: - ALL_EVENTS[cls.cluster_id] = {} - # register this clusterattribute in the ALL_ATTRIBUTES dict for quick lookups - ALL_EVENTS[cls.cluster_id][cls.event_id] = cls - except NotImplementedError: - # handle case where the ClusterAttribute class is not (fully) subclassed - # and accessing the id property throws a NotImplementedError. - pass + + if cls.cluster_id not in ALL_EVENTS: + ALL_EVENTS[cls.cluster_id] = {} + # register this clusterattribute in the ALL_ATTRIBUTES dict for quick lookups + ALL_EVENTS[cls.cluster_id][cls.event_id] = cls @ChipUtility.classproperty def cluster_id(self) -> int: From a9ad3d003ba92695302c8c1b26aa5f75c4c09dbd Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Fri, 18 Oct 2024 16:41:43 -0400 Subject: [PATCH 4/4] Fix unit tests to instantiate the classes properly --- .../test/unit_tests/test_cluster_objects.py | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/controller/python/test/unit_tests/test_cluster_objects.py b/src/controller/python/test/unit_tests/test_cluster_objects.py index 13b12db185270e..beca5ff39863d9 100644 --- a/src/controller/python/test/unit_tests/test_cluster_objects.py +++ b/src/controller/python/test/unit_tests/test_cluster_objects.py @@ -193,6 +193,14 @@ class IntAttribute(ClusterObjects.ClusterAttributeDescriptor): def attribute_type(cls) -> ClusterObjects.ClusterObjectFieldDescriptor: return ClusterObjects.ClusterObjectFieldDescriptor(Type=int) + @chip.ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000000 + + @chip.ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + def test_basic_encode(self): res = _encode_attribute_and_then_decode_to_native( 42, TestAttributeDescriptor.IntAttribute) @@ -208,6 +216,14 @@ class StructAttribute(ClusterObjects.ClusterAttributeDescriptor): def attribute_type(cls) -> ClusterObjects.ClusterObjectFieldDescriptor: return ClusterObjects.ClusterObjectFieldDescriptor(Type=TestClusterObjects.C) + @chip.ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000000 + + @chip.ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + def test_struct_encode(self): res = _encode_attribute_and_then_decode_to_native( TestClusterObjects.C(X=42, Y=24), TestAttributeDescriptor.StructAttribute) @@ -223,6 +239,14 @@ class ArrayAttribute(ClusterObjects.ClusterAttributeDescriptor): def attribute_type(cls) -> ClusterObjects.ClusterObjectFieldDescriptor: return ClusterObjects.ClusterObjectFieldDescriptor(Type=typing.List[int]) + @chip.ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000000 + + @chip.ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + def test_array_encode(self): res = _encode_attribute_and_then_decode_to_native( [1, 2, 3, 4, 5], TestAttributeDescriptor.ArrayAttribute)