"""Config flow for Homeassistant Analytics integration.""" from __future__ import annotations from typing import Any from python_homeassistant_analytics import ( HomeassistantAnalyticsClient, HomeassistantAnalyticsConnectionError, ) from python_homeassistant_analytics.models import IntegrationType import voluptuous as vol from homeassistant.config_entries import ( ConfigEntry, ConfigFlow, ConfigFlowResult, OptionsFlow, OptionsFlowWithConfigEntry, ) from homeassistant.core import callback from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.selector import ( SelectOptionDict, SelectSelector, SelectSelectorConfig, ) from .const import ( CONF_TRACKED_CUSTOM_INTEGRATIONS, CONF_TRACKED_INTEGRATIONS, DOMAIN, LOGGER, ) INTEGRATION_TYPES_WITHOUT_ANALYTICS = ( IntegrationType.BRAND, IntegrationType.ENTITY, IntegrationType.VIRTUAL, ) class HomeassistantAnalyticsConfigFlow(ConfigFlow, domain=DOMAIN): """Handle a config flow for Homeassistant Analytics.""" @staticmethod @callback def async_get_options_flow(config_entry: ConfigEntry) -> OptionsFlow: """Get the options flow for this handler.""" return HomeassistantAnalyticsOptionsFlowHandler(config_entry) async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Handle the initial step.""" errors: dict[str, str] = {} if user_input is not None: if not user_input.get(CONF_TRACKED_INTEGRATIONS) and not user_input.get( CONF_TRACKED_CUSTOM_INTEGRATIONS ): errors["base"] = "no_integrations_selected" else: return self.async_create_entry( title="Home Assistant Analytics Insights", data={}, options={ CONF_TRACKED_INTEGRATIONS: user_input.get( CONF_TRACKED_INTEGRATIONS, [] ), CONF_TRACKED_CUSTOM_INTEGRATIONS: user_input.get( CONF_TRACKED_CUSTOM_INTEGRATIONS, [] ), }, ) client = HomeassistantAnalyticsClient( session=async_get_clientsession(self.hass) ) try: integrations = await client.get_integrations() custom_integrations = await client.get_custom_integrations() except HomeassistantAnalyticsConnectionError: LOGGER.exception("Error connecting to Home Assistant analytics") return self.async_abort(reason="cannot_connect") except Exception: # noqa: BLE001 LOGGER.exception("Unexpected error") return self.async_abort(reason="unknown") options = [ SelectOptionDict( value=domain, label=integration.title, ) for domain, integration in integrations.items() if integration.integration_type not in INTEGRATION_TYPES_WITHOUT_ANALYTICS ] return self.async_show_form( step_id="user", errors=errors, data_schema=vol.Schema( { vol.Optional(CONF_TRACKED_INTEGRATIONS): SelectSelector( SelectSelectorConfig( options=options, multiple=True, sort=True, ) ), vol.Optional(CONF_TRACKED_CUSTOM_INTEGRATIONS): SelectSelector( SelectSelectorConfig( options=list(custom_integrations), multiple=True, sort=True, ) ), } ), ) class HomeassistantAnalyticsOptionsFlowHandler(OptionsFlowWithConfigEntry): """Handle Homeassistant Analytics options.""" async def async_step_init( self, user_input: dict[str, Any] | None = None ) -> ConfigFlowResult: """Manage the options.""" errors: dict[str, str] = {} if user_input is not None: if not user_input.get(CONF_TRACKED_INTEGRATIONS) and not user_input.get( CONF_TRACKED_CUSTOM_INTEGRATIONS ): errors["base"] = "no_integrations_selected" else: return self.async_create_entry( title="", data={ CONF_TRACKED_INTEGRATIONS: user_input.get( CONF_TRACKED_INTEGRATIONS, [] ), CONF_TRACKED_CUSTOM_INTEGRATIONS: user_input.get( CONF_TRACKED_CUSTOM_INTEGRATIONS, [] ), }, ) client = HomeassistantAnalyticsClient( session=async_get_clientsession(self.hass) ) try: integrations = await client.get_integrations() custom_integrations = await client.get_custom_integrations() except HomeassistantAnalyticsConnectionError: LOGGER.exception("Error connecting to Home Assistant analytics") return self.async_abort(reason="cannot_connect") options = [ SelectOptionDict( value=domain, label=integration.title, ) for domain, integration in integrations.items() if integration.integration_type not in INTEGRATION_TYPES_WITHOUT_ANALYTICS ] return self.async_show_form( step_id="init", errors=errors, data_schema=self.add_suggested_values_to_schema( vol.Schema( { vol.Optional(CONF_TRACKED_INTEGRATIONS): SelectSelector( SelectSelectorConfig( options=options, multiple=True, sort=True, ) ), vol.Optional(CONF_TRACKED_CUSTOM_INTEGRATIONS): SelectSelector( SelectSelectorConfig( options=list(custom_integrations), multiple=True, sort=True, ) ), }, ), self.options, ), )