Skip to content

Commit 42e57ff

Browse files
committed
Update unsupported attribute on configure
This allow us to only display available attributes.
1 parent 70b6e91 commit 42e57ff

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

zha/zigbee/cluster_handlers/__init__.py

+47
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@
1111
from typing import TYPE_CHECKING, Any, Final, ParamSpec, TypedDict
1212

1313
import zigpy.exceptions
14+
import zigpy.types
1415
import zigpy.util
1516
import zigpy.zcl
1617
from zigpy.zcl.foundation import (
1718
CommandSchema,
1819
ConfigureReportingResponseRecord,
20+
DiscoverAttributesResponseRecord,
21+
GeneralCommand,
1922
Status,
2023
ZCLAttributeDef,
2124
)
@@ -441,6 +444,10 @@ async def async_configure(self) -> None:
441444
if ch_specific_cfg:
442445
self.debug("Performing cluster handler specific configuration")
443446
await ch_specific_cfg()
447+
448+
self.debug("Discovering available attributes")
449+
await self.discover_unsupported_attributes()
450+
444451
self.debug("finished cluster handler configuration")
445452
else:
446453
self.debug("skipping cluster handler configuration")
@@ -624,6 +631,46 @@ async def write_attributes_safe(
624631
f"Failed to write attribute {name}={value}: {record.status}",
625632
)
626633

634+
async def _discover_attributes_all(
635+
self,
636+
) -> list[DiscoverAttributesResponseRecord] | None:
637+
discovery_complete = zigpy.types.Bool.false
638+
start_attribute_id = 0
639+
attribute_info = []
640+
cluster = self.cluster
641+
while discovery_complete != zigpy.types.Bool.true:
642+
rsp = await cluster.discover_attributes(
643+
start_attribute_id=start_attribute_id, max_attribute_ids=0xFF
644+
)
645+
assert rsp, "Must have a response to discover request"
646+
647+
if rsp.command.id == GeneralCommand.Default_Response:
648+
self.debug(
649+
"Ignoring attribute discovery due to unexpected default response"
650+
)
651+
return None
652+
653+
attribute_info.extend(rsp.attribute_info)
654+
discovery_complete = rsp.discovery_complete
655+
start_attribute_id = (
656+
max((info.attrid for info in rsp.attribute_info), default=0) + 1
657+
)
658+
return attribute_info
659+
660+
async def discover_unsupported_attributes(self):
661+
"""Discover the list of unsupported attributes from the device."""
662+
attribute_info = await self._discover_attributes_all()
663+
if attribute_info is None:
664+
return
665+
attr_ids = {info.attrid for info in attribute_info}
666+
667+
cluster = self.cluster
668+
for attr_id in cluster.attributes:
669+
if attr_id in attr_ids:
670+
cluster.remove_unsupported_attribute(attr_id)
671+
else:
672+
cluster.add_unsupported_attribute(attr_id)
673+
627674
def log(self, level, msg, *args, **kwargs) -> None:
628675
"""Log a message."""
629676
msg = f"[%s:%s]: {msg}"

0 commit comments

Comments
 (0)