mirror of
https://github.com/home-assistant/core.git
synced 2026-04-02 16:36:08 +01:00
210 lines
7.6 KiB
Python
210 lines
7.6 KiB
Python
"""Support for button entities through the SmartThings cloud API."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Any
|
|
|
|
from pysmartthings import Attribute, Capability, Category, Command, SmartThings
|
|
|
|
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
|
|
from homeassistant.const import EntityCategory
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.exceptions import ServiceValidationError
|
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|
|
|
from . import FullDevice, SmartThingsConfigEntry
|
|
from .const import DOMAIN, MAIN
|
|
from .entity import SmartThingsEntity
|
|
|
|
|
|
@dataclass(frozen=True, kw_only=True)
|
|
class SmartThingsButtonDescription(ButtonEntityDescription):
|
|
"""Class describing SmartThings button entities."""
|
|
|
|
key: Capability
|
|
command: Command
|
|
command_identifier: str | None = None
|
|
components: list[str] | None = None
|
|
argument: int | str | list[Any] | dict[str, Any] | None = None
|
|
requires_remote_control_status: bool = False
|
|
requires_dishwasher_machine_state: set[str] | None = None
|
|
|
|
|
|
CAPABILITIES_TO_BUTTONS: dict[Capability | str, SmartThingsButtonDescription] = {
|
|
Capability.OVEN_OPERATING_STATE: SmartThingsButtonDescription(
|
|
key=Capability.OVEN_OPERATING_STATE,
|
|
translation_key="stop",
|
|
command=Command.STOP,
|
|
),
|
|
Capability.CUSTOM_WATER_FILTER: SmartThingsButtonDescription(
|
|
key=Capability.CUSTOM_WATER_FILTER,
|
|
translation_key="reset_water_filter",
|
|
command=Command.RESET_WATER_FILTER,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
),
|
|
Capability.SAMSUNG_CE_HOOD_FILTER: SmartThingsButtonDescription(
|
|
key=Capability.SAMSUNG_CE_HOOD_FILTER,
|
|
translation_key="reset_hood_filter",
|
|
command=Command.RESET_HOOD_FILTER,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
),
|
|
Capability.CUSTOM_HEPA_FILTER: SmartThingsButtonDescription(
|
|
key=Capability.CUSTOM_HEPA_FILTER,
|
|
translation_key="reset_hepa_filter",
|
|
command=Command.RESET_HEPA_FILTER,
|
|
entity_category=EntityCategory.DIAGNOSTIC,
|
|
components=[MAIN, "station"],
|
|
),
|
|
}
|
|
|
|
|
|
DISHWASHER_OPERATION_COMMANDS_TO_BUTTONS: dict[
|
|
Command | str, SmartThingsButtonDescription
|
|
] = {
|
|
Command.CANCEL: SmartThingsButtonDescription(
|
|
key=Capability.SAMSUNG_CE_DISHWASHER_OPERATION,
|
|
translation_key="cancel",
|
|
command_identifier="drain",
|
|
command=Command.CANCEL,
|
|
argument=[True],
|
|
requires_remote_control_status=True,
|
|
),
|
|
Command.PAUSE: SmartThingsButtonDescription(
|
|
key=Capability.SAMSUNG_CE_DISHWASHER_OPERATION,
|
|
translation_key="pause",
|
|
command=Command.PAUSE,
|
|
requires_remote_control_status=True,
|
|
requires_dishwasher_machine_state={"run"},
|
|
),
|
|
Command.RESUME: SmartThingsButtonDescription(
|
|
key=Capability.SAMSUNG_CE_DISHWASHER_OPERATION,
|
|
translation_key="resume",
|
|
command=Command.RESUME,
|
|
requires_remote_control_status=True,
|
|
requires_dishwasher_machine_state={"pause"},
|
|
),
|
|
Command.START: SmartThingsButtonDescription(
|
|
key=Capability.SAMSUNG_CE_DISHWASHER_OPERATION,
|
|
translation_key="start",
|
|
command=Command.START,
|
|
requires_remote_control_status=True,
|
|
requires_dishwasher_machine_state={"stop"},
|
|
),
|
|
}
|
|
|
|
DISHWASHER_CANCEL_AND_DRAIN_BUTTON = SmartThingsButtonDescription(
|
|
key=Capability.CUSTOM_SUPPORTED_OPTIONS,
|
|
translation_key="cancel_and_drain",
|
|
command_identifier="89",
|
|
command=Command.SET_COURSE,
|
|
argument="89",
|
|
requires_remote_control_status=True,
|
|
)
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
entry: SmartThingsConfigEntry,
|
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
|
) -> None:
|
|
"""Add button entities for a config entry."""
|
|
entry_data = entry.runtime_data
|
|
entities: list[SmartThingsEntity] = []
|
|
entities.extend(
|
|
SmartThingsButtonEntity(
|
|
entry_data.client, device, description, Capability(capability), component
|
|
)
|
|
for capability, description in CAPABILITIES_TO_BUTTONS.items()
|
|
for device in entry_data.devices.values()
|
|
for component in description.components or [MAIN]
|
|
if component in device.status and capability in device.status[component]
|
|
)
|
|
entities.extend(
|
|
SmartThingsButtonEntity(
|
|
entry_data.client,
|
|
device,
|
|
description,
|
|
Capability.SAMSUNG_CE_DISHWASHER_OPERATION,
|
|
)
|
|
for device in entry_data.devices.values()
|
|
if Capability.SAMSUNG_CE_DISHWASHER_OPERATION in device.status[MAIN]
|
|
for description in DISHWASHER_OPERATION_COMMANDS_TO_BUTTONS.values()
|
|
)
|
|
entities.extend(
|
|
SmartThingsButtonEntity(
|
|
entry_data.client,
|
|
device,
|
|
DISHWASHER_CANCEL_AND_DRAIN_BUTTON,
|
|
Capability.CUSTOM_SUPPORTED_OPTIONS,
|
|
)
|
|
for device in entry_data.devices.values()
|
|
if (
|
|
device.device.components[MAIN].manufacturer_category == Category.DISHWASHER
|
|
and Capability.CUSTOM_SUPPORTED_OPTIONS in device.status[MAIN]
|
|
)
|
|
)
|
|
async_add_entities(entities)
|
|
|
|
|
|
class SmartThingsButtonEntity(SmartThingsEntity, ButtonEntity):
|
|
"""Define a SmartThings button."""
|
|
|
|
entity_description: SmartThingsButtonDescription
|
|
|
|
def __init__(
|
|
self,
|
|
client: SmartThings,
|
|
device: FullDevice,
|
|
entity_description: SmartThingsButtonDescription,
|
|
capability: Capability,
|
|
component: str = MAIN,
|
|
) -> None:
|
|
"""Initialize the instance."""
|
|
capabilities = set()
|
|
if entity_description.requires_remote_control_status:
|
|
capabilities.add(Capability.REMOTE_CONTROL_STATUS)
|
|
if entity_description.requires_dishwasher_machine_state:
|
|
capabilities.add(Capability.DISHWASHER_OPERATING_STATE)
|
|
super().__init__(client, device, capabilities)
|
|
self.entity_description = entity_description
|
|
self.button_capability = capability
|
|
self._attr_unique_id = f"{device.device.device_id}_{component}_{entity_description.key}_{entity_description.command}"
|
|
if entity_description.command_identifier is not None:
|
|
self._attr_unique_id += f"_{entity_description.command_identifier}"
|
|
|
|
async def async_press(self) -> None:
|
|
"""Press the button."""
|
|
self._validate_before_execute()
|
|
await self.execute_device_command(
|
|
self.button_capability,
|
|
self.entity_description.command,
|
|
self.entity_description.argument,
|
|
)
|
|
|
|
def _validate_before_execute(self) -> None:
|
|
"""Validate that the command can be executed."""
|
|
if (
|
|
self.entity_description.requires_remote_control_status
|
|
and self.get_attribute_value(
|
|
Capability.REMOTE_CONTROL_STATUS, Attribute.REMOTE_CONTROL_ENABLED
|
|
)
|
|
== "false"
|
|
):
|
|
raise ServiceValidationError(
|
|
translation_domain=DOMAIN, translation_key="remote_control_status"
|
|
)
|
|
if (
|
|
self.entity_description.requires_dishwasher_machine_state
|
|
and self.get_attribute_value(
|
|
Capability.DISHWASHER_OPERATING_STATE, Attribute.MACHINE_STATE
|
|
)
|
|
not in self.entity_description.requires_dishwasher_machine_state
|
|
):
|
|
state_list = " or ".join(
|
|
self.entity_description.requires_dishwasher_machine_state
|
|
)
|
|
raise ServiceValidationError(
|
|
f"Can only be updated when dishwasher machine state is {state_list}"
|
|
)
|