diff --git a/scripts/py_matter_yamltests/matter_yamltests/definitions.py b/scripts/py_matter_yamltests/matter_yamltests/definitions.py
index 9cf5786dca7a76..4e6d8d9e0c177b 100644
--- a/scripts/py_matter_yamltests/matter_yamltests/definitions.py
+++ b/scripts/py_matter_yamltests/matter_yamltests/definitions.py
@@ -16,11 +16,14 @@
import enum
import functools
import glob
-from typing import List
+import io
+from typing import List, Optional
from matter_idl.matter_idl_types import *
from matter_idl.zapxml import ParseSource, ParseXmls
+from .pseudo_clusters.pseudo_clusters import PseudoClusters
+
class _ItemType(enum.Enum):
Cluster = 0
@@ -240,7 +243,7 @@ def __enforce_casing(self, target_name: str, targets: list):
f'Unknown target {target_name}. Did you mean {name} ?')
-def SpecDefinitionsFromPaths(paths: str):
+def SpecDefinitionsFromPaths(paths: str, pseudo_clusters: Optional[PseudoClusters] = PseudoClusters([])):
def sort_with_global_attribute_first(a, b):
if a.endswith('global-attributes.xml'):
return -1
@@ -262,4 +265,12 @@ def sort_with_global_attribute_first(a, b):
filenames.sort(key=functools.cmp_to_key(sort_with_global_attribute_first))
sources = [ParseSource(source=name) for name in filenames]
+
+ for pseudo_cluster in pseudo_clusters.clusters:
+ if pseudo_cluster.definition is not None:
+ name = pseudo_cluster.name
+ definition = pseudo_cluster.definition
+ sources = (
+ sources + [ParseSource(source=io.StringIO(definition), name=name)])
+
return SpecDefinitions(sources)
diff --git a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/delay_commands.py b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/delay_commands.py
index 9cf90fab89b32c..0536dd2bfb4110 100644
--- a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/delay_commands.py
+++ b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/delay_commands.py
@@ -19,9 +19,36 @@
from ..pseudo_cluster import PseudoCluster
from .accessory_server_bridge import AccessoryServerBridge
+_DEFINITION = '''
+
+
+ DelayCommands
+ 0xFFF1FD02
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+'''
+
class DelayCommands(PseudoCluster):
name = 'DelayCommands'
+ definition = _DEFINITION
async def WaitForMs(self, request):
duration_in_ms = 0
diff --git a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/log_commands.py b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/log_commands.py
index 802553a8857e97..00a98e285c84e6 100644
--- a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/log_commands.py
+++ b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/log_commands.py
@@ -15,9 +15,28 @@
from ..pseudo_cluster import PseudoCluster
+_DEFINITION = '''
+
+
+ LogCommands
+ 0xFFF1FD01
+
+
+
+
+
+
+
+
+
+
+
+'''
+
class LogCommands(PseudoCluster):
name = 'LogCommands'
+ definition = _DEFINITION
async def UserPrompt(self, request):
pass
diff --git a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/system_commands.py b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/system_commands.py
index eb46438a3502b7..4f082e710b22ed 100644
--- a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/system_commands.py
+++ b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/clusters/system_commands.py
@@ -16,9 +16,53 @@
from ..pseudo_cluster import PseudoCluster
from .accessory_server_bridge import AccessoryServerBridge
+_DEFINITION = '''
+
+
+ SystemCommands
+ 0xFFF1FD03
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+'''
+
class SystemCommands(PseudoCluster):
name = 'SystemCommands'
+ definition = _DEFINITION
async def Start(self, request):
AccessoryServerBridge.start(request)
diff --git a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/pseudo_cluster.py b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/pseudo_cluster.py
index 5e8aa53950a4ff..4bc016dfc30850 100644
--- a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/pseudo_cluster.py
+++ b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/pseudo_cluster.py
@@ -34,9 +34,6 @@ class CustomCommand(PseudoCluster):
async def MyCustomMethod(self, request):
pass
- async def MyCustomMethod(self, request):
- pass
-
It can then be called from any test step as:
- label: "Call a custom method"
@@ -46,8 +43,37 @@ async def MyCustomMethod(self, request):
values:
- name: "MyCustomParameter"
value: "this_is_a_custom_value"
+
+ A pseudo cluster can optionally declare a definition in order to benefit
+ from automatic command names checking and argument names validation.
+
+ For example, the 'CustomCommands' pseudo cluster can be implemented as:
+
+ _DEFINITION = '''
+
+
+ CustomCommands
+ 0xFFF1FD00
+
+
+
+
+
+
+ '''
+
+ class CustomCommand(PseudoCluster):
+ name = 'CustomCommands'
+ definition = _DEFINITION
+
+ async def MyCustomMethod(self, request):
+ pass
"""
@abstractproperty
def name(self):
pass
+
+ @property
+ def definition(self):
+ return None
diff --git a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/pseudo_clusters.py b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/pseudo_clusters.py
index 18bd65f0612dc0..58ff3bcb7f99f9 100644
--- a/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/pseudo_clusters.py
+++ b/scripts/py_matter_yamltests/matter_yamltests/pseudo_clusters/pseudo_clusters.py
@@ -20,7 +20,7 @@
class PseudoClusters:
def __init__(self, clusters: list[PseudoCluster]):
- self.__clusters = clusters
+ self.clusters = clusters
def supports(self, request) -> bool:
return False if self.__get_command(request) is None else True
@@ -38,7 +38,7 @@ async def execute(self, request):
return status, []
def __get_command(self, request):
- for cluster in self.__clusters:
+ for cluster in self.clusters:
if request.cluster == cluster.name and getattr(cluster, request.command, None):
return getattr(cluster, request.command)
return None