Use entity selector in Homekit bridge config flow (#126340)

Use entity selector in homekit bridge config flow
This commit is contained in:
Paul Bottein 2024-09-25 12:11:55 +02:00 committed by GitHub
parent 49efa4d47b
commit a5b556b21b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -39,6 +39,7 @@ from homeassistant.helpers import (
config_validation as cv, config_validation as cv,
device_registry as dr, device_registry as dr,
entity_registry as er, entity_registry as er,
selector,
) )
from homeassistant.loader import async_get_integrations from homeassistant.loader import async_get_integrations
@ -178,12 +179,12 @@ def _async_build_entities_filter(
) )
def _async_cameras_from_entities(entities: list[str]) -> dict[str, str]: def _async_cameras_from_entities(entities: list[str]) -> list[str]:
return { return [
entity_id: entity_id entity_id
for entity_id in entities for entity_id in entities
if entity_id.startswith(CAMERA_ENTITY_PREFIX) if entity_id.startswith(CAMERA_ENTITY_PREFIX)
} ]
async def _async_name_to_type_map(hass: HomeAssistant) -> dict[str, str]: async def _async_name_to_type_map(hass: HomeAssistant) -> dict[str, str]:
@ -371,7 +372,7 @@ class OptionsFlowHandler(OptionsFlow):
"""Initialize options flow.""" """Initialize options flow."""
self.config_entry = config_entry self.config_entry = config_entry
self.hk_options: dict[str, Any] = {} self.hk_options: dict[str, Any] = {}
self.included_cameras: dict[str, str] = {} self.included_cameras: list[str] = []
async def async_step_yaml( async def async_step_yaml(
self, user_input: dict[str, Any] | None = None self, user_input: dict[str, Any] | None = None
@ -461,13 +462,21 @@ class OptionsFlowHandler(OptionsFlow):
data_schema = vol.Schema( data_schema = vol.Schema(
{ {
vol.Optional( vol.Optional(
CONF_CAMERA_COPY, CONF_CAMERA_COPY, default=cameras_with_copy
default=cameras_with_copy, ): selector.EntitySelector(
): cv.multi_select(self.included_cameras), selector.EntitySelectorConfig(
multiple=True,
include_entities=(self.included_cameras),
)
),
vol.Optional( vol.Optional(
CONF_CAMERA_AUDIO, CONF_CAMERA_AUDIO, default=cameras_with_audio
default=cameras_with_audio, ): selector.EntitySelector(
): cv.multi_select(self.included_cameras), selector.EntitySelectorConfig(
multiple=True,
include_entities=(self.included_cameras),
)
),
} }
) )
return self.async_show_form(step_id="cameras", data_schema=data_schema) return self.async_show_form(step_id="cameras", data_schema=data_schema)
@ -508,9 +517,13 @@ class OptionsFlowHandler(OptionsFlow):
step_id="accessory", step_id="accessory",
data_schema=vol.Schema( data_schema=vol.Schema(
{ {
vol.Required(CONF_ENTITIES, default=default_value): vol.In( vol.Required(
all_supported_entities CONF_ENTITIES, default=default_value
) ): selector.EntitySelector(
selector.EntitySelectorConfig(
include_entities=all_supported_entities,
)
),
} }
), ),
) )
@ -546,9 +559,14 @@ class OptionsFlowHandler(OptionsFlow):
}, },
data_schema=vol.Schema( data_schema=vol.Schema(
{ {
vol.Optional(CONF_ENTITIES, default=default_value): cv.multi_select( vol.Optional(
all_supported_entities CONF_ENTITIES, default=default_value
) ): selector.EntitySelector(
selector.EntitySelectorConfig(
multiple=True,
include_entities=all_supported_entities,
)
),
} }
), ),
) )
@ -561,17 +579,17 @@ class OptionsFlowHandler(OptionsFlow):
domains = hk_options[CONF_DOMAINS] domains = hk_options[CONF_DOMAINS]
if user_input is not None: if user_input is not None:
self.included_cameras = {} self.included_cameras = []
entities = cv.ensure_list(user_input[CONF_ENTITIES]) entities = cv.ensure_list(user_input[CONF_ENTITIES])
if CAMERA_DOMAIN in domains: if CAMERA_DOMAIN in domains:
camera_entities = _async_get_matching_entities( camera_entities = _async_get_matching_entities(
self.hass, [CAMERA_DOMAIN] self.hass, [CAMERA_DOMAIN]
) )
self.included_cameras = { self.included_cameras = [
entity_id: entity_id entity_id
for entity_id in camera_entities for entity_id in camera_entities
if entity_id not in entities if entity_id not in entities
} ]
hk_options[CONF_FILTER] = _make_entity_filter( hk_options[CONF_FILTER] = _make_entity_filter(
include_domains=domains, exclude_entities=entities include_domains=domains, exclude_entities=entities
) )
@ -598,9 +616,14 @@ class OptionsFlowHandler(OptionsFlow):
}, },
data_schema=vol.Schema( data_schema=vol.Schema(
{ {
vol.Optional(CONF_ENTITIES, default=default_value): cv.multi_select( vol.Optional(
all_supported_entities CONF_ENTITIES, default=default_value
) ): selector.EntitySelector(
selector.EntitySelectorConfig(
multiple=True,
include_entities=all_supported_entities,
)
),
} }
), ),
) )
@ -684,13 +707,11 @@ def _async_get_matching_entities(
domains: list[str] | None = None, domains: list[str] | None = None,
include_entity_category: bool = False, include_entity_category: bool = False,
include_hidden: bool = False, include_hidden: bool = False,
) -> dict[str, str]: ) -> list[str]:
"""Fetch all entities or entities in the given domains.""" """Fetch all entities or entities in the given domains."""
ent_reg = er.async_get(hass) ent_reg = er.async_get(hass)
return { return [
state.entity_id: ( state.entity_id
f"{state.attributes.get(ATTR_FRIENDLY_NAME, state.entity_id)} ({state.entity_id})"
)
for state in sorted( for state in sorted(
hass.states.async_all(domains and set(domains)), hass.states.async_all(domains and set(domains)),
key=lambda item: item.entity_id, key=lambda item: item.entity_id,
@ -698,7 +719,7 @@ def _async_get_matching_entities(
if not _exclude_by_entity_registry( if not _exclude_by_entity_registry(
ent_reg, state.entity_id, include_entity_category, include_hidden ent_reg, state.entity_id, include_entity_category, include_hidden
) )
} ]
def _domains_set_from_entities(entity_ids: Iterable[str]) -> set[str]: def _domains_set_from_entities(entity_ids: Iterable[str]) -> set[str]: