Skip to content

Commit 9cf5a3f

Browse files
cecillerestyled-commits
authored andcommitted
Spec parsing: Add global commands for thermostat (project-chip#35607)
* Spec parsing: Add global commands for thermostat * use in-progress for clusters too * Fix command check (merge conflict?) * Restyled by isort * Fix test that checks the default cluster dir --------- Co-authored-by: Restyled.io <commits@restyled.io>
1 parent 61dbd81 commit 9cf5a3f

File tree

3 files changed

+50
-6
lines changed

3 files changed

+50
-6
lines changed

src/python_testing/TC_DeviceConformance.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ def record_warning(location, problem):
166166
if attribute_id not in self.xml_clusters[cluster_id].attributes.keys():
167167
# TODO: Consolidate the range checks with IDM-10.1 once that lands
168168
if attribute_id <= 0x4FFF:
169-
# manufacturer attribute
170169
record_error(location=location, problem='Standard attribute found on device, but not in spec')
171170
continue
172171
xml_attribute = self.xml_clusters[cluster_id].attributes[attribute_id]
@@ -193,9 +192,7 @@ def check_spec_conformance_for_commands(command_type: CommandType):
193192
if command_id not in xml_commands_dict:
194193
# TODO: Consolidate range checks with IDM-10.1 once that lands
195194
if command_id <= 0xFF:
196-
# manufacturer command
197-
continue
198-
record_error(location=location, problem='Standard command found on device, but not in spec')
195+
record_error(location=location, problem='Standard command found on device, but not in spec')
199196
continue
200197
xml_command = xml_commands_dict[command_id]
201198
conformance_decision_with_choice = xml_command.conformance(feature_map, attribute_list, all_command_list)

src/python_testing/TestSpecParsingSupport.py

+28-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ def test_build_xml_override(self):
272272
asserts.assert_equal(set(in_progress.keys())-set(tot_xml_clusters.keys()),
273273
set(), "There are some in_progress clusters that are not included in the TOT spec")
274274

275-
str_path = str(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', 'data_model', 'master', 'clusters'))
275+
str_path = str(os.path.join(os.path.dirname(os.path.realpath(__file__)),
276+
'..', '..', 'data_model', 'in_progress', 'clusters'))
276277
string_override_check, problems = build_xml_clusters(str_path)
277278
asserts.assert_equal(string_override_check.keys(), self.spec_xml_clusters.keys(), "Mismatched cluster generation")
278279

@@ -462,6 +463,32 @@ def test_provisional_clusters(self):
462463
asserts.assert_in(id, clusters.keys(), "Non-provisional cluster not parsed")
463464
asserts.assert_false(clusters[id].is_provisional, "Non-provisional cluster marked as provisional")
464465

466+
def test_atomic_thermostat(self):
467+
tot_xml_clusters, problems = build_xml_clusters(PrebuiltDataModelDirectory.kMaster)
468+
one_three_clusters, problems = build_xml_clusters(PrebuiltDataModelDirectory.k1_3)
469+
in_progress, problems = build_xml_clusters(PrebuiltDataModelDirectory.kInProgress)
470+
471+
asserts.assert_in("Atomic Request", tot_xml_clusters[Clusters.Thermostat.id].command_map,
472+
"Atomic request not found on thermostat command map")
473+
request_id = tot_xml_clusters[Clusters.Thermostat.id].command_map["Atomic Request"]
474+
asserts.assert_in(request_id, tot_xml_clusters[Clusters.Thermostat.id].accepted_commands.keys(),
475+
"Atomic request not found in thermostat accepted command list")
476+
477+
asserts.assert_in("Atomic Response", tot_xml_clusters[Clusters.Thermostat.id].command_map,
478+
"Atomic response not found in the thermostat command map")
479+
response_id = tot_xml_clusters[Clusters.Thermostat.id].command_map["Atomic Response"]
480+
asserts.assert_in(response_id, tot_xml_clusters[Clusters.Thermostat.id].generated_commands.keys(),
481+
"Atomic response not found in thermostat generated command list")
482+
483+
asserts.assert_not_in(
484+
"Atomic Request", one_three_clusters[Clusters.Thermostat.id].command_map, "Atomic request found on thermostat command map for 1.3")
485+
asserts.assert_not_in(request_id, one_three_clusters[Clusters.Thermostat.id].accepted_commands.keys(),
486+
"Atomic request found in thermostat accepted command list for 1.3")
487+
asserts.assert_not_in(
488+
"Atomic Response", one_three_clusters[Clusters.Thermostat.id].command_map, "Atomic response found on thermostat command map for 1.3")
489+
asserts.assert_not_in(response_id, one_three_clusters[Clusters.Thermostat.id].generated_commands.keys(),
490+
"Atomic request found in thermostat generated command list for 1.3")
491+
465492

466493
if __name__ == "__main__":
467494
default_matter_test_main()

src/python_testing/spec_parsing_support.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from typing import Callable, Optional
2727

2828
import chip.clusters as Clusters
29+
import conformance_support
2930
from chip.tlv import uint
3031
from conformance_support import (OPTIONAL_CONFORM, TOP_LEVEL_CONFORMANCE_TAGS, ConformanceDecision, ConformanceException,
3132
ConformanceParseParameters, feature, is_disallowed, mandatory, optional, or_operation,
@@ -528,7 +529,7 @@ def _get_data_model_directory(data_model_directory: typing.Union[PrebuiltDataMod
528529
return data_model_directory
529530

530531

531-
def build_xml_clusters(data_model_directory: typing.Union[PrebuiltDataModelDirectory, str] = PrebuiltDataModelDirectory.kMaster) -> tuple[dict[uint, XmlCluster], list[ProblemNotice]]:
532+
def build_xml_clusters(data_model_directory: typing.Union[PrebuiltDataModelDirectory, str] = PrebuiltDataModelDirectory.kInProgress) -> tuple[dict[uint, XmlCluster], list[ProblemNotice]]:
532533
dir = _get_data_model_directory(data_model_directory, DataModelLevel.kCluster)
533534

534535
clusters: dict[int, XmlCluster] = {}
@@ -611,6 +612,25 @@ def remove_problem(location: typing.Union[CommandPathLocation, FeaturePathLocati
611612
0x05: XmlAttribute(name='SupportedTemperatureLevels', datatype='list', conformance=feature(0x02, 'TL'), read_access=view, write_access=none, write_optional=False),
612613
}
613614

615+
# TODO: Need automated parsing for atomic attributes.
616+
atomic_request_cmd_id = 0xFE
617+
atomic_response_cmd_id = 0xFD
618+
atomic_request_name = "Atomic Request"
619+
atomic_response_name = "Atomic Response"
620+
presets_name = "Presets"
621+
schedules_name = "Schedules"
622+
if clusters[Clusters.Thermostat.id].revision >= 8:
623+
presents_id = clusters[Clusters.Thermostat.id].attribute_map[presets_name]
624+
schedules_id = clusters[Clusters.Thermostat.id].attribute_map[schedules_name]
625+
conformance = or_operation([conformance_support.attribute(presents_id, presets_name),
626+
conformance_support.attribute(schedules_id, schedules_name)])
627+
clusters[Clusters.Thermostat.id].accepted_commands[atomic_request_cmd_id] = XmlCommand(
628+
id=atomic_request_cmd_id, name=atomic_request_name, conformance=conformance)
629+
clusters[Clusters.Thermostat.id].generated_commands[atomic_response_cmd_id] = XmlCommand(
630+
id=atomic_response_cmd_id, name=atomic_response_name, conformance=conformance)
631+
clusters[Clusters.Thermostat.id].command_map[atomic_request_name] = atomic_request_cmd_id
632+
clusters[Clusters.Thermostat.id].command_map[atomic_response_name] = atomic_response_cmd_id
633+
614634
check_clusters_for_unknown_commands(clusters, problems)
615635

616636
return clusters, problems

0 commit comments

Comments
 (0)