"""Config flow for Discovergy integration.""" from __future__ import annotations from collections.abc import Mapping import logging from typing import Any import pydiscovergy from pydiscovergy.authentication import BasicAuth import pydiscovergy.error as discovergyError import voluptuous as vol from homeassistant import config_entries from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_EMAIL, CONF_PASSWORD from homeassistant.data_entry_flow import FlowResult from homeassistant.helpers.httpx_client import get_async_client from .const import APP_NAME, DOMAIN _LOGGER = logging.getLogger(__name__) def make_schema(email: str = "", password: str = "") -> vol.Schema: """Create schema for config flow.""" return vol.Schema( { vol.Required( CONF_EMAIL, default=email, ): str, vol.Required( CONF_PASSWORD, default=password, ): str, } ) class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): """Handle a config flow for Discovergy.""" VERSION = 1 existing_entry: ConfigEntry | None = None async def async_step_user( self, user_input: dict[str, Any] | None = None ) -> FlowResult: """Handle the initial step.""" if user_input is None: return self.async_show_form( step_id="user", data_schema=make_schema(), ) return await self._validate_and_save(user_input) async def async_step_reauth(self, entry_data: Mapping[str, Any]) -> FlowResult: """Handle the initial step.""" self.existing_entry = await self.async_set_unique_id(self.context["unique_id"]) if entry_data is None: return self.async_show_form( step_id="reauth", data_schema=make_schema( self.existing_entry.data[CONF_EMAIL] or "", self.existing_entry.data[CONF_PASSWORD] or "", ), ) return await self._validate_and_save(entry_data, step_id="reauth") async def _validate_and_save( self, user_input: Mapping[str, Any] | None = None, step_id: str = "user" ) -> FlowResult: """Validate user input and create config entry.""" errors = {} if user_input: try: await pydiscovergy.Discovergy( email=user_input[CONF_EMAIL], password=user_input[CONF_PASSWORD], app_name=APP_NAME, httpx_client=get_async_client(self.hass), authentication=BasicAuth(), ).get_meters() except discovergyError.HTTPError: errors["base"] = "cannot_connect" except discovergyError.InvalidLogin: errors["base"] = "invalid_auth" except Exception: # pylint: disable=broad-except _LOGGER.exception("Unexpected error occurred while getting meters") errors["base"] = "unknown" else: if self.existing_entry: self.hass.config_entries.async_update_entry( self.existing_entry, data={ CONF_EMAIL: user_input[CONF_EMAIL], CONF_PASSWORD: user_input[CONF_PASSWORD], }, ) await self.hass.config_entries.async_reload( self.existing_entry.entry_id ) return self.async_abort(reason="reauth_successful") # set unique id to title which is the account email await self.async_set_unique_id(user_input[CONF_EMAIL].lower()) self._abort_if_unique_id_configured() return self.async_create_entry( title=user_input[CONF_EMAIL], data=user_input ) return self.async_show_form( step_id=step_id, data_schema=make_schema(), errors=errors, )