193 lines
5.8 KiB
Python
193 lines
5.8 KiB
Python
"""Support for ZHA button."""
|
|
from __future__ import annotations
|
|
|
|
import abc
|
|
import functools
|
|
import logging
|
|
from typing import TYPE_CHECKING, Any, Self
|
|
|
|
from homeassistant.components.button import ButtonDeviceClass, ButtonEntity
|
|
from homeassistant.config_entries import ConfigEntry
|
|
from homeassistant.const import EntityCategory, Platform
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
|
|
from .core import discovery
|
|
from .core.const import CLUSTER_HANDLER_IDENTIFY, SIGNAL_ADD_ENTITIES
|
|
from .core.helpers import get_zha_data
|
|
from .core.registries import ZHA_ENTITIES
|
|
from .entity import ZhaEntity
|
|
|
|
if TYPE_CHECKING:
|
|
from .core.cluster_handlers import ClusterHandler
|
|
from .core.device import ZHADevice
|
|
|
|
|
|
MULTI_MATCH = functools.partial(ZHA_ENTITIES.multipass_match, Platform.BUTTON)
|
|
CONFIG_DIAGNOSTIC_MATCH = functools.partial(
|
|
ZHA_ENTITIES.config_diagnostic_match, Platform.BUTTON
|
|
)
|
|
DEFAULT_DURATION = 5 # seconds
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
config_entry: ConfigEntry,
|
|
async_add_entities: AddEntitiesCallback,
|
|
) -> None:
|
|
"""Set up the Zigbee Home Automation button from config entry."""
|
|
zha_data = get_zha_data(hass)
|
|
entities_to_create = zha_data.platforms[Platform.BUTTON]
|
|
|
|
unsub = async_dispatcher_connect(
|
|
hass,
|
|
SIGNAL_ADD_ENTITIES,
|
|
functools.partial(
|
|
discovery.async_add_entities,
|
|
async_add_entities,
|
|
entities_to_create,
|
|
),
|
|
)
|
|
config_entry.async_on_unload(unsub)
|
|
|
|
|
|
class ZHAButton(ZhaEntity, ButtonEntity):
|
|
"""Defines a ZHA button."""
|
|
|
|
_command_name: str
|
|
|
|
def __init__(
|
|
self,
|
|
unique_id: str,
|
|
zha_device: ZHADevice,
|
|
cluster_handlers: list[ClusterHandler],
|
|
**kwargs: Any,
|
|
) -> None:
|
|
"""Init this button."""
|
|
super().__init__(unique_id, zha_device, cluster_handlers, **kwargs)
|
|
self._cluster_handler: ClusterHandler = cluster_handlers[0]
|
|
|
|
@abc.abstractmethod
|
|
def get_args(self) -> list[Any]:
|
|
"""Return the arguments to use in the command."""
|
|
|
|
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)
|
|
|
|
|
|
@MULTI_MATCH(cluster_handler_names=CLUSTER_HANDLER_IDENTIFY)
|
|
class ZHAIdentifyButton(ZHAButton):
|
|
"""Defines a ZHA identify button."""
|
|
|
|
@classmethod
|
|
def create_entity(
|
|
cls,
|
|
unique_id: str,
|
|
zha_device: ZHADevice,
|
|
cluster_handlers: list[ClusterHandler],
|
|
**kwargs: Any,
|
|
) -> Self | None:
|
|
"""Entity Factory.
|
|
|
|
Return entity if it is a supported configuration, otherwise return None
|
|
"""
|
|
if ZHA_ENTITIES.prevent_entity_creation(
|
|
Platform.BUTTON, zha_device.ieee, CLUSTER_HANDLER_IDENTIFY
|
|
):
|
|
return None
|
|
return cls(unique_id, zha_device, cluster_handlers, **kwargs)
|
|
|
|
_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]
|
|
|
|
|
|
class ZHAAttributeButton(ZhaEntity, ButtonEntity):
|
|
"""Defines a ZHA button, which writes a value to an attribute."""
|
|
|
|
_attribute_name: str
|
|
_attribute_value: Any = None
|
|
|
|
def __init__(
|
|
self,
|
|
unique_id: str,
|
|
zha_device: ZHADevice,
|
|
cluster_handlers: list[ClusterHandler],
|
|
**kwargs: Any,
|
|
) -> None:
|
|
"""Init this button."""
|
|
super().__init__(unique_id, zha_device, cluster_handlers, **kwargs)
|
|
self._cluster_handler: ClusterHandler = cluster_handlers[0]
|
|
|
|
async def async_press(self) -> None:
|
|
"""Write attribute with defined value."""
|
|
await self._cluster_handler.write_attributes_safe(
|
|
{self._attribute_name: self._attribute_value}
|
|
)
|
|
self.async_write_ha_state()
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(
|
|
cluster_handler_names="tuya_manufacturer",
|
|
manufacturers={
|
|
"_TZE200_htnnfasr",
|
|
},
|
|
)
|
|
class FrostLockResetButton(ZHAAttributeButton):
|
|
"""Defines a ZHA frost lock reset button."""
|
|
|
|
_unique_id_suffix = "reset_frost_lock"
|
|
_attribute_name = "frost_lock_reset"
|
|
_attribute_value = 0
|
|
_attr_device_class = ButtonDeviceClass.RESTART
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_translation_key = "reset_frost_lock"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(
|
|
cluster_handler_names="opple_cluster", models={"lumi.motion.ac01"}
|
|
)
|
|
class NoPresenceStatusResetButton(ZHAAttributeButton):
|
|
"""Defines a ZHA no presence status reset button."""
|
|
|
|
_unique_id_suffix = "reset_no_presence_status"
|
|
_attribute_name = "reset_no_presence_status"
|
|
_attribute_value = 1
|
|
_attr_device_class = ButtonDeviceClass.RESTART
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_translation_key = "reset_no_presence_status"
|
|
|
|
|
|
@MULTI_MATCH(cluster_handler_names="opple_cluster", models={"aqara.feeder.acn001"})
|
|
class AqaraPetFeederFeedButton(ZHAAttributeButton):
|
|
"""Defines a feed button for the aqara c1 pet feeder."""
|
|
|
|
_unique_id_suffix = "feeding"
|
|
_attribute_name = "feeding"
|
|
_attribute_value = 1
|
|
_attr_translation_key = "feed"
|
|
|
|
|
|
@CONFIG_DIAGNOSTIC_MATCH(
|
|
cluster_handler_names="opple_cluster", models={"lumi.sensor_smoke.acn03"}
|
|
)
|
|
class AqaraSelfTestButton(ZHAAttributeButton):
|
|
"""Defines a ZHA self-test button for Aqara smoke sensors."""
|
|
|
|
_unique_id_suffix = "self_test"
|
|
_attribute_name = "self_test"
|
|
_attribute_value = 1
|
|
_attr_entity_category = EntityCategory.CONFIG
|
|
_attr_translation_key = "self_test"
|