Cleanup nest config flow (#63351)

This commit is contained in:
Allen Porter 2022-01-04 07:33:17 -08:00 committed by GitHub
parent 1a7ae839d3
commit fdb4b1d7f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 22 deletions

View File

@ -142,17 +142,16 @@ class InstalledAppAuth(config_entry_oauth2_flow.LocalOAuth2Implementation):
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up Nest components with dispatch between old/new flows.""" """Set up Nest components with dispatch between old/new flows."""
hass.data[DOMAIN] = {} hass.data[DOMAIN] = {}
hass.data[DOMAIN][DATA_NEST_CONFIG] = config.get(DOMAIN)
if DOMAIN not in config: if DOMAIN not in config:
return True return True
if CONF_PROJECT_ID not in config[DOMAIN]: config_mode = config_flow.get_config_mode(hass)
if config_mode == config_flow.ConfigMode.LEGACY:
return await async_setup_legacy(hass, config) return await async_setup_legacy(hass, config)
# For setup of ConfigEntry below
hass.data[DOMAIN][DATA_NEST_CONFIG] = config[DOMAIN]
project_id = config[DOMAIN][CONF_PROJECT_ID] project_id = config[DOMAIN][CONF_PROJECT_ID]
config_flow.NestFlowHandler.register_sdm_api(hass)
config_flow.NestFlowHandler.async_register_implementation( config_flow.NestFlowHandler.async_register_implementation(
hass, hass,
InstalledAppAuth( InstalledAppAuth(

View File

@ -27,6 +27,7 @@ from __future__ import annotations
import asyncio import asyncio
from collections import OrderedDict from collections import OrderedDict
from enum import Enum
import logging import logging
import os import os
from typing import Any from typing import Any
@ -66,6 +67,23 @@ CLOUD_CONSOLE_URL = "https://console.cloud.google.com/home/dashboard"
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
class ConfigMode(Enum):
"""Integration configuration mode."""
SDM = 1 # SDM api with configuration.yaml
LEGACY = 2 # "Works with Nest" API
def get_config_mode(hass: HomeAssistant) -> ConfigMode:
"""Return the integration configuration mode."""
if DOMAIN not in hass.data:
return ConfigMode.SDM
config = hass.data[DOMAIN][DATA_NEST_CONFIG]
if CONF_PROJECT_ID in config:
return ConfigMode.SDM
return ConfigMode.LEGACY
def _generate_subscription_id(cloud_project_id: str) -> str: def _generate_subscription_id(cloud_project_id: str) -> str:
"""Create a new subscription id.""" """Create a new subscription id."""
rnd = get_random_string(SUBSCRIPTION_RAND_LENGTH) rnd = get_random_string(SUBSCRIPTION_RAND_LENGTH)
@ -124,16 +142,10 @@ class NestFlowHandler(
self._reauth = False self._reauth = False
self._data: dict[str, Any] = {DATA_SDM: {}} self._data: dict[str, Any] = {DATA_SDM: {}}
@classmethod @property
def register_sdm_api(cls, hass: HomeAssistant) -> None: def config_mode(self) -> ConfigMode:
"""Configure the flow handler to use the SDM API.""" """Return the configuration type for this flow."""
if DOMAIN not in hass.data: return get_config_mode(self.hass)
hass.data[DOMAIN] = {}
hass.data[DOMAIN][DATA_SDM] = {}
def is_sdm_api(self) -> bool:
"""Return true if this flow is setup to use SDM API."""
return DOMAIN in self.hass.data and DATA_SDM in self.hass.data[DOMAIN]
@property @property
def logger(self) -> logging.Logger: def logger(self) -> logging.Logger:
@ -152,7 +164,7 @@ class NestFlowHandler(
async def async_oauth_create_entry(self, data: dict[str, Any]) -> FlowResult: async def async_oauth_create_entry(self, data: dict[str, Any]) -> FlowResult:
"""Complete OAuth setup and finish pubsub or finish.""" """Complete OAuth setup and finish pubsub or finish."""
assert self.is_sdm_api(), "Step only supported for SDM API" assert self.config_mode != ConfigMode.LEGACY, "Step only supported for SDM API"
self._data.update(data) self._data.update(data)
if not self._configure_pubsub(): if not self._configure_pubsub():
_LOGGER.debug("Skipping Pub/Sub configuration") _LOGGER.debug("Skipping Pub/Sub configuration")
@ -163,7 +175,7 @@ class NestFlowHandler(
self, user_input: dict[str, Any] | None = None self, user_input: dict[str, Any] | None = None
) -> FlowResult: ) -> FlowResult:
"""Perform reauth upon an API authentication error.""" """Perform reauth upon an API authentication error."""
assert self.is_sdm_api(), "Step only supported for SDM API" assert self.config_mode != ConfigMode.LEGACY, "Step only supported for SDM API"
if user_input is None: if user_input is None:
_LOGGER.error("Reauth invoked with empty config entry data") _LOGGER.error("Reauth invoked with empty config entry data")
return self.async_abort(reason="missing_configuration") return self.async_abort(reason="missing_configuration")
@ -175,7 +187,7 @@ class NestFlowHandler(
self, user_input: dict[str, Any] | None = None self, user_input: dict[str, Any] | None = None
) -> FlowResult: ) -> FlowResult:
"""Confirm reauth dialog.""" """Confirm reauth dialog."""
assert self.is_sdm_api(), "Step only supported for SDM API" assert self.config_mode != ConfigMode.LEGACY, "Step only supported for SDM API"
if user_input is None: if user_input is None:
return self.async_show_form( return self.async_show_form(
step_id="reauth_confirm", step_id="reauth_confirm",
@ -195,7 +207,7 @@ class NestFlowHandler(
self, user_input: dict[str, Any] | None = None self, user_input: dict[str, Any] | None = None
) -> FlowResult: ) -> FlowResult:
"""Handle a flow initialized by the user.""" """Handle a flow initialized by the user."""
if self.is_sdm_api(): if self.config_mode == ConfigMode.SDM:
# Reauth will update an existing entry # Reauth will update an existing entry
if self._async_current_entries() and not self._reauth: if self._async_current_entries() and not self._reauth:
return self.async_abort(reason="single_instance_allowed") return self.async_abort(reason="single_instance_allowed")
@ -309,7 +321,7 @@ class NestFlowHandler(
async def async_step_finish(self, data: dict[str, Any] | None = None) -> FlowResult: async def async_step_finish(self, data: dict[str, Any] | None = None) -> FlowResult:
"""Create an entry for the SDM flow.""" """Create an entry for the SDM flow."""
assert self.is_sdm_api(), "Step only supported for SDM API" assert self.config_mode != ConfigMode.LEGACY, "Step only supported for SDM API"
await self.async_set_unique_id(DOMAIN) await self.async_set_unique_id(DOMAIN)
# Update existing config entry when in the reauth flow. This # Update existing config entry when in the reauth flow. This
# integration only supports one config entry so remove any prior entries # integration only supports one config entry so remove any prior entries
@ -333,7 +345,9 @@ class NestFlowHandler(
self, user_input: dict[str, Any] | None = None self, user_input: dict[str, Any] | None = None
) -> FlowResult: ) -> FlowResult:
"""Handle a flow start.""" """Handle a flow start."""
assert not self.is_sdm_api(), "Step only supported for legacy API" assert (
self.config_mode == ConfigMode.LEGACY
), "Step only supported for legacy API"
flows = self.hass.data.get(DATA_FLOW_IMPL, {}) flows = self.hass.data.get(DATA_FLOW_IMPL, {})
@ -365,7 +379,9 @@ class NestFlowHandler(
implementation type we expect a pin or an external component to implementation type we expect a pin or an external component to
deliver the authentication code. deliver the authentication code.
""" """
assert not self.is_sdm_api(), "Step only supported for legacy API" assert (
self.config_mode == ConfigMode.LEGACY
), "Step only supported for legacy API"
flow = self.hass.data[DATA_FLOW_IMPL][self.flow_impl] flow = self.hass.data[DATA_FLOW_IMPL][self.flow_impl]
@ -407,7 +423,9 @@ class NestFlowHandler(
async def async_step_import(self, info: dict[str, Any]) -> FlowResult: async def async_step_import(self, info: dict[str, Any]) -> FlowResult:
"""Import existing auth from Nest.""" """Import existing auth from Nest."""
assert not self.is_sdm_api(), "Step only supported for legacy API" assert (
self.config_mode == ConfigMode.LEGACY
), "Step only supported for legacy API"
if self._async_current_entries(): if self._async_current_entries():
return self.async_abort(reason="single_instance_allowed") return self.async_abort(reason="single_instance_allowed")