-
Couldn't load subscription status.
- Fork 53
Read out the supported and unsupported attribute of a device at configure #101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
4962ff5
48c5111
1110a5a
744a031
b1aba9a
474925c
0fbbad4
f97d8b3
882e038
c16d356
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,11 +11,15 @@ | |
| from typing import TYPE_CHECKING, Any, Final, ParamSpec, TypedDict | ||
|
|
||
| import zigpy.exceptions | ||
| import zigpy.types | ||
| import zigpy.util | ||
| import zigpy.zcl | ||
| from zigpy.zcl.foundation import ( | ||
| GENERAL_COMMANDS, | ||
| CommandSchema, | ||
| ConfigureReportingResponseRecord, | ||
| DiscoverAttributesResponseRecord, | ||
| GeneralCommand, | ||
| Status, | ||
| ZCLAttributeDef, | ||
| ) | ||
|
|
@@ -441,6 +445,7 @@ async def async_configure(self) -> None: | |
| if ch_specific_cfg: | ||
| self.debug("Performing cluster handler specific configuration") | ||
| await ch_specific_cfg() | ||
|
|
||
| self.debug("finished cluster handler configuration") | ||
| else: | ||
| self.debug("skipping cluster handler configuration") | ||
|
|
@@ -458,6 +463,10 @@ async def async_initialize(self, from_cache: bool) -> None: | |
| uncached = [a for a, cached in self.ZCL_INIT_ATTRS.items() if not cached] | ||
| uncached.extend([cfg["attr"] for cfg in self.REPORT_CONFIG]) | ||
|
|
||
| if not from_cache: | ||
| self.debug("discovering unsupported attributes") | ||
| await self.discover_unsupported_attributes() | ||
|
|
||
| if cached: | ||
| self.debug("initializing cached cluster handler attributes: %s", cached) | ||
| await self._get_attributes( | ||
|
|
@@ -624,6 +633,47 @@ async def write_attributes_safe( | |
| f"Failed to write attribute {name}={value}: {record.status}", | ||
| ) | ||
|
|
||
| async def _discover_attributes_all( | ||
| self, | ||
| ) -> list[DiscoverAttributesResponseRecord] | None: | ||
| discovery_complete = zigpy.types.Bool.false | ||
| start_attribute_id = 0 | ||
| attribute_info = [] | ||
| cluster = self.cluster | ||
| while discovery_complete != zigpy.types.Bool.true: | ||
| rsp = await cluster.discover_attributes( | ||
| start_attribute_id=start_attribute_id, max_attribute_ids=0xFF | ||
| ) | ||
| if not isinstance( | ||
| rsp, GENERAL_COMMANDS[GeneralCommand.Discover_Attributes_rsp].schema | ||
| ): | ||
| self.debug( | ||
| "Ignoring attribute discovery due to unexpected default response: %r", | ||
| rsp, | ||
| ) | ||
| return None | ||
|
|
||
| attribute_info.extend(rsp.attribute_info) | ||
| discovery_complete = rsp.discovery_complete | ||
| start_attribute_id = ( | ||
| max((info.attrid for info in rsp.attribute_info), default=0) + 1 | ||
| ) | ||
| return attribute_info | ||
|
|
||
| async def discover_unsupported_attributes(self): | ||
| """Discover the list of unsupported attributes from the device.""" | ||
| attribute_info = await self._discover_attributes_all() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also i'm not fully sure what type of errors devices might respond with here. We may want to gracefully handle some things. For example, the GeneralCommand.Default_Response response is sent by some quirks here which seem utterly wrong. |
||
| if attribute_info is None: | ||
| return | ||
| attr_ids = {info.attrid for info in attribute_info} | ||
|
|
||
| cluster = self.cluster | ||
| for attr_id in cluster.attributes: | ||
| if attr_id in attr_ids: | ||
| cluster.remove_unsupported_attribute(attr_id) | ||
| else: | ||
| cluster.add_unsupported_attribute(attr_id) | ||
|
|
||
| def log(self, level, msg, *args, **kwargs) -> None: | ||
| """Log a message.""" | ||
| msg = f"[%s:%s]: {msg}" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wan't sure if this should go here in ZHA or in ZIGPY. The cache of unsupported attributes does exist in ZIGPY.