Files
core/homeassistant/components/assist_pipeline/select.py

179 lines
5.8 KiB
Python

"""Select entities for a pipeline."""
from __future__ import annotations
from collections.abc import Iterable
from dataclasses import replace
from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.const import EntityCategory, Platform
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import collection, entity_registry as er, restore_state
from .const import OPTION_PREFERRED
from .pipeline import KEY_ASSIST_PIPELINE, AssistDevice
from .vad import VadSensitivity
@callback
def get_chosen_pipeline(
hass: HomeAssistant, domain: str, unique_id_prefix: str
) -> str | None:
"""Get the chosen pipeline for a domain."""
ent_reg = er.async_get(hass)
pipeline_entity_id = ent_reg.async_get_entity_id(
Platform.SELECT, domain, f"{unique_id_prefix}-pipeline"
)
if pipeline_entity_id is None:
return None
state = hass.states.get(pipeline_entity_id)
if state is None or state.state == OPTION_PREFERRED:
return None
pipeline_store = hass.data[KEY_ASSIST_PIPELINE].pipeline_store
return next(
(item.id for item in pipeline_store.async_items() if item.name == state.state),
None,
)
@callback
def get_vad_sensitivity(
hass: HomeAssistant, domain: str, unique_id_prefix: str
) -> VadSensitivity:
"""Get the chosen vad sensitivity for a domain."""
ent_reg = er.async_get(hass)
sensitivity_entity_id = ent_reg.async_get_entity_id(
Platform.SELECT, domain, f"{unique_id_prefix}-vad_sensitivity"
)
if sensitivity_entity_id is None:
return VadSensitivity.DEFAULT
state = hass.states.get(sensitivity_entity_id)
if state is None:
return VadSensitivity.DEFAULT
return VadSensitivity(state.state)
class AssistPipelineSelect(SelectEntity, restore_state.RestoreEntity):
"""Entity to represent a pipeline selector."""
entity_description = SelectEntityDescription(
key="pipeline",
translation_key="pipeline",
entity_category=EntityCategory.CONFIG,
)
_attr_should_poll = False
_attr_current_option = OPTION_PREFERRED
_attr_options = [OPTION_PREFERRED]
def __init__(
self,
hass: HomeAssistant,
domain: str,
unique_id_prefix: str,
index: int = 0,
) -> None:
"""Initialize a pipeline selector."""
if index < 1:
# Keep compatibility
key_suffix = ""
placeholder = ""
else:
key_suffix = f"_{index + 1}"
placeholder = f" {index + 1}"
self.entity_description = replace(
self.entity_description,
key=f"pipeline{key_suffix}",
translation_placeholders={"index": placeholder},
)
self._domain = domain
self._unique_id_prefix = unique_id_prefix
self._attr_unique_id = f"{unique_id_prefix}-{self.entity_description.key}"
self.hass = hass
self._update_options()
async def async_added_to_hass(self) -> None:
"""When entity is added to Home Assistant."""
await super().async_added_to_hass()
pipeline_data = self.hass.data[KEY_ASSIST_PIPELINE]
pipeline_store = pipeline_data.pipeline_store
self.async_on_remove(
pipeline_store.async_add_change_set_listener(self._pipelines_updated)
)
state = await self.async_get_last_state()
if state is not None and state.state in self.options:
self._attr_current_option = state.state
if self.registry_entry and (device_id := self.registry_entry.device_id):
pipeline_data.pipeline_devices[device_id] = AssistDevice(
self._domain, self._unique_id_prefix
)
def cleanup() -> None:
"""Clean up registered device."""
pipeline_data.pipeline_devices.pop(device_id)
self.async_on_remove(cleanup)
async def async_select_option(self, option: str) -> None:
"""Select an option."""
self._attr_current_option = option
self.async_write_ha_state()
async def _pipelines_updated(
self, change_set: Iterable[collection.CollectionChange]
) -> None:
"""Handle pipeline update."""
self._update_options()
self.async_write_ha_state()
@callback
def _update_options(self) -> None:
"""Handle pipeline update."""
pipeline_store = self.hass.data[KEY_ASSIST_PIPELINE].pipeline_store
options = [OPTION_PREFERRED]
options.extend(sorted(item.name for item in pipeline_store.async_items()))
self._attr_options = options
if self._attr_current_option not in options:
self._attr_current_option = OPTION_PREFERRED
class VadSensitivitySelect(SelectEntity, restore_state.RestoreEntity):
"""Entity to represent VAD sensitivity."""
entity_description = SelectEntityDescription(
key="vad_sensitivity",
translation_key="vad_sensitivity",
entity_category=EntityCategory.CONFIG,
)
_attr_should_poll = False
_attr_current_option = VadSensitivity.DEFAULT.value
_attr_options = [vs.value for vs in VadSensitivity]
def __init__(self, hass: HomeAssistant, unique_id_prefix: str) -> None:
"""Initialize a pipeline selector."""
self._attr_unique_id = f"{unique_id_prefix}-vad_sensitivity"
self.hass = hass
async def async_added_to_hass(self) -> None:
"""When entity is added to Home Assistant."""
await super().async_added_to_hass()
state = await self.async_get_last_state()
if state is not None and state.state in self.options:
self._attr_current_option = state.state
async def async_select_option(self, option: str) -> None:
"""Select an option."""
self._attr_current_option = option
self.async_write_ha_state()