From 3634532166f26791d22687ec2ecaac8dd7ac4d5f Mon Sep 17 00:00:00 2001 From: cecille Date: Mon, 16 Sep 2024 18:06:33 -0400 Subject: [PATCH 1/5] Spec parsing: Add global commands for thermostat --- src/python_testing/TestSpecParsingSupport.py | 26 ++++++++++++++++++++ src/python_testing/spec_parsing_support.py | 21 ++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/python_testing/TestSpecParsingSupport.py b/src/python_testing/TestSpecParsingSupport.py index aa2a68427607e4..559557150146ad 100644 --- a/src/python_testing/TestSpecParsingSupport.py +++ b/src/python_testing/TestSpecParsingSupport.py @@ -462,6 +462,32 @@ def test_provisional_clusters(self): asserts.assert_in(id, clusters.keys(), "Non-provisional cluster not parsed") asserts.assert_false(clusters[id].is_provisional, "Non-provisional cluster marked as provisional") + def test_atomic_thermostat(self): + tot_xml_clusters, problems = build_xml_clusters(PrebuiltDataModelDirectory.kMaster) + one_three_clusters, problems = build_xml_clusters(PrebuiltDataModelDirectory.k1_3) + in_progress, problems = build_xml_clusters(PrebuiltDataModelDirectory.kInProgress) + + asserts.assert_in("Atomic Request", tot_xml_clusters[Clusters.Thermostat.id].command_map, + "Atomic request not found on thermostat command map") + request_id = tot_xml_clusters[Clusters.Thermostat.id].command_map["Atomic Request"] + asserts.assert_in(request_id, tot_xml_clusters[Clusters.Thermostat.id].accepted_commands.keys(), + "Atomic request not found in thermostat accepted command list") + + asserts.assert_in("Atomic Response", tot_xml_clusters[Clusters.Thermostat.id].command_map, + "Atomic response not found in the thermostat command map") + response_id = tot_xml_clusters[Clusters.Thermostat.id].command_map["Atomic Response"] + asserts.assert_in(response_id, tot_xml_clusters[Clusters.Thermostat.id].generated_commands.keys(), + "Atomic response not found in thermostat generated command list") + + asserts.assert_not_in( + "Atomic Request", one_three_clusters[Clusters.Thermostat.id].command_map, "Atomic request found on thermostat command map for 1.3") + asserts.assert_not_in(request_id, one_three_clusters[Clusters.Thermostat.id].accepted_commands.keys(), + "Atomic request found in thermostat accepted command list for 1.3") + asserts.assert_not_in( + "Atomic Response", one_three_clusters[Clusters.Thermostat.id].command_map, "Atomic response found on thermostat command map for 1.3") + asserts.assert_not_in(response_id, one_three_clusters[Clusters.Thermostat.id].generated_commands.keys(), + "Atomic request found in thermostat generated command list for 1.3") + if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/spec_parsing_support.py b/src/python_testing/spec_parsing_support.py index 445e168ecb4f5a..4ca0470467755f 100644 --- a/src/python_testing/spec_parsing_support.py +++ b/src/python_testing/spec_parsing_support.py @@ -26,6 +26,8 @@ from typing import Callable, Optional import chip.clusters as Clusters +import conformance_support + from chip.tlv import uint from conformance_support import (OPTIONAL_CONFORM, TOP_LEVEL_CONFORMANCE_TAGS, ConformanceDecision, ConformanceException, ConformanceParseParameters, feature, is_disallowed, mandatory, optional, or_operation, @@ -611,6 +613,25 @@ def remove_problem(location: typing.Union[CommandPathLocation, FeaturePathLocati 0x05: XmlAttribute(name='SupportedTemperatureLevels', datatype='list', conformance=feature(0x02, 'TL'), read_access=view, write_access=none, write_optional=False), } + # TODO: Need automated parsing for atomic attributes. + atomic_request_cmd_id = 0xFE + atomic_response_cmd_id = 0xFD + atomic_request_name = "Atomic Request" + atomic_response_name = "Atomic Response" + presets_name = "Presets" + schedules_name = "Schedules" + if clusters[Clusters.Thermostat.id].revision >= 8: + presents_id = clusters[Clusters.Thermostat.id].attribute_map[presets_name] + schedules_id = clusters[Clusters.Thermostat.id].attribute_map[schedules_name] + conformance = or_operation([conformance_support.attribute(presents_id, presets_name), + conformance_support.attribute(schedules_id, schedules_name)]) + clusters[Clusters.Thermostat.id].accepted_commands[atomic_request_cmd_id] = XmlCommand( + id=atomic_request_cmd_id, name=atomic_request_name, conformance=conformance) + clusters[Clusters.Thermostat.id].generated_commands[atomic_response_cmd_id] = XmlCommand( + id=atomic_response_cmd_id, name=atomic_response_name, conformance=conformance) + clusters[Clusters.Thermostat.id].command_map[atomic_request_name] = atomic_request_cmd_id + clusters[Clusters.Thermostat.id].command_map[atomic_response_name] = atomic_response_cmd_id + check_clusters_for_unknown_commands(clusters, problems) return clusters, problems From fdf55ceaa1534556d704df65844bd52364472f6b Mon Sep 17 00:00:00 2001 From: cecille Date: Mon, 16 Sep 2024 21:41:12 -0400 Subject: [PATCH 2/5] use in-progress for clusters too --- src/python_testing/spec_parsing_support.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/spec_parsing_support.py b/src/python_testing/spec_parsing_support.py index 4ca0470467755f..625efa12436eb8 100644 --- a/src/python_testing/spec_parsing_support.py +++ b/src/python_testing/spec_parsing_support.py @@ -530,7 +530,7 @@ def _get_data_model_directory(data_model_directory: typing.Union[PrebuiltDataMod return data_model_directory -def build_xml_clusters(data_model_directory: typing.Union[PrebuiltDataModelDirectory, str] = PrebuiltDataModelDirectory.kMaster) -> tuple[dict[uint, XmlCluster], list[ProblemNotice]]: +def build_xml_clusters(data_model_directory: typing.Union[PrebuiltDataModelDirectory, str] = PrebuiltDataModelDirectory.kInProgress) -> tuple[dict[uint, XmlCluster], list[ProblemNotice]]: dir = _get_data_model_directory(data_model_directory, DataModelLevel.kCluster) clusters: dict[int, XmlCluster] = {} From 05f4297ab9e3ea804055f70969535712522c6fac Mon Sep 17 00:00:00 2001 From: cecille Date: Tue, 17 Sep 2024 16:42:30 -0400 Subject: [PATCH 3/5] Fix command check (merge conflict?) --- src/python_testing/TC_DeviceConformance.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index a6d6f19bfb53e7..86a981c86cde15 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -166,7 +166,6 @@ def record_warning(location, problem): if attribute_id not in self.xml_clusters[cluster_id].attributes.keys(): # TODO: Consolidate the range checks with IDM-10.1 once that lands if attribute_id <= 0x4FFF: - # manufacturer attribute record_error(location=location, problem='Standard attribute found on device, but not in spec') continue xml_attribute = self.xml_clusters[cluster_id].attributes[attribute_id] @@ -193,9 +192,7 @@ def check_spec_conformance_for_commands(command_type: CommandType): if command_id not in xml_commands_dict: # TODO: Consolidate range checks with IDM-10.1 once that lands if command_id <= 0xFF: - # manufacturer command - continue - record_error(location=location, problem='Standard command found on device, but not in spec') + record_error(location=location, problem='Standard command found on device, but not in spec') continue xml_command = xml_commands_dict[command_id] conformance_decision_with_choice = xml_command.conformance(feature_map, attribute_list, all_command_list) From 3fdfc6cf144076f37e3f72fb54dbb17c4c9e15a6 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Tue, 17 Sep 2024 20:43:10 +0000 Subject: [PATCH 4/5] Restyled by isort --- src/python_testing/spec_parsing_support.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/python_testing/spec_parsing_support.py b/src/python_testing/spec_parsing_support.py index 625efa12436eb8..5a66a900c28c91 100644 --- a/src/python_testing/spec_parsing_support.py +++ b/src/python_testing/spec_parsing_support.py @@ -27,7 +27,6 @@ import chip.clusters as Clusters import conformance_support - from chip.tlv import uint from conformance_support import (OPTIONAL_CONFORM, TOP_LEVEL_CONFORMANCE_TAGS, ConformanceDecision, ConformanceException, ConformanceParseParameters, feature, is_disallowed, mandatory, optional, or_operation, From 1adfbe307d13f0c91491e3d8cddf0d485574df03 Mon Sep 17 00:00:00 2001 From: cecille Date: Wed, 18 Sep 2024 18:01:16 -0400 Subject: [PATCH 5/5] Fix test that checks the default cluster dir --- src/python_testing/TestSpecParsingSupport.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/python_testing/TestSpecParsingSupport.py b/src/python_testing/TestSpecParsingSupport.py index 559557150146ad..c7f087cb03d834 100644 --- a/src/python_testing/TestSpecParsingSupport.py +++ b/src/python_testing/TestSpecParsingSupport.py @@ -272,7 +272,8 @@ def test_build_xml_override(self): asserts.assert_equal(set(in_progress.keys())-set(tot_xml_clusters.keys()), set(), "There are some in_progress clusters that are not included in the TOT spec") - str_path = str(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', 'data_model', 'master', 'clusters')) + str_path = str(os.path.join(os.path.dirname(os.path.realpath(__file__)), + '..', '..', 'data_model', 'in_progress', 'clusters')) string_override_check, problems = build_xml_clusters(str_path) asserts.assert_equal(string_override_check.keys(), self.spec_xml_clusters.keys(), "Mismatched cluster generation")