1
0
mirror of https://github.com/home-assistant/core.git synced 2025-05-10 17:09:17 +00:00

152 lines
5.5 KiB
Python

"""Support for select entities through the SmartThings cloud API."""
from __future__ import annotations
from dataclasses import dataclass
from pysmartthings import Attribute, Capability, Command, SmartThings
from homeassistant.components.select import SelectEntity, SelectEntityDescription
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 MAIN
from .entity import SmartThingsEntity
@dataclass(frozen=True, kw_only=True)
class SmartThingsSelectDescription(SelectEntityDescription):
"""Class describing SmartThings select entities."""
key: Capability
requires_remote_control_status: bool = False
options_attribute: Attribute
status_attribute: Attribute
command: Command
default_options: list[str] | None = None
CAPABILITIES_TO_SELECT: dict[Capability | str, SmartThingsSelectDescription] = {
Capability.DISHWASHER_OPERATING_STATE: SmartThingsSelectDescription(
key=Capability.DISHWASHER_OPERATING_STATE,
name=None,
translation_key="operating_state",
requires_remote_control_status=True,
options_attribute=Attribute.SUPPORTED_MACHINE_STATES,
status_attribute=Attribute.MACHINE_STATE,
command=Command.SET_MACHINE_STATE,
),
Capability.DRYER_OPERATING_STATE: SmartThingsSelectDescription(
key=Capability.DRYER_OPERATING_STATE,
name=None,
translation_key="operating_state",
requires_remote_control_status=True,
options_attribute=Attribute.SUPPORTED_MACHINE_STATES,
status_attribute=Attribute.MACHINE_STATE,
command=Command.SET_MACHINE_STATE,
default_options=["run", "pause", "stop"],
),
Capability.WASHER_OPERATING_STATE: SmartThingsSelectDescription(
key=Capability.WASHER_OPERATING_STATE,
name=None,
translation_key="operating_state",
requires_remote_control_status=True,
options_attribute=Attribute.SUPPORTED_MACHINE_STATES,
status_attribute=Attribute.MACHINE_STATE,
command=Command.SET_MACHINE_STATE,
default_options=["run", "pause", "stop"],
),
Capability.SAMSUNG_CE_AUTO_DISPENSE_DETERGENT: SmartThingsSelectDescription(
key=Capability.SAMSUNG_CE_AUTO_DISPENSE_DETERGENT,
translation_key="detergent_amount",
options_attribute=Attribute.SUPPORTED_AMOUNT,
status_attribute=Attribute.AMOUNT,
command=Command.SET_AMOUNT,
entity_category=EntityCategory.CONFIG,
),
Capability.SAMSUNG_CE_FLEXIBLE_AUTO_DISPENSE_DETERGENT: SmartThingsSelectDescription(
key=Capability.SAMSUNG_CE_FLEXIBLE_AUTO_DISPENSE_DETERGENT,
translation_key="flexible_detergent_amount",
options_attribute=Attribute.SUPPORTED_AMOUNT,
status_attribute=Attribute.AMOUNT,
command=Command.SET_AMOUNT,
entity_category=EntityCategory.CONFIG,
),
}
async def async_setup_entry(
hass: HomeAssistant,
entry: SmartThingsConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Add select entities for a config entry."""
entry_data = entry.runtime_data
async_add_entities(
SmartThingsSelectEntity(
entry_data.client, device, CAPABILITIES_TO_SELECT[capability]
)
for device in entry_data.devices.values()
for capability in device.status[MAIN]
if capability in CAPABILITIES_TO_SELECT
)
class SmartThingsSelectEntity(SmartThingsEntity, SelectEntity):
"""Define a SmartThings select."""
entity_description: SmartThingsSelectDescription
def __init__(
self,
client: SmartThings,
device: FullDevice,
entity_description: SmartThingsSelectDescription,
) -> None:
"""Initialize the instance."""
capabilities = {entity_description.key}
if entity_description.requires_remote_control_status:
capabilities.add(Capability.REMOTE_CONTROL_STATUS)
super().__init__(client, device, capabilities)
self.entity_description = entity_description
self._attr_unique_id = f"{device.device.device_id}_{MAIN}_{entity_description.key}_{entity_description.status_attribute}_{entity_description.status_attribute}"
@property
def options(self) -> list[str]:
"""Return the list of options."""
return (
self.get_attribute_value(
self.entity_description.key, self.entity_description.options_attribute
)
or self.entity_description.default_options
or []
)
@property
def current_option(self) -> str | None:
"""Return the current option."""
return self.get_attribute_value(
self.entity_description.key, self.entity_description.status_attribute
)
async def async_select_option(self, option: str) -> None:
"""Select an option."""
if (
self.entity_description.requires_remote_control_status
and self.get_attribute_value(
Capability.REMOTE_CONTROL_STATUS, Attribute.REMOTE_CONTROL_ENABLED
)
== "false"
):
raise ServiceValidationError(
"Can only be updated when remote control is enabled"
)
await self.execute_device_command(
self.entity_description.key,
self.entity_description.command,
option,
)