From 563946cae416aedf76ff846c33e24b0233107144 Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Fri, 19 Jul 2024 12:44:26 -0400 Subject: [PATCH 01/10] TC-IDM-10.5: Device type conformance - Add Initial test only looks at clusters. Remaining - revisions - feature conformance - cluster elements --- src/python_testing/TC_DeviceConformance.py | 96 +++++++++++- .../TestSpecParsingDeviceType.py | 146 +++++++++++++++++- src/python_testing/conformance_support.py | 4 +- 3 files changed, 237 insertions(+), 9 deletions(-) diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index 851921df60f0a4..a411cc5d437370 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -33,16 +33,18 @@ from basic_composition_support import BasicCompositionTests from chip.tlv import uint from conformance_support import ConformanceDecision, conformance_allowed -from global_attribute_ids import GlobalAttributeIds -from matter_testing_support import (AttributePathLocation, ClusterPathLocation, CommandPathLocation, MatterBaseTest, ProblemNotice, +from global_attribute_ids import GlobalAttributeIds, ClusterIdType, DeviceTypeIdType, is_valid_device_type_id, cluster_id_type, device_type_id_type +from matter_testing_support import (AttributePathLocation, ClusterPathLocation, CommandPathLocation, DeviceTypePathLocation, MatterBaseTest, ProblemNotice, ProblemSeverity, async_test_body, default_matter_test_main) -from spec_parsing_support import CommandType, build_xml_clusters +from spec_parsing_support import CommandType, build_xml_clusters, build_xml_device_types class DeviceConformanceTests(BasicCompositionTests): async def setup_class_helper(self): await super().setup_class_helper() self.xml_clusters, self.problems = build_xml_clusters() + self.xml_device_types, problems = build_xml_device_types() + self.problems.extend(problems) def check_conformance(self, ignore_in_progress: bool, is_ci: bool): problems = [] @@ -192,6 +194,7 @@ def check_spec_conformance_for_commands(command_type: CommandType): print(f'success = {success}') return success, problems + def check_revisions(self, ignore_in_progress: bool): problems = [] success = True @@ -234,6 +237,87 @@ def record_warning(location, problem): return success, problems + def check_device_type(self, fail_on_extra_clusters: bool = True, allow_provisional: bool = False) -> tuple[bool, list[ProblemNotice]]: + success = True + problems = [] + test_name = self.get_test_name() + + def record_problem(location, problem, severity): + problems.append(ProblemNotice("IDM-10.5", location, severity, problem, "")) + + def record_error(location, problem): + nonlocal success + record_problem(location, problem, ProblemSeverity.ERROR) + success = False + + def record_warning(location, problem): + record_problem(location, problem, ProblemSeverity.WARNING) + + for endpoint_id, endpoint in self.endpoints.items(): + if Clusters.Descriptor not in endpoint: + location = ClusterPathLocation(endpoint_id=endpoint_id, cluster_id=Clusters.Descriptor.id) + record_error(location=location, problem='No descriptor cluster found on endpoint') + continue + + device_type_list = endpoint[Clusters.Descriptor][Clusters.Descriptor.Attributes.DeviceTypeList] + invalid_device_types = [x for x in device_type_list if not is_valid_device_type_id(device_type_id_type(x.deviceType))] + standard_device_types = [x for x in endpoint[Clusters.Descriptor] + [Clusters.Descriptor.Attributes.DeviceTypeList] if device_type_id_type(x.deviceType) == DeviceTypeIdType.kStandard] + endpoint_clusters = [] + server_clusters = [] + for device_type in invalid_device_types: + location = DeviceTypePathLocation(device_type_id=device_type.deviceType) + record_error(location=location, problem='Invalid device type ID (out of valid range)') + + for device_type in standard_device_types: + device_type_id = device_type.deviceType + location = DeviceTypePathLocation(device_type_id=device_type_id) + if device_type_id not in self.xml_device_types.keys(): + record_error(location=location, problem='Unknown device type ID in standard range') + continue + + if device_type_id not in self.xml_device_types.keys(): + location = DeviceTypePathLocation(device_type_id=device_type_id) + record_error(location=location, problem='Unknown device type') + continue + + # TODO: check revision. Possibly in another test? + + xml_device = self.xml_device_types[device_type_id] + # IDM 10.1 checks individual clusters for validity, + # so here we can ignore checks for invalid and manufacturer clusters. + server_clusters = [x for x in endpoint[Clusters.Descriptor] + [Clusters.Descriptor.Attributes.ServerList] if cluster_id_type(x) == ClusterIdType.kStandard] + + # As a start, we are only checking server clusters + # TODO: check client clusters too? + for cluster_id, cluster_requirement in xml_device.server_clusters.items(): + # Device type cluster conformances do not include any conformances based on cluster elements + conformance_decision_with_choice = cluster_requirement.conformance(0, [], []) + location = DeviceTypePathLocation(device_type_id=device_type_id, cluster_id=cluster_id) + if conformance_decision_with_choice.decision == ConformanceDecision.MANDATORY and cluster_id not in server_clusters: + record_error(location=location, + problem=f"Mandatory cluster {cluster_requirement.name} for device type {xml_device.name} is not present in the server list") + success = False + + if cluster_id in server_clusters and not conformance_allowed(conformance_decision_with_choice, allow_provisional): + record_error(location=location, + problem=f"Disallowed cluster {cluster_requirement.name} found in server list for device type {xml_device.name}") + success = False + # If we want to check for extra clusters on the endpoint, we need to know the entire set of clusters in all the device type + # lists across all the device types on the endpoint. + endpoint_clusters += xml_device.server_clusters.keys() + if fail_on_extra_clusters: + fn = record_error + else: + fn = record_warning + extra_clusters = set(server_clusters) - set(endpoint_clusters) + for extra in extra_clusters: + location = ClusterPathLocation(endpoint_id=endpoint_id, cluster_id=extra) + fn(location=location, problem=f"Extra cluster found on endpoint with device types {device_type_list}") + + return success, problems + class TC_DeviceConformance(MatterBaseTest, DeviceConformanceTests): @async_test_body async def setup_class(self): @@ -255,6 +339,12 @@ def test_TC_IDM_10_3(self): if not success: self.fail_current_test("Problems with cluster revision on at least one cluster") + def test_TC_IDM_10_5(self): + fail_on_extra_clusters = self.user_params.get("fail_on_extra_clusters", True) + success, problems = self.check_device_type(fail_on_extra_clusters) + self.problems.extend(problems) + if not success: + self.fail_current_test("Problems with Device type conformance on one or more endpoints") if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/TestSpecParsingDeviceType.py b/src/python_testing/TestSpecParsingDeviceType.py index bc199872f8f178..d6b8f9475fba6d 100644 --- a/src/python_testing/TestSpecParsingDeviceType.py +++ b/src/python_testing/TestSpecParsingDeviceType.py @@ -16,22 +16,27 @@ # import xml.etree.ElementTree as ElementTree +import chip.clusters as Clusters +from chip.clusters import Attribute +from chip.tlv import uint from jinja2 import Template from matter_testing_support import MatterBaseTest, default_matter_test_main from mobly import asserts -from spec_parsing_support import build_xml_device_types, parse_single_device_type +from spec_parsing_support import build_xml_device_types, build_xml_clusters, parse_single_device_type +from TC_DeviceConformance import DeviceConformanceTests +from conformance_support import conformance_allowed class TestSpecParsingDeviceType(MatterBaseTest): - # This just tests that the current spec can be parsed without failures def test_spec_device_parsing(self): - device_types, problems = build_xml_device_types() - self.problems += problems - for id, d in device_types.items(): + for id, d in self.xml_device_types.items(): print(str(d)) def setup_class(self): + self.xml_clusters, self.xml_cluster_problems = build_xml_clusters() + self.xml_device_types, self.xml_device_types_problems = build_xml_device_types() + self.device_type_id = 0xBBEF self.revision = 2 self.classification_class = "simple" @@ -106,6 +111,137 @@ def test_bad_scope(self): device_type, problems = parse_single_device_type(et) asserts.assert_equal(len(problems), 1, "Device with no scope did not generate a problem notice") + # All these tests are based on the temp sensor device type because it is very simple + # it requires temperature measurement, identify and the base devices. + # Right now I'm not testing for binding condition. + # The test is entirely based on the descriptor cluster so that's all I'm populating here + # because it makes the test less complex to write. + def create_test(self, server_list: list[uint], no_descriptor:bool = False, bad_device_id: bool = False) -> DeviceConformanceTests: + self.test = DeviceConformanceTests() + self.test.xml_device_types = self.xml_device_types + self.test.xml_clusters = self.xml_clusters + + if bad_device_id: + known_ids = list(self.test.xml_device_types.keys()) + device_type_id = [a for a in range(min(known_ids), max(known_ids)) if a not in known_ids][0] + else: + device_type_id = 0x0302 + + resp = Attribute.AsyncReadTransaction.ReadResponse({}, [], {}) + if no_descriptor: + resp.attributes = {1: {}} + else: + desc = Clusters.Descriptor + server_list_attr = Clusters.Descriptor.Attributes.ServerList + device_type_list_attr = Clusters.Descriptor.Attributes.DeviceTypeList + device_type_list = [Clusters.Descriptor.Structs.DeviceTypeStruct(deviceType=device_type_id, revision=2)] + resp.attributes = {1: {desc: {device_type_list_attr: device_type_list, server_list_attr: server_list}}} + self.test.endpoints = resp.attributes + + def create_good_device(self, device_type_id:int) -> DeviceConformanceTests: + self.test = DeviceConformanceTests() + self.test.xml_device_types = self.xml_device_types + self.test.xml_clusters = self.xml_clusters + + resp = Attribute.AsyncReadTransaction.ReadResponse({}, [], {}) + desc = Clusters.Descriptor + server_list_attr = Clusters.Descriptor.Attributes.ServerList + device_type_list_attr = Clusters.Descriptor.Attributes.DeviceTypeList + device_type_list = [Clusters.Descriptor.Structs.DeviceTypeStruct(deviceType=device_type_id, revision=self.xml_device_types[device_type_id].revision)] + server_list = [k for k, v in self.xml_device_types[device_type_id].server_clusters.items() if conformance_allowed(v.conformance(0, [], []), False)] + resp.attributes = {1: {desc: {device_type_list_attr: device_type_list, server_list_attr: server_list}}} + + self.test.endpoints = resp.attributes + + # Test with temp sensor with temp sensor, identify and descriptor + def test_ts_minimal_clusters(self): + self.create_test([Clusters.TemperatureMeasurement.id, Clusters.Identify.id, Clusters.Descriptor.id]) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_true(success, "Failure on Temperature Sensor device type test") + + # Temp sensor with temp sensor, identify, descriptor, binding + def test_ts_minimal_with_binding(self): + self.create_test([Clusters.TemperatureMeasurement.id, Clusters.Identify.id, Clusters.Binding.id, Clusters.Descriptor.id]) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_true(success, "Failure on Temperature Sensor device type test") + asserts.assert_false(problems, "Found problems on Temperature sensor device type test") + + # Temp sensor with temp sensor, identify, descriptor, fixed label + def test_ts_minimal_with_label(self): + self.create_test([Clusters.TemperatureMeasurement.id, Clusters.Identify.id, Clusters.FixedLabel.id, Clusters.Descriptor.id]) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_true(success, "Failure on Temperature Sensor device type test") + asserts.assert_false(problems, "Found problems on Temperature sensor device type test") + + # Temp sensor with temp sensor, descriptor + def test_ts_missing_identify(self): + self.create_test([Clusters.TemperatureMeasurement.id, Clusters.Descriptor.id]) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_equal(len(problems), 1, "Unexpected number of problems") + asserts.assert_false(success, "Unexpected success running test that should fail") + + # endpoint 1 empty + def test_endpoint_missing_descriptor(self): + self.create_test([], no_descriptor=True) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_equal(len(problems), 1, "Unexpected number of problems") + asserts.assert_false(success, "Unexpected success running test that should fail") + + # Temp sensor with temp sensor, descriptor, identify, onoff + def test_ts_extra_cluster(self): + self.create_test([Clusters.TemperatureMeasurement.id, Clusters.Identify.id, Clusters.Descriptor.id, Clusters.OnOff.id]) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_equal(len(problems), 1, "Unexpected number of problems") + asserts.assert_false(success, "Unexpected success running test that should fail") + + success, problems = self.test.check_device_type(fail_on_extra_clusters=False) + asserts.assert_equal(len(problems), 1, "Did not receive expected warning for extra clusters") + asserts.assert_true(success, "Unexpected failure") + + def test_bad_device_type_id(self): + self.create_test([], bad_device_id=True) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_equal(len(problems), 1, "Unexpected number of problems") + asserts.assert_false(success, "Unexpected success running test that should fail") + + def test_all_device_types(self): + for id in self.xml_device_types.keys(): + self.create_good_device(id) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_false(problems, f"Unexpected problems on device type {id}") + asserts.assert_true(success, f"Unexpected failure on device type {id}") + + def test_disallowed_cluster(self): + for id, dt in self.xml_device_types.items(): + expected_problems = 0 + self.create_good_device(id) + for cluster_id, cluster in dt.server_clusters.items(): + if not conformance_allowed(cluster.conformance(0, [], []), False): + self.test.endpoints[1][Clusters.Descriptor][Clusters.Descriptor.Attributes.ServerList].append(cluster_id) + expected_problems += 1 + if expected_problems == 0: + continue + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_equal(len(problems), expected_problems, "Unexpected number of problems") + asserts.assert_false(success, "Unexpected success running test that should fail") if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/conformance_support.py b/src/python_testing/conformance_support.py index 6e439f1deb2b4d..b1b1574b50f3b7 100644 --- a/src/python_testing/conformance_support.py +++ b/src/python_testing/conformance_support.py @@ -331,7 +331,9 @@ def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_li for op in self.op_list: decision_with_choice = op(feature_map, attribute_list, all_command_list) # and operations can't happen on optional or disallowed - if decision_with_choice.decision in [ConformanceDecision.OPTIONAL, ConformanceDecision.DISALLOWED, ConformanceDecision.PROVISIONAL]: + if decision_with_choice.decision == ConformanceDecision.OPTIONAL and all([type(op)==device_feature for op in self.op_list]): + return decision_with_choice + elif decision_with_choice.decision in [ConformanceDecision.OPTIONAL, ConformanceDecision.DISALLOWED, ConformanceDecision.PROVISIONAL]: raise ConformanceException('AND operation on optional or disallowed item') elif decision_with_choice.decision == ConformanceDecision.NOT_APPLICABLE: return decision_with_choice From 4b10819e1d1dd78f93a27b3f3d30f3f7e88e691d Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Fri, 19 Jul 2024 21:49:50 +0000 Subject: [PATCH 02/10] Restyled by autopep8 --- src/python_testing/TC_DeviceConformance.py | 4 ++-- src/python_testing/TestSpecParsingDeviceType.py | 11 +++++++---- src/python_testing/conformance_support.py | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index a411cc5d437370..881f2cd7382a04 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -194,7 +194,6 @@ def check_spec_conformance_for_commands(command_type: CommandType): print(f'success = {success}') return success, problems - def check_revisions(self, ignore_in_progress: bool): problems = [] success = True @@ -236,7 +235,6 @@ def record_warning(location, problem): return success, problems - def check_device_type(self, fail_on_extra_clusters: bool = True, allow_provisional: bool = False) -> tuple[bool, list[ProblemNotice]]: success = True problems = [] @@ -318,6 +316,7 @@ def record_warning(location, problem): return success, problems + class TC_DeviceConformance(MatterBaseTest, DeviceConformanceTests): @async_test_body async def setup_class(self): @@ -346,5 +345,6 @@ def test_TC_IDM_10_5(self): if not success: self.fail_current_test("Problems with Device type conformance on one or more endpoints") + if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/TestSpecParsingDeviceType.py b/src/python_testing/TestSpecParsingDeviceType.py index d6b8f9475fba6d..04570aed354f3b 100644 --- a/src/python_testing/TestSpecParsingDeviceType.py +++ b/src/python_testing/TestSpecParsingDeviceType.py @@ -116,7 +116,7 @@ def test_bad_scope(self): # Right now I'm not testing for binding condition. # The test is entirely based on the descriptor cluster so that's all I'm populating here # because it makes the test less complex to write. - def create_test(self, server_list: list[uint], no_descriptor:bool = False, bad_device_id: bool = False) -> DeviceConformanceTests: + def create_test(self, server_list: list[uint], no_descriptor: bool = False, bad_device_id: bool = False) -> DeviceConformanceTests: self.test = DeviceConformanceTests() self.test.xml_device_types = self.xml_device_types self.test.xml_clusters = self.xml_clusters @@ -138,7 +138,7 @@ def create_test(self, server_list: list[uint], no_descriptor:bool = False, bad_d resp.attributes = {1: {desc: {device_type_list_attr: device_type_list, server_list_attr: server_list}}} self.test.endpoints = resp.attributes - def create_good_device(self, device_type_id:int) -> DeviceConformanceTests: + def create_good_device(self, device_type_id: int) -> DeviceConformanceTests: self.test = DeviceConformanceTests() self.test.xml_device_types = self.xml_device_types self.test.xml_clusters = self.xml_clusters @@ -147,8 +147,10 @@ def create_good_device(self, device_type_id:int) -> DeviceConformanceTests: desc = Clusters.Descriptor server_list_attr = Clusters.Descriptor.Attributes.ServerList device_type_list_attr = Clusters.Descriptor.Attributes.DeviceTypeList - device_type_list = [Clusters.Descriptor.Structs.DeviceTypeStruct(deviceType=device_type_id, revision=self.xml_device_types[device_type_id].revision)] - server_list = [k for k, v in self.xml_device_types[device_type_id].server_clusters.items() if conformance_allowed(v.conformance(0, [], []), False)] + device_type_list = [Clusters.Descriptor.Structs.DeviceTypeStruct( + deviceType=device_type_id, revision=self.xml_device_types[device_type_id].revision)] + server_list = [k for k, v in self.xml_device_types[device_type_id].server_clusters.items( + ) if conformance_allowed(v.conformance(0, [], []), False)] resp.attributes = {1: {desc: {device_type_list_attr: device_type_list, server_list_attr: server_list}}} self.test.endpoints = resp.attributes @@ -243,5 +245,6 @@ def test_disallowed_cluster(self): asserts.assert_equal(len(problems), expected_problems, "Unexpected number of problems") asserts.assert_false(success, "Unexpected success running test that should fail") + if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/conformance_support.py b/src/python_testing/conformance_support.py index b1b1574b50f3b7..90b6a4c3dd105c 100644 --- a/src/python_testing/conformance_support.py +++ b/src/python_testing/conformance_support.py @@ -331,7 +331,7 @@ def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_li for op in self.op_list: decision_with_choice = op(feature_map, attribute_list, all_command_list) # and operations can't happen on optional or disallowed - if decision_with_choice.decision == ConformanceDecision.OPTIONAL and all([type(op)==device_feature for op in self.op_list]): + if decision_with_choice.decision == ConformanceDecision.OPTIONAL and all([type(op) == device_feature for op in self.op_list]): return decision_with_choice elif decision_with_choice.decision in [ConformanceDecision.OPTIONAL, ConformanceDecision.DISALLOWED, ConformanceDecision.PROVISIONAL]: raise ConformanceException('AND operation on optional or disallowed item') From be752d64d42463b12f949458eefd41050eabeefd Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Fri, 19 Jul 2024 21:49:54 +0000 Subject: [PATCH 03/10] Restyled by isort --- src/python_testing/TC_DeviceConformance.py | 7 ++++--- src/python_testing/TestSpecParsingDeviceType.py | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index 881f2cd7382a04..b6164cc3c3ab11 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -33,9 +33,10 @@ from basic_composition_support import BasicCompositionTests from chip.tlv import uint from conformance_support import ConformanceDecision, conformance_allowed -from global_attribute_ids import GlobalAttributeIds, ClusterIdType, DeviceTypeIdType, is_valid_device_type_id, cluster_id_type, device_type_id_type -from matter_testing_support import (AttributePathLocation, ClusterPathLocation, CommandPathLocation, DeviceTypePathLocation, MatterBaseTest, ProblemNotice, - ProblemSeverity, async_test_body, default_matter_test_main) +from global_attribute_ids import (ClusterIdType, DeviceTypeIdType, GlobalAttributeIds, cluster_id_type, device_type_id_type, + is_valid_device_type_id) +from matter_testing_support import (AttributePathLocation, ClusterPathLocation, CommandPathLocation, DeviceTypePathLocation, + MatterBaseTest, ProblemNotice, ProblemSeverity, async_test_body, default_matter_test_main) from spec_parsing_support import CommandType, build_xml_clusters, build_xml_device_types diff --git a/src/python_testing/TestSpecParsingDeviceType.py b/src/python_testing/TestSpecParsingDeviceType.py index 04570aed354f3b..59793817a5c5d2 100644 --- a/src/python_testing/TestSpecParsingDeviceType.py +++ b/src/python_testing/TestSpecParsingDeviceType.py @@ -19,12 +19,12 @@ import chip.clusters as Clusters from chip.clusters import Attribute from chip.tlv import uint +from conformance_support import conformance_allowed from jinja2 import Template from matter_testing_support import MatterBaseTest, default_matter_test_main from mobly import asserts -from spec_parsing_support import build_xml_device_types, build_xml_clusters, parse_single_device_type +from spec_parsing_support import build_xml_clusters, build_xml_device_types, parse_single_device_type from TC_DeviceConformance import DeviceConformanceTests -from conformance_support import conformance_allowed class TestSpecParsingDeviceType(MatterBaseTest): From 51edb7925df17448085feb2adbc5bb9596430548 Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Fri, 19 Jul 2024 21:31:20 -0400 Subject: [PATCH 04/10] Add OTA requestor device type to door lock Then I can use it in the example. --- examples/lock-app/lock-common/lock-app.matter | 5 + examples/lock-app/lock-common/lock-app.zap | 136 ++++++++++++++---- 2 files changed, 117 insertions(+), 24 deletions(-) diff --git a/examples/lock-app/lock-common/lock-app.matter b/examples/lock-app/lock-common/lock-app.matter index d53a80f7402b1c..3bc7fd69a23c77 100644 --- a/examples/lock-app/lock-common/lock-app.matter +++ b/examples/lock-app/lock-common/lock-app.matter @@ -2502,6 +2502,7 @@ cluster DoorLock = 257 { endpoint 0 { device type ma_rootdevice = 22, version 1; device type ma_powersource = 17, version 1; + device type ma_otarequestor = 18, version 1; binding cluster OtaSoftwareUpdateProvider; @@ -2575,6 +2576,10 @@ endpoint 0 { ram attribute updatePossible default = 1; ram attribute updateState default = 0; ram attribute updateStateProgress default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/lock-app/lock-common/lock-app.zap b/examples/lock-app/lock-common/lock-app.zap index 182645823f1065..998bdc8d973ce1 100644 --- a/examples/lock-app/lock-common/lock-app.zap +++ b/examples/lock-app/lock-common/lock-app.zap @@ -38,12 +38,18 @@ "id": 1, "name": "MA-rootdevice", "deviceTypeRef": { - "code": 17, + "code": 18, "profileId": 259, - "label": "MA-powersource", - "name": "MA-powersource" + "label": "MA-otarequestor", + "name": "MA-otarequestor" }, "deviceTypes": [ + { + "code": 18, + "profileId": 259, + "label": "MA-otarequestor", + "name": "MA-otarequestor" + }, { "code": 17, "profileId": 259, @@ -58,15 +64,17 @@ } ], "deviceVersions": [ + 1, 1, 1 ], "deviceIdentifiers": [ + 18, 17, 22 ], - "deviceTypeName": "MA-powersource", - "deviceTypeCode": 17, + "deviceTypeName": "MA-otarequestor", + "deviceTypeCode": 18, "deviceTypeProfileId": 259, "clusters": [ { @@ -104,7 +112,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -120,7 +128,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -136,7 +144,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -258,7 +266,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -274,7 +282,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -460,7 +468,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -476,7 +484,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -492,7 +500,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -508,7 +516,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -524,7 +532,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -540,7 +548,7 @@ "singleton": 1, "bounded": 0, "defaultValue": "", - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -556,7 +564,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -572,7 +580,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -588,7 +596,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -604,7 +612,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -620,7 +628,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -956,6 +964,22 @@ } ], "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "ClusterRevision", "code": 65533, @@ -1056,6 +1080,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -1132,7 +1220,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "en-US", - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -1148,7 +1236,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -2249,7 +2337,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 From 0e6d6ebbda8a644b656107313c8ad5cd88e7f969 Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Fri, 19 Jul 2024 21:45:39 -0400 Subject: [PATCH 05/10] add test to CI --- src/python_testing/TC_DeviceConformance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index b6164cc3c3ab11..662aeeda274671 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -24,7 +24,7 @@ # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# test-runner-run/run1/script-args: --storage-path admin_storage.json --manual-code 10054912339 --bool-arg ignore_in_progress:True allow_provisional:True --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --tests test_TC_IDM_10_2 +# test-runner-run/run1/script-args: --storage-path admin_storage.json --manual-code 10054912339 --bool-arg ignore_in_progress:True allow_provisional:True --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --tests test_TC_IDM_10_2 test_TC_IDM_10_5 # === END CI TEST ARGUMENTS === from typing import Callable From 4c1f585760ec616c36e45b8bfa933e7ad1883140 Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Fri, 19 Jul 2024 22:34:21 -0400 Subject: [PATCH 06/10] linter --- src/python_testing/TC_DeviceConformance.py | 1 - src/python_testing/TestSpecParsingDeviceType.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index 662aeeda274671..92890aa3086f19 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -239,7 +239,6 @@ def record_warning(location, problem): def check_device_type(self, fail_on_extra_clusters: bool = True, allow_provisional: bool = False) -> tuple[bool, list[ProblemNotice]]: success = True problems = [] - test_name = self.get_test_name() def record_problem(location, problem, severity): problems.append(ProblemNotice("IDM-10.5", location, severity, problem, "")) diff --git a/src/python_testing/TestSpecParsingDeviceType.py b/src/python_testing/TestSpecParsingDeviceType.py index 59793817a5c5d2..7729ccee8af24d 100644 --- a/src/python_testing/TestSpecParsingDeviceType.py +++ b/src/python_testing/TestSpecParsingDeviceType.py @@ -212,7 +212,7 @@ def test_ts_extra_cluster(self): asserts.assert_equal(len(problems), 1, "Did not receive expected warning for extra clusters") asserts.assert_true(success, "Unexpected failure") - def test_bad_device_type_id(self): + def test_bad_device_type_id_device_type_test(self): self.create_test([], bad_device_id=True) success, problems = self.test.check_device_type(fail_on_extra_clusters=True) if problems: From b4bde38166ceff777ba22ebcd126692e00f5d56f Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Mon, 22 Jul 2024 18:24:52 -0400 Subject: [PATCH 07/10] OTA requestor isn't hooked up, remove Let's go the other way and remove the cluster and the device type. --- examples/lock-app/lock-common/lock-app.matter | 174 ---------- examples/lock-app/lock-common/lock-app.zap | 305 +----------------- 2 files changed, 5 insertions(+), 474 deletions(-) diff --git a/examples/lock-app/lock-common/lock-app.matter b/examples/lock-app/lock-common/lock-app.matter index 3bc7fd69a23c77..1119d51fc2f072 100644 --- a/examples/lock-app/lock-common/lock-app.matter +++ b/examples/lock-app/lock-common/lock-app.matter @@ -256,160 +256,6 @@ cluster BasicInformation = 40 { command MfgSpecificPing(): DefaultSuccess = 0; } -/** Provides an interface for providing OTA software updates */ -cluster OtaSoftwareUpdateProvider = 41 { - revision 1; // NOTE: Default/not specifically set - - enum ApplyUpdateActionEnum : enum8 { - kProceed = 0; - kAwaitNextAction = 1; - kDiscontinue = 2; - } - - enum DownloadProtocolEnum : enum8 { - kBDXSynchronous = 0; - kBDXAsynchronous = 1; - kHTTPS = 2; - kVendorSpecific = 3; - } - - enum StatusEnum : enum8 { - kUpdateAvailable = 0; - kBusy = 1; - kNotAvailable = 2; - kDownloadProtocolNotSupported = 3; - } - - readonly attribute command_id generatedCommandList[] = 65528; - readonly attribute command_id acceptedCommandList[] = 65529; - readonly attribute event_id eventList[] = 65530; - readonly attribute attrib_id attributeList[] = 65531; - readonly attribute bitmap32 featureMap = 65532; - readonly attribute int16u clusterRevision = 65533; - - request struct QueryImageRequest { - vendor_id vendorID = 0; - int16u productID = 1; - int32u softwareVersion = 2; - DownloadProtocolEnum protocolsSupported[] = 3; - optional int16u hardwareVersion = 4; - optional char_string<2> location = 5; - optional boolean requestorCanConsent = 6; - optional octet_string<512> metadataForProvider = 7; - } - - response struct QueryImageResponse = 1 { - StatusEnum status = 0; - optional int32u delayedActionTime = 1; - optional char_string<256> imageURI = 2; - optional int32u softwareVersion = 3; - optional char_string<64> softwareVersionString = 4; - optional octet_string<32> updateToken = 5; - optional boolean userConsentNeeded = 6; - optional octet_string<512> metadataForRequestor = 7; - } - - request struct ApplyUpdateRequestRequest { - octet_string<32> updateToken = 0; - int32u newVersion = 1; - } - - response struct ApplyUpdateResponse = 3 { - ApplyUpdateActionEnum action = 0; - int32u delayedActionTime = 1; - } - - request struct NotifyUpdateAppliedRequest { - octet_string<32> updateToken = 0; - int32u softwareVersion = 1; - } - - /** Determine availability of a new Software Image */ - command QueryImage(QueryImageRequest): QueryImageResponse = 0; - /** Determine next action to take for a downloaded Software Image */ - command ApplyUpdateRequest(ApplyUpdateRequestRequest): ApplyUpdateResponse = 2; - /** Notify OTA Provider that an update was applied */ - command NotifyUpdateApplied(NotifyUpdateAppliedRequest): DefaultSuccess = 4; -} - -/** Provides an interface for downloading and applying OTA software updates */ -cluster OtaSoftwareUpdateRequestor = 42 { - revision 1; // NOTE: Default/not specifically set - - enum AnnouncementReasonEnum : enum8 { - kSimpleAnnouncement = 0; - kUpdateAvailable = 1; - kUrgentUpdateAvailable = 2; - } - - enum ChangeReasonEnum : enum8 { - kUnknown = 0; - kSuccess = 1; - kFailure = 2; - kTimeOut = 3; - kDelayByProvider = 4; - } - - enum UpdateStateEnum : enum8 { - kUnknown = 0; - kIdle = 1; - kQuerying = 2; - kDelayedOnQuery = 3; - kDownloading = 4; - kApplying = 5; - kDelayedOnApply = 6; - kRollingBack = 7; - kDelayedOnUserConsent = 8; - } - - fabric_scoped struct ProviderLocation { - node_id providerNodeID = 1; - endpoint_no endpoint = 2; - fabric_idx fabricIndex = 254; - } - - info event StateTransition = 0 { - UpdateStateEnum previousState = 0; - UpdateStateEnum newState = 1; - ChangeReasonEnum reason = 2; - nullable int32u targetSoftwareVersion = 3; - } - - critical event VersionApplied = 1 { - int32u softwareVersion = 0; - int16u productID = 1; - } - - info event DownloadError = 2 { - int32u softwareVersion = 0; - int64u bytesDownloaded = 1; - nullable int8u progressPercent = 2; - nullable int64s platformCode = 3; - } - - attribute access(write: administer) ProviderLocation defaultOTAProviders[] = 0; - readonly attribute boolean updatePossible = 1; - readonly attribute UpdateStateEnum updateState = 2; - readonly attribute nullable int8u updateStateProgress = 3; - readonly attribute command_id generatedCommandList[] = 65528; - readonly attribute command_id acceptedCommandList[] = 65529; - readonly attribute event_id eventList[] = 65530; - readonly attribute attrib_id attributeList[] = 65531; - readonly attribute bitmap32 featureMap = 65532; - readonly attribute int16u clusterRevision = 65533; - - request struct AnnounceOTAProviderRequest { - node_id providerNodeID = 0; - vendor_id vendorID = 1; - AnnouncementReasonEnum announcementReason = 2; - optional octet_string<512> metadataForNode = 3; - endpoint_no endpoint = 4; - } - - /** Announce the presence of an OTA Provider */ - command AnnounceOTAProvider(AnnounceOTAProviderRequest): DefaultSuccess = 0; -} - /** Nodes should be expected to be deployed to any and all regions of the world. These global regions may have differing common languages, units of measurements, and numerical formatting standards. As such, Nodes that visually or audibly convey information need a mechanism by which @@ -2502,9 +2348,7 @@ cluster DoorLock = 257 { endpoint 0 { device type ma_rootdevice = 22, version 1; device type ma_powersource = 17, version 1; - device type ma_otarequestor = 18, version 1; - binding cluster OtaSoftwareUpdateProvider; server cluster Descriptor { callback attribute deviceTypeList; @@ -2568,24 +2412,6 @@ endpoint 0 { ram attribute clusterRevision default = 3; } - server cluster OtaSoftwareUpdateRequestor { - emits event StateTransition; - emits event VersionApplied; - emits event DownloadError; - callback attribute defaultOTAProviders; - ram attribute updatePossible default = 1; - ram attribute updateState default = 0; - ram attribute updateStateProgress default = 0; - callback attribute generatedCommandList; - callback attribute acceptedCommandList; - callback attribute eventList; - callback attribute attributeList; - ram attribute featureMap default = 0; - ram attribute clusterRevision default = 1; - - handle command AnnounceOTAProvider; - } - server cluster LocalizationConfiguration { persist attribute activeLocale default = "en-US"; callback attribute supportedLocales; diff --git a/examples/lock-app/lock-common/lock-app.zap b/examples/lock-app/lock-common/lock-app.zap index 998bdc8d973ce1..66ddc5ba5eca0a 100644 --- a/examples/lock-app/lock-common/lock-app.zap +++ b/examples/lock-app/lock-common/lock-app.zap @@ -38,18 +38,12 @@ "id": 1, "name": "MA-rootdevice", "deviceTypeRef": { - "code": 18, + "code": 17, "profileId": 259, - "label": "MA-otarequestor", - "name": "MA-otarequestor" + "label": "MA-powersource", + "name": "MA-powersource" }, "deviceTypes": [ - { - "code": 18, - "profileId": 259, - "label": "MA-otarequestor", - "name": "MA-otarequestor" - }, { "code": 17, "profileId": 259, @@ -64,17 +58,15 @@ } ], "deviceVersions": [ - 1, 1, 1 ], "deviceIdentifiers": [ - 18, 17, 22 ], - "deviceTypeName": "MA-otarequestor", - "deviceTypeCode": 18, + "deviceTypeName": "MA-powersource", + "deviceTypeCode": 17, "deviceTypeProfileId": 259, "clusters": [ { @@ -914,293 +906,6 @@ } ] }, - { - "name": "OTA Software Update Provider", - "code": 41, - "mfgCode": null, - "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER", - "side": "client", - "enabled": 1, - "commands": [ - { - "name": "QueryImage", - "code": 0, - "mfgCode": null, - "source": "client", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "QueryImageResponse", - "code": 1, - "mfgCode": null, - "source": "server", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "ApplyUpdateRequest", - "code": 2, - "mfgCode": null, - "source": "client", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "ApplyUpdateResponse", - "code": 3, - "mfgCode": null, - "source": "server", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "NotifyUpdateApplied", - "code": 4, - "mfgCode": null, - "source": "client", - "isIncoming": 0, - "isEnabled": 1 - } - ], - "attributes": [ - { - "name": "FeatureMap", - "code": 65532, - "mfgCode": null, - "side": "client", - "type": "bitmap32", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "ClusterRevision", - "code": 65533, - "mfgCode": null, - "side": "client", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "1", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - } - ] - }, - { - "name": "OTA Software Update Requestor", - "code": 42, - "mfgCode": null, - "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER", - "side": "server", - "enabled": 1, - "commands": [ - { - "name": "AnnounceOTAProvider", - "code": 0, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - } - ], - "attributes": [ - { - "name": "DefaultOTAProviders", - "code": 0, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "UpdatePossible", - "code": 1, - "mfgCode": null, - "side": "server", - "type": "boolean", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "1", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, - { - "name": "UpdateState", - "code": 2, - "mfgCode": null, - "side": "server", - "type": "UpdateStateEnum", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, - { - "name": "UpdateStateProgress", - "code": 3, - "mfgCode": null, - "side": "server", - "type": "int8u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "GeneratedCommandList", - "code": 65528, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "AcceptedCommandList", - "code": 65529, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "AttributeList", - "code": 65531, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "FeatureMap", - "code": 65532, - "mfgCode": null, - "side": "server", - "type": "bitmap32", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "ClusterRevision", - "code": 65533, - "mfgCode": null, - "side": "server", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "1", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - } - ], - "events": [ - { - "name": "StateTransition", - "code": 0, - "mfgCode": null, - "side": "server", - "included": 1 - }, - { - "name": "VersionApplied", - "code": 1, - "mfgCode": null, - "side": "server", - "included": 1 - }, - { - "name": "DownloadError", - "code": 2, - "mfgCode": null, - "side": "server", - "included": 1 - } - ] - }, { "name": "Localization Configuration", "code": 43, From bab19328bc07f5d12f4a55fc052ef5ecaef4538b Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Tue, 23 Jul 2024 19:39:04 -0400 Subject: [PATCH 08/10] Revert "OTA requestor isn't hooked up, remove" This reverts commit b4bde38166ceff777ba22ebcd126692e00f5d56f. --- examples/lock-app/lock-common/lock-app.matter | 174 ++++++++++ examples/lock-app/lock-common/lock-app.zap | 305 +++++++++++++++++- 2 files changed, 474 insertions(+), 5 deletions(-) diff --git a/examples/lock-app/lock-common/lock-app.matter b/examples/lock-app/lock-common/lock-app.matter index 5611967d988660..a424f5d7c47e17 100644 --- a/examples/lock-app/lock-common/lock-app.matter +++ b/examples/lock-app/lock-common/lock-app.matter @@ -256,6 +256,160 @@ cluster BasicInformation = 40 { command MfgSpecificPing(): DefaultSuccess = 0; } +/** Provides an interface for providing OTA software updates */ +cluster OtaSoftwareUpdateProvider = 41 { + revision 1; // NOTE: Default/not specifically set + + enum ApplyUpdateActionEnum : enum8 { + kProceed = 0; + kAwaitNextAction = 1; + kDiscontinue = 2; + } + + enum DownloadProtocolEnum : enum8 { + kBDXSynchronous = 0; + kBDXAsynchronous = 1; + kHTTPS = 2; + kVendorSpecific = 3; + } + + enum StatusEnum : enum8 { + kUpdateAvailable = 0; + kBusy = 1; + kNotAvailable = 2; + kDownloadProtocolNotSupported = 3; + } + + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct QueryImageRequest { + vendor_id vendorID = 0; + int16u productID = 1; + int32u softwareVersion = 2; + DownloadProtocolEnum protocolsSupported[] = 3; + optional int16u hardwareVersion = 4; + optional char_string<2> location = 5; + optional boolean requestorCanConsent = 6; + optional octet_string<512> metadataForProvider = 7; + } + + response struct QueryImageResponse = 1 { + StatusEnum status = 0; + optional int32u delayedActionTime = 1; + optional char_string<256> imageURI = 2; + optional int32u softwareVersion = 3; + optional char_string<64> softwareVersionString = 4; + optional octet_string<32> updateToken = 5; + optional boolean userConsentNeeded = 6; + optional octet_string<512> metadataForRequestor = 7; + } + + request struct ApplyUpdateRequestRequest { + octet_string<32> updateToken = 0; + int32u newVersion = 1; + } + + response struct ApplyUpdateResponse = 3 { + ApplyUpdateActionEnum action = 0; + int32u delayedActionTime = 1; + } + + request struct NotifyUpdateAppliedRequest { + octet_string<32> updateToken = 0; + int32u softwareVersion = 1; + } + + /** Determine availability of a new Software Image */ + command QueryImage(QueryImageRequest): QueryImageResponse = 0; + /** Determine next action to take for a downloaded Software Image */ + command ApplyUpdateRequest(ApplyUpdateRequestRequest): ApplyUpdateResponse = 2; + /** Notify OTA Provider that an update was applied */ + command NotifyUpdateApplied(NotifyUpdateAppliedRequest): DefaultSuccess = 4; +} + +/** Provides an interface for downloading and applying OTA software updates */ +cluster OtaSoftwareUpdateRequestor = 42 { + revision 1; // NOTE: Default/not specifically set + + enum AnnouncementReasonEnum : enum8 { + kSimpleAnnouncement = 0; + kUpdateAvailable = 1; + kUrgentUpdateAvailable = 2; + } + + enum ChangeReasonEnum : enum8 { + kUnknown = 0; + kSuccess = 1; + kFailure = 2; + kTimeOut = 3; + kDelayByProvider = 4; + } + + enum UpdateStateEnum : enum8 { + kUnknown = 0; + kIdle = 1; + kQuerying = 2; + kDelayedOnQuery = 3; + kDownloading = 4; + kApplying = 5; + kDelayedOnApply = 6; + kRollingBack = 7; + kDelayedOnUserConsent = 8; + } + + fabric_scoped struct ProviderLocation { + node_id providerNodeID = 1; + endpoint_no endpoint = 2; + fabric_idx fabricIndex = 254; + } + + info event StateTransition = 0 { + UpdateStateEnum previousState = 0; + UpdateStateEnum newState = 1; + ChangeReasonEnum reason = 2; + nullable int32u targetSoftwareVersion = 3; + } + + critical event VersionApplied = 1 { + int32u softwareVersion = 0; + int16u productID = 1; + } + + info event DownloadError = 2 { + int32u softwareVersion = 0; + int64u bytesDownloaded = 1; + nullable int8u progressPercent = 2; + nullable int64s platformCode = 3; + } + + attribute access(write: administer) ProviderLocation defaultOTAProviders[] = 0; + readonly attribute boolean updatePossible = 1; + readonly attribute UpdateStateEnum updateState = 2; + readonly attribute nullable int8u updateStateProgress = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AnnounceOTAProviderRequest { + node_id providerNodeID = 0; + vendor_id vendorID = 1; + AnnouncementReasonEnum announcementReason = 2; + optional octet_string<512> metadataForNode = 3; + endpoint_no endpoint = 4; + } + + /** Announce the presence of an OTA Provider */ + command AnnounceOTAProvider(AnnounceOTAProviderRequest): DefaultSuccess = 0; +} + /** Nodes should be expected to be deployed to any and all regions of the world. These global regions may have differing common languages, units of measurements, and numerical formatting standards. As such, Nodes that visually or audibly convey information need a mechanism by which @@ -2350,7 +2504,9 @@ cluster DoorLock = 257 { endpoint 0 { device type ma_rootdevice = 22, version 1; device type ma_powersource = 17, version 1; + device type ma_otarequestor = 18, version 1; + binding cluster OtaSoftwareUpdateProvider; server cluster Descriptor { callback attribute deviceTypeList; @@ -2414,6 +2570,24 @@ endpoint 0 { ram attribute clusterRevision default = 3; } + server cluster OtaSoftwareUpdateRequestor { + emits event StateTransition; + emits event VersionApplied; + emits event DownloadError; + callback attribute defaultOTAProviders; + ram attribute updatePossible default = 1; + ram attribute updateState default = 0; + ram attribute updateStateProgress default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command AnnounceOTAProvider; + } + server cluster LocalizationConfiguration { persist attribute activeLocale default = "en-US"; callback attribute supportedLocales; diff --git a/examples/lock-app/lock-common/lock-app.zap b/examples/lock-app/lock-common/lock-app.zap index 0db49fbe740b85..2836f9bf461bcf 100644 --- a/examples/lock-app/lock-common/lock-app.zap +++ b/examples/lock-app/lock-common/lock-app.zap @@ -38,12 +38,18 @@ "id": 1, "name": "MA-rootdevice", "deviceTypeRef": { - "code": 17, + "code": 18, "profileId": 259, - "label": "MA-powersource", - "name": "MA-powersource" + "label": "MA-otarequestor", + "name": "MA-otarequestor" }, "deviceTypes": [ + { + "code": 18, + "profileId": 259, + "label": "MA-otarequestor", + "name": "MA-otarequestor" + }, { "code": 17, "profileId": 259, @@ -58,15 +64,17 @@ } ], "deviceVersions": [ + 1, 1, 1 ], "deviceIdentifiers": [ + 18, 17, 22 ], - "deviceTypeName": "MA-powersource", - "deviceTypeCode": 17, + "deviceTypeName": "MA-otarequestor", + "deviceTypeCode": 18, "deviceTypeProfileId": 259, "clusters": [ { @@ -906,6 +914,293 @@ } ] }, + { + "name": "OTA Software Update Provider", + "code": 41, + "mfgCode": null, + "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "QueryImage", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "QueryImageResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ApplyUpdateRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ApplyUpdateResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NotifyUpdateApplied", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "OTA Software Update Requestor", + "code": 42, + "mfgCode": null, + "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AnnounceOTAProvider", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "DefaultOTAProviders", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "UpdatePossible", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpdateState", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "UpdateStateEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpdateStateProgress", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StateTransition", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "VersionApplied", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "DownloadError", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, { "name": "Localization Configuration", "code": 43, From d8cb90946bbe98e815c5c7e46e7d1f3f078285d3 Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Tue, 23 Jul 2024 19:39:13 -0400 Subject: [PATCH 09/10] Revert "Add OTA requestor device type to door lock" This reverts commit 51edb7925df17448085feb2adbc5bb9596430548. --- examples/lock-app/lock-common/lock-app.matter | 5 - examples/lock-app/lock-common/lock-app.zap | 136 ++++-------------- 2 files changed, 24 insertions(+), 117 deletions(-) diff --git a/examples/lock-app/lock-common/lock-app.matter b/examples/lock-app/lock-common/lock-app.matter index a424f5d7c47e17..c42fb812cb8d41 100644 --- a/examples/lock-app/lock-common/lock-app.matter +++ b/examples/lock-app/lock-common/lock-app.matter @@ -2504,7 +2504,6 @@ cluster DoorLock = 257 { endpoint 0 { device type ma_rootdevice = 22, version 1; device type ma_powersource = 17, version 1; - device type ma_otarequestor = 18, version 1; binding cluster OtaSoftwareUpdateProvider; @@ -2578,10 +2577,6 @@ endpoint 0 { ram attribute updatePossible default = 1; ram attribute updateState default = 0; ram attribute updateStateProgress default = 0; - callback attribute generatedCommandList; - callback attribute acceptedCommandList; - callback attribute eventList; - callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/lock-app/lock-common/lock-app.zap b/examples/lock-app/lock-common/lock-app.zap index 2836f9bf461bcf..605da39d72da56 100644 --- a/examples/lock-app/lock-common/lock-app.zap +++ b/examples/lock-app/lock-common/lock-app.zap @@ -38,18 +38,12 @@ "id": 1, "name": "MA-rootdevice", "deviceTypeRef": { - "code": 18, + "code": 17, "profileId": 259, - "label": "MA-otarequestor", - "name": "MA-otarequestor" + "label": "MA-powersource", + "name": "MA-powersource" }, "deviceTypes": [ - { - "code": 18, - "profileId": 259, - "label": "MA-otarequestor", - "name": "MA-otarequestor" - }, { "code": 17, "profileId": 259, @@ -64,17 +58,15 @@ } ], "deviceVersions": [ - 1, 1, 1 ], "deviceIdentifiers": [ - 18, 17, 22 ], - "deviceTypeName": "MA-otarequestor", - "deviceTypeCode": 18, + "deviceTypeName": "MA-powersource", + "deviceTypeCode": 17, "deviceTypeProfileId": 259, "clusters": [ { @@ -112,7 +104,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -128,7 +120,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -144,7 +136,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -266,7 +258,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -282,7 +274,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -468,7 +460,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -484,7 +476,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -500,7 +492,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -516,7 +508,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -532,7 +524,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -548,7 +540,7 @@ "singleton": 1, "bounded": 0, "defaultValue": "", - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -564,7 +556,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -580,7 +572,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -596,7 +588,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -612,7 +604,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -628,7 +620,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -964,22 +956,6 @@ } ], "attributes": [ - { - "name": "FeatureMap", - "code": 65532, - "mfgCode": null, - "side": "client", - "type": "bitmap32", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "ClusterRevision", "code": 65533, @@ -1080,70 +1056,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "GeneratedCommandList", - "code": 65528, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "AcceptedCommandList", - "code": 65529, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "AttributeList", - "code": 65531, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "FeatureMap", "code": 65532, @@ -1220,7 +1132,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "en-US", - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -1236,7 +1148,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -2337,7 +2249,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 0, + "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 From 6170f0aeb98393fb42bf70b2678ff5e6e6f531bd Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Tue, 23 Jul 2024 19:40:29 -0400 Subject: [PATCH 10/10] Remove from CI until door lock OTA is sorted. --- src/python_testing/TC_DeviceConformance.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index 92890aa3086f19..2e18ff9a0cd88a 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -24,9 +24,10 @@ # test-runner-run/run1/factoryreset: True # test-runner-run/run1/quiet: True # test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# test-runner-run/run1/script-args: --storage-path admin_storage.json --manual-code 10054912339 --bool-arg ignore_in_progress:True allow_provisional:True --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --tests test_TC_IDM_10_2 test_TC_IDM_10_5 +# test-runner-run/run1/script-args: --storage-path admin_storage.json --manual-code 10054912339 --bool-arg ignore_in_progress:True allow_provisional:True --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --tests test_TC_IDM_10_2 # === END CI TEST ARGUMENTS === +# TODO: Enable 10.5 in CI once the door lock OTA requestor problem is sorted. from typing import Callable import chip.clusters as Clusters