From c3222ef733ecbd1325352fcaa52d2c8ab4dd7f06 Mon Sep 17 00:00:00 2001 From: "David F. Mulcahey" <david.mulcahey@me.com> Date: Sun, 28 Jan 2024 13:28:06 -0500 Subject: [PATCH] Fix statuses for ZHA attribute reporting configuration event (#108532) Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com> --- .../zha/core/cluster_handlers/__init__.py | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/zha/core/cluster_handlers/__init__.py b/homeassistant/components/zha/core/cluster_handlers/__init__.py index c72d84adecd..65137d683de 100644 --- a/homeassistant/components/zha/core/cluster_handlers/__init__.py +++ b/homeassistant/components/zha/core/cluster_handlers/__init__.py @@ -262,7 +262,7 @@ class ClusterHandler(LogMixin): "id": attr, "name": attr_name, "change": config[2], - "success": False, + "status": None, } to_configure = [*self.REPORT_CONFIG] @@ -274,10 +274,7 @@ class ClusterHandler(LogMixin): reports = {rec["attr"]: rec["config"] for rec in chunk} try: res = await self.cluster.configure_reporting_multiple(reports, **kwargs) - self._configure_reporting_status(reports, res[0]) - # if we get a response, then it's a success - for attr_stat in event_data.values(): - attr_stat["success"] = True + self._configure_reporting_status(reports, res[0], event_data) except (zigpy.exceptions.ZigbeeException, asyncio.TimeoutError) as ex: self.debug( "failed to set reporting on '%s' cluster for: %s", @@ -304,7 +301,10 @@ class ClusterHandler(LogMixin): ) def _configure_reporting_status( - self, attrs: dict[str, tuple[int, int, float | int]], res: list | tuple + self, + attrs: dict[str, tuple[int, int, float | int]], + res: list | tuple, + event_data: dict[str, dict[str, Any]], ) -> None: """Parse configure reporting result.""" if isinstance(res, (Exception, ConfigureReportingResponseRecord)): @@ -315,6 +315,8 @@ class ClusterHandler(LogMixin): self.name, res, ) + for attr in attrs: + event_data[attr]["status"] = Status.FAILURE.name return if res[0].status == Status.SUCCESS and len(res) == 1: self.debug( @@ -323,24 +325,38 @@ class ClusterHandler(LogMixin): self.name, res, ) + # 2.5.8.1.3 Status Field + # The status field specifies the status of the Configure Reporting operation attempted on this attribute, as detailed in 2.5.7.3. + # Note that attribute status records are not included for successfully configured attributes, in order to save bandwidth. + # In the case of successful configuration of all attributes, only a single attribute status record SHALL be included in the command, + # with the status field set to SUCCESS and the direction and attribute identifier fields omitted. + for attr in attrs: + event_data[attr]["status"] = Status.SUCCESS.name return + for record in res: + event_data[self.cluster.find_attribute(record.attrid).name][ + "status" + ] = record.status.name failed = [ self.cluster.find_attribute(record.attrid).name for record in res if record.status != Status.SUCCESS ] - self.debug( - "Successfully configured reporting for '%s' on '%s' cluster", - set(attrs) - set(failed), - self.name, - ) self.debug( "Failed to configure reporting for '%s' on '%s' cluster: %s", failed, self.name, res, ) + success = set(attrs) - set(failed) + self.debug( + "Successfully configured reporting for '%s' on '%s' cluster", + set(attrs) - set(failed), + self.name, + ) + for attr in success: + event_data[attr]["status"] = Status.SUCCESS.name async def async_configure(self) -> None: """Set cluster binding and attribute reporting.""" -- GitLab