From 4798771273df583af5435abb5472d9b3633264a8 Mon Sep 17 00:00:00 2001 From: tianfeng-yang <130436698+tianfeng-yang@users.noreply.github.com> Date: Thu, 22 Jun 2023 00:42:23 +0800 Subject: [PATCH] [Python] export cluster status when sendCommand failed (#27335) --- .../python/chip/clusters/Command.py | 13 +++++++----- .../python/chip/interaction_model/__init__.py | 20 +++++++++++++++++-- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/controller/python/chip/clusters/Command.py b/src/controller/python/chip/clusters/Command.py index df2037192e24c3..5ce2f4c620db4a 100644 --- a/src/controller/python/chip/clusters/Command.py +++ b/src/controller/python/chip/clusters/Command.py @@ -64,7 +64,8 @@ def FindCommandClusterObject(isClientSideCommand: bool, path: CommandPath): if inspect.isclass(command): for name, field in inspect.getmembers(command): if ('__dataclass_fields__' in name): - if (field['cluster_id'].default == path.ClusterId) and (field['command_id'].default == path.CommandId) and (field['is_client'].default == isClientSideCommand): + if (field['cluster_id'].default == path.ClusterId) and (field['command_id'].default == + path.CommandId) and (field['is_client'].default == isClientSideCommand): return eval('chip.clusters.Objects.' + clusterName + '.Commands.' + commandName) return None @@ -105,11 +106,11 @@ def _handleError(self, imError: Status, chipError: PyChipError, exception: Excep else: try: self._future.set_exception( - chip.interaction_model.InteractionModelError(chip.interaction_model.Status(imError.IMStatus))) + chip.interaction_model.InteractionModelError(chip.interaction_model.Status(imError.IMStatus), imError.ClusterStatus)) except Exception as e2: logger.exception("Failed to map interaction model status received: %s. Remapping to Failure." % imError) self._future.set_exception(chip.interaction_model.InteractionModelError( - chip.interaction_model.Status.Failure)) + chip.interaction_model.Status.Failure, imError.ClusterStatus)) def handleError(self, status: Status, chipError: PyChipError): self._event_loop.call_soon_threadsafe( @@ -126,7 +127,8 @@ def handleError(self, status: Status, chipError: PyChipError): @_OnCommandSenderResponseCallbackFunct -def _OnCommandSenderResponseCallback(closure, endpoint: int, cluster: int, command: int, imStatus: int, clusterStatus: int, payload, size): +def _OnCommandSenderResponseCallback(closure, endpoint: int, cluster: int, command: int, + imStatus: int, clusterStatus: int, payload, size): data = ctypes.string_at(payload, size) closure.handleResponse(CommandPath(endpoint, cluster, command), Status( imStatus, clusterStatus), data[:]) @@ -142,7 +144,8 @@ def _OnCommandSenderDoneCallback(closure): ctypes.pythonapi.Py_DecRef(ctypes.py_object(closure)) -def SendCommand(future: Future, eventLoop, responseType: Type, device, commandPath: CommandPath, payload: ClusterCommand, timedRequestTimeoutMs: Union[None, int] = None, interactionTimeoutMs: Union[None, int] = None, busyWaitMs: Union[None, int] = None) -> PyChipError: +def SendCommand(future: Future, eventLoop, responseType: Type, device, commandPath: CommandPath, payload: ClusterCommand, + timedRequestTimeoutMs: Union[None, int] = None, interactionTimeoutMs: Union[None, int] = None, busyWaitMs: Union[None, int] = None) -> PyChipError: ''' Send a cluster-object encapsulated command to a device and does the following: - On receipt of a successful data response, returns the cluster-object equivalent through the provided future. - None (on a successful response containing no data) diff --git a/src/controller/python/chip/interaction_model/__init__.py b/src/controller/python/chip/interaction_model/__init__.py index 1b9fc2177e242e..a2c9e1479397fa 100644 --- a/src/controller/python/chip/interaction_model/__init__.py +++ b/src/controller/python/chip/interaction_model/__init__.py @@ -31,6 +31,10 @@ __all__ = ["Status", "InteractionModelError"] +# defined src/controller/python/chip/interaction_model/Delegate.h +kUndefinedClusterStatus: int = 0xFF + + class Status(enum.IntEnum): Success = 0x0 Failure = 0x01 @@ -79,12 +83,24 @@ class Status(enum.IntEnum): class InteractionModelError(ChipStackException): - def __init__(self, status: Status): + def __init__(self, status: Status, clusterStatus: int = kUndefinedClusterStatus): self._status = status + self._clusterStatus = clusterStatus def __str__(self): - return f"InteractionModelError: {self._status.name} (0x{self._status.value:x})" + if self.hasClusterStatus: + return f"InteractionModelError: {self._status.name} (0x{self._status.value:x}, clusterStatus: {self._clusterStatus})" + else: + return f"InteractionModelError: {self._status.name} (0x{self._status.value:x})" + + @property + def hasClusterStatus(self) -> bool: + return self._clusterStatus != kUndefinedClusterStatus @property def status(self) -> Status: return self._status + + @property + def clusterStatus(self) -> int: + return self._clusterStatus