123 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Python
		
	
	
"""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,
 | 
						|
        )
 |