Skip to content
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

Add support for ZHA entities exposed by Zigpy quirks #111176

Merged
merged 44 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
e19a26a
Add counter entities to the ZHA coordinator device
dmulcahey Feb 3, 2024
fbac356
rework to prepare for non coordinator device counters
dmulcahey Feb 4, 2024
29edee1
Initial scaffolding to support quirks v2 entities
dmulcahey Feb 5, 2024
701d4ba
update for zigpy changes
dmulcahey Feb 9, 2024
5eb9ef8
add assertion error message
dmulcahey Feb 9, 2024
ede11e5
clean up test
dmulcahey Feb 9, 2024
7d02aed
update group entity discovery kwargs
dmulcahey Feb 9, 2024
a52d5cd
constants and clearer names
dmulcahey Feb 10, 2024
307dfe9
apply custom device configuration
dmulcahey Feb 10, 2024
b8e1337
quirks switches
dmulcahey Feb 10, 2024
f167ded
quirks select entities
dmulcahey Feb 10, 2024
b5f5951
quirks sensor entities
dmulcahey Feb 10, 2024
480fbe3
update discovery
dmulcahey Feb 10, 2024
edd5667
move call to super
dmulcahey Feb 10, 2024
ebd79b4
add complex quirks v2 discovery test
dmulcahey Feb 10, 2024
2b91e33
remove duplicate replaces
dmulcahey Feb 10, 2024
25fa855
add quirks v2 button entity support
dmulcahey Feb 11, 2024
02f4c1d
add quirks v2 binary sensor entity support
dmulcahey Feb 11, 2024
3241b4f
fix exception in counter entitiy discovery
dmulcahey Feb 11, 2024
1947707
oops
dmulcahey Feb 11, 2024
0443485
update formatting
dmulcahey Feb 12, 2024
5bf492e
support custom on and off values
dmulcahey Feb 13, 2024
a1a495f
logging
dmulcahey Feb 13, 2024
df23d95
don't filter out entities quirks says should be created
dmulcahey Feb 20, 2024
60410da
fix type alias warnings
dmulcahey Feb 20, 2024
03784f3
sync up with zigpy changes and additions
dmulcahey Feb 21, 2024
81fcf96
add a binary sensor test
dmulcahey Feb 21, 2024
9ea1733
button coverage
dmulcahey Feb 21, 2024
c36f807
switch coverage
dmulcahey Feb 21, 2024
051798a
initial select coverage
dmulcahey Feb 22, 2024
8aabae7
number coverage
dmulcahey Feb 22, 2024
54e4603
sensor coverage
dmulcahey Feb 22, 2024
df2115f
update discovery after rebase
dmulcahey Feb 28, 2024
e8dd6a1
coverage
dmulcahey Feb 28, 2024
bcc5b27
single line
dmulcahey Feb 29, 2024
64ddc80
line lengths
dmulcahey Feb 29, 2024
5563199
fix double underscore
dmulcahey Feb 29, 2024
de774e6
review comments
dmulcahey Feb 29, 2024
d299c50
set category from quirks in base entity
dmulcahey Feb 29, 2024
2345ab9
line lengths
dmulcahey Feb 29, 2024
bf2dfc3
move comment
dmulcahey Feb 29, 2024
d33609d
imports
dmulcahey Feb 29, 2024
a06cddf
simplify
dmulcahey Feb 29, 2024
24d2221
simplify
dmulcahey Feb 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion homeassistant/components/zha/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import functools
from typing import Any

from zigpy.quirks.v2 import BinarySensorMetadata, EntityMetadata
import zigpy.types as t
from zigpy.zcl.clusters.general import OnOff
from zigpy.zcl.clusters.security import IasZone
Expand All @@ -26,6 +27,7 @@
CLUSTER_HANDLER_OCCUPANCY,
CLUSTER_HANDLER_ON_OFF,
CLUSTER_HANDLER_ZONE,
QUIRK_METADATA,
SIGNAL_ADD_ENTITIES,
SIGNAL_ATTR_UPDATED,
)
Expand Down Expand Up @@ -76,8 +78,16 @@ class BinarySensor(ZhaEntity, BinarySensorEntity):

def __init__(self, unique_id, zha_device, cluster_handlers, **kwargs) -> None:
"""Initialize the ZHA binary sensor."""
super().__init__(unique_id, zha_device, cluster_handlers, **kwargs)
self._cluster_handler = cluster_handlers[0]
if QUIRK_METADATA in kwargs:
self._init_from_quirks_metadata(kwargs[QUIRK_METADATA])
super().__init__(unique_id, zha_device, cluster_handlers, **kwargs)

def _init_from_quirks_metadata(self, entity_metadata: EntityMetadata) -> None:
"""Init this entity from the quirks metadata."""
super()._init_from_quirks_metadata(entity_metadata)
binary_sensor_metadata: BinarySensorMetadata = entity_metadata.entity_metadata
self._attribute_name = binary_sensor_metadata.attribute_name

async def async_added_to_hass(self) -> None:
"""Run when about to be added to hass."""
Expand Down
52 changes: 40 additions & 12 deletions homeassistant/components/zha/button.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
"""Support for ZHA button."""
from __future__ import annotations

import abc
import functools
import logging
from typing import TYPE_CHECKING, Any, Self

from zigpy.quirks.v2 import (
EntityMetadata,
WriteAttributeButtonMetadata,
ZCLCommandButtonMetadata,
)

from homeassistant.components.button import ButtonDeviceClass, ButtonEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory, Platform
Expand All @@ -14,7 +19,7 @@
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .core import discovery
from .core.const import CLUSTER_HANDLER_IDENTIFY, SIGNAL_ADD_ENTITIES
from .core.const import CLUSTER_HANDLER_IDENTIFY, QUIRK_METADATA, SIGNAL_ADD_ENTITIES
from .core.helpers import get_zha_data
from .core.registries import ZHA_ENTITIES
from .entity import ZhaEntity
Expand Down Expand Up @@ -58,6 +63,8 @@ class ZHAButton(ZhaEntity, ButtonEntity):
"""Defines a ZHA button."""

_command_name: str
_args: list[Any]
_kwargs: dict[str, Any]

def __init__(
self,
Expand All @@ -67,18 +74,33 @@ def __init__(
**kwargs: Any,
) -> None:
"""Init this button."""
super().__init__(unique_id, zha_device, cluster_handlers, **kwargs)
self._cluster_handler: ClusterHandler = cluster_handlers[0]
if QUIRK_METADATA in kwargs:
self._init_from_quirks_metadata(kwargs[QUIRK_METADATA])
super().__init__(unique_id, zha_device, cluster_handlers, **kwargs)

def _init_from_quirks_metadata(self, entity_metadata: EntityMetadata) -> None:
"""Init this entity from the quirks metadata."""
super()._init_from_quirks_metadata(entity_metadata)
button_metadata: ZCLCommandButtonMetadata = entity_metadata.entity_metadata
self._command_name = button_metadata.command_name
self._args = button_metadata.args
self._kwargs = button_metadata.kwargs

@abc.abstractmethod
def get_args(self) -> list[Any]:
"""Return the arguments to use in the command."""
return list(self._args) if self._args else []

def get_kwargs(self) -> dict[str, Any]:
"""Return the keyword arguments to use in the command."""
return self._kwargs

async def async_press(self) -> None:
"""Send out a update command."""
command = getattr(self._cluster_handler, self._command_name)
arguments = self.get_args()
await command(*arguments)
arguments = self.get_args() or []
kwargs = self.get_kwargs() or {}
await command(*arguments, **kwargs)


@MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_IDENTIFY)
Expand Down Expand Up @@ -106,11 +128,8 @@ def create_entity(
_attr_device_class = ButtonDeviceClass.IDENTIFY
_attr_entity_category = EntityCategory.DIAGNOSTIC
_command_name = "identify"

def get_args(self) -> list[Any]:
"""Return the arguments to use in the command."""

return [DEFAULT_DURATION]
_kwargs = {}
_args = [DEFAULT_DURATION]


class ZHAAttributeButton(ZhaEntity, ButtonEntity):
Expand All @@ -127,8 +146,17 @@ def __init__(
**kwargs: Any,
) -> None:
"""Init this button."""
super().__init__(unique_id, zha_device, cluster_handlers, **kwargs)
self._cluster_handler: ClusterHandler = cluster_handlers[0]
if QUIRK_METADATA in kwargs:
self._init_from_quirks_metadata(kwargs[QUIRK_METADATA])
super().__init__(unique_id, zha_device, cluster_handlers, **kwargs)

def _init_from_quirks_metadata(self, entity_metadata: EntityMetadata) -> None:
"""Init this entity from the quirks metadata."""
super()._init_from_quirks_metadata(entity_metadata)
button_metadata: WriteAttributeButtonMetadata = entity_metadata.entity_metadata
self._attribute_name = button_metadata.attribute_name
self._attribute_value = button_metadata.attribute_value

async def async_press(self) -> None:
"""Write attribute with defined value."""
Expand Down
6 changes: 6 additions & 0 deletions homeassistant/components/zha/core/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
BAUD_RATES = [2400, 4800, 9600, 14400, 19200, 38400, 57600, 115200, 128000, 256000]
BINDINGS = "bindings"

CLUSTER_DETAILS = "cluster_details"

CLUSTER_HANDLER_ACCELEROMETER = "accelerometer"
CLUSTER_HANDLER_BINARY_INPUT = "binary_input"
CLUSTER_HANDLER_ANALOG_INPUT = "analog_input"
Expand Down Expand Up @@ -230,6 +232,10 @@
PRESET_COMPLEX = "Complex"
PRESET_TEMP_MANUAL = "Temporary manual"

QUIRK_METADATA = "quirk_metadata"

ZCL_INIT_ATTRS = "ZCL_INIT_ATTRS"

ZHA_ALARM_OPTIONS = "zha_alarm_options"
ZHA_OPTIONS = "zha_options"

Expand Down
4 changes: 4 additions & 0 deletions homeassistant/components/zha/core/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import zigpy.exceptions
from zigpy.profiles import PROFILES
import zigpy.quirks
from zigpy.quirks.v2 import CustomDeviceV2
from zigpy.types.named import EUI64, NWK
from zigpy.zcl.clusters import Cluster
from zigpy.zcl.clusters.general import Groups, Identify
Expand Down Expand Up @@ -582,6 +583,9 @@ async def async_configure(self) -> None:
await asyncio.gather(
*(endpoint.async_configure() for endpoint in self._endpoints.values())
)
if isinstance(self._zigpy_device, CustomDeviceV2):
self.debug("applying quirks v2 custom device configuration")
await self._zigpy_device.apply_custom_configuration()
async_dispatcher_send(
self.hass,
const.ZHA_CLUSTER_HANDLER_MSG,
Expand Down
Loading
Loading