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