"""Text for Shelly.""" from dataclasses import dataclass from typing import Final, override from aioshelly.const import RPC_GENERATIONS from homeassistant.components.text import ( DOMAIN as TEXT_DOMAIN, TextEntity, TextEntityDescription, ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import ROLE_GENERIC from .coordinator import ShellyConfigEntry, ShellyRpcCoordinator from .entity import ( RpcEntityDescription, ShellyRpcAttributeEntity, async_setup_entry_rpc, rpc_call, ) from .utils import ( async_remove_orphaned_entities, get_device_entry_gen, get_rpc_channel_name, get_virtual_component_ids, is_view_for_platform, ) PARALLEL_UPDATES = 0 @dataclass(frozen=True, kw_only=True) class RpcTextDescription(RpcEntityDescription, TextEntityDescription): """Class to describe a RPC text entity.""" RPC_TEXT_ENTITIES: Final = { "text_generic": RpcTextDescription( key="text", sub_key="value", removal_condition=lambda config, _status, key: ( not is_view_for_platform(config, key, TEXT_DOMAIN) ), role=ROLE_GENERIC, ), } async def async_setup_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up text entities.""" if get_device_entry_gen(config_entry) in RPC_GENERATIONS: return _async_setup_rpc_entry(hass, config_entry, async_add_entities) return None @callback def _async_setup_rpc_entry( hass: HomeAssistant, config_entry: ShellyConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: """Set up entities for RPC device.""" coordinator = config_entry.runtime_data.rpc assert coordinator async_setup_entry_rpc( hass, config_entry, async_add_entities, RPC_TEXT_ENTITIES, RpcText ) # the user can remove virtual components from the device configuration, so # we need to remove orphaned entities virtual_text_ids = get_virtual_component_ids(coordinator.device.config, TEXT_DOMAIN) async_remove_orphaned_entities( hass, config_entry.entry_id, coordinator.mac, TEXT_DOMAIN, virtual_text_ids, "text", ) class RpcText(ShellyRpcAttributeEntity, TextEntity): """Represent a RPC text entity.""" entity_description: RpcTextDescription attribute_value: str | None _id: int def __init__( self, coordinator: ShellyRpcCoordinator, key: str, attribute: str, description: RpcTextDescription, ) -> None: """Initialize sensor.""" super().__init__(coordinator, key, attribute, description) self._attr_name = get_rpc_channel_name(coordinator.device, key) @property @override def native_value(self) -> str | None: """Return value of sensor.""" return self.attribute_value @rpc_call @override async def async_set_value(self, value: str) -> None: """Change the value.""" await self.coordinator.device.text_set(self._id, value)