mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Implement config_Flow for Sensibo (#60900)
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
0e48a658f3
commit
566f631933
@ -935,6 +935,7 @@ omit =
|
|||||||
homeassistant/components/sense/sensor.py
|
homeassistant/components/sense/sensor.py
|
||||||
homeassistant/components/sensehat/light.py
|
homeassistant/components/sensehat/light.py
|
||||||
homeassistant/components/sensehat/sensor.py
|
homeassistant/components/sensehat/sensor.py
|
||||||
|
homeassistant/components/sensibo/__init__.py
|
||||||
homeassistant/components/sensibo/climate.py
|
homeassistant/components/sensibo/climate.py
|
||||||
homeassistant/components/serial/sensor.py
|
homeassistant/components/serial/sensor.py
|
||||||
homeassistant/components/serial_pm/sensor.py
|
homeassistant/components/serial_pm/sensor.py
|
||||||
|
@ -793,7 +793,8 @@ homeassistant/components/select/* @home-assistant/core
|
|||||||
tests/components/select/* @home-assistant/core
|
tests/components/select/* @home-assistant/core
|
||||||
homeassistant/components/sense/* @kbickar
|
homeassistant/components/sense/* @kbickar
|
||||||
tests/components/sense/* @kbickar
|
tests/components/sense/* @kbickar
|
||||||
homeassistant/components/sensibo/* @andrey-git
|
homeassistant/components/sensibo/* @andrey-git @gjohansson-ST
|
||||||
|
tests/components/sensibo/* @andrey-git @gjohansson-ST
|
||||||
homeassistant/components/sentry/* @dcramer @frenck
|
homeassistant/components/sentry/* @dcramer @frenck
|
||||||
tests/components/sentry/* @dcramer @frenck
|
tests/components/sentry/* @dcramer @frenck
|
||||||
homeassistant/components/serial/* @fabaff
|
homeassistant/components/serial/* @fabaff
|
||||||
|
@ -1 +1,62 @@
|
|||||||
"""The sensibo component."""
|
"""The sensibo component."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
|
import async_timeout
|
||||||
|
import pysensibo
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import CONF_API_KEY
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
|
|
||||||
|
from .const import _INITIAL_FETCH_FIELDS, DOMAIN, PLATFORMS, TIMEOUT
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
|
"""Set up Sensibo from a config entry."""
|
||||||
|
client = pysensibo.SensiboClient(
|
||||||
|
entry.data[CONF_API_KEY], session=async_get_clientsession(hass), timeout=TIMEOUT
|
||||||
|
)
|
||||||
|
devicelist = []
|
||||||
|
try:
|
||||||
|
async with async_timeout.timeout(TIMEOUT):
|
||||||
|
for dev in await client.async_get_devices(_INITIAL_FETCH_FIELDS):
|
||||||
|
devicelist.append(dev)
|
||||||
|
except (
|
||||||
|
aiohttp.client_exceptions.ClientConnectorError,
|
||||||
|
asyncio.TimeoutError,
|
||||||
|
pysensibo.SensiboError,
|
||||||
|
) as err:
|
||||||
|
raise ConfigEntryNotReady(
|
||||||
|
f"Failed to get devices from Sensibo servers: {err}"
|
||||||
|
) from err
|
||||||
|
|
||||||
|
if not devicelist:
|
||||||
|
return False
|
||||||
|
|
||||||
|
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {
|
||||||
|
"devices": devicelist,
|
||||||
|
"client": client,
|
||||||
|
}
|
||||||
|
|
||||||
|
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
|
||||||
|
_LOGGER.debug("Loaded entry for %s", entry.title)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
|
"""Unload Sensibo config entry."""
|
||||||
|
if await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
|
||||||
|
del hass.data[DOMAIN][entry.entry_id]
|
||||||
|
if not hass.data[DOMAIN]:
|
||||||
|
del hass.data[DOMAIN]
|
||||||
|
_LOGGER.debug("Unloaded entry for %s", entry.title)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
@ -8,7 +8,10 @@ import async_timeout
|
|||||||
import pysensibo
|
import pysensibo
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.climate import PLATFORM_SCHEMA, ClimateEntity
|
from homeassistant.components.climate import (
|
||||||
|
PLATFORM_SCHEMA as PARENT_PLATFORM_SCHEMA,
|
||||||
|
ClimateEntity,
|
||||||
|
)
|
||||||
from homeassistant.components.climate.const import (
|
from homeassistant.components.climate.const import (
|
||||||
HVAC_MODE_COOL,
|
HVAC_MODE_COOL,
|
||||||
HVAC_MODE_DRY,
|
HVAC_MODE_DRY,
|
||||||
@ -20,6 +23,7 @@ from homeassistant.components.climate.const import (
|
|||||||
SUPPORT_SWING_MODE,
|
SUPPORT_SWING_MODE,
|
||||||
SUPPORT_TARGET_TEMPERATURE,
|
SUPPORT_TARGET_TEMPERATURE,
|
||||||
)
|
)
|
||||||
|
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ENTITY_ID,
|
ATTR_ENTITY_ID,
|
||||||
ATTR_STATE,
|
ATTR_STATE,
|
||||||
@ -30,21 +34,22 @@ from homeassistant.const import (
|
|||||||
TEMP_CELSIUS,
|
TEMP_CELSIUS,
|
||||||
TEMP_FAHRENHEIT,
|
TEMP_FAHRENHEIT,
|
||||||
)
|
)
|
||||||
from homeassistant.exceptions import PlatformNotReady
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.entity_platform import (
|
||||||
|
AddEntitiesCallback,
|
||||||
|
ConfigType,
|
||||||
|
DiscoveryInfoType,
|
||||||
|
)
|
||||||
from homeassistant.util.temperature import convert as convert_temperature
|
from homeassistant.util.temperature import convert as convert_temperature
|
||||||
|
|
||||||
from .const import DOMAIN as SENSIBO_DOMAIN
|
from .const import _FETCH_FIELDS, ALL, DOMAIN, TIMEOUT
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
ALL = ["all"]
|
|
||||||
TIMEOUT = 8
|
|
||||||
|
|
||||||
SERVICE_ASSUME_STATE = "assume_state"
|
SERVICE_ASSUME_STATE = "assume_state"
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
PLATFORM_SCHEMA = PARENT_PLATFORM_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
vol.Required(CONF_API_KEY): cv.string,
|
vol.Required(CONF_API_KEY): cv.string,
|
||||||
vol.Optional(CONF_ID, default=ALL): vol.All(cv.ensure_list, [cv.string]),
|
vol.Optional(CONF_ID, default=ALL): vol.All(cv.ensure_list, [cv.string]),
|
||||||
@ -55,18 +60,6 @@ ASSUME_STATE_SCHEMA = vol.Schema(
|
|||||||
{vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, vol.Required(ATTR_STATE): cv.string}
|
{vol.Optional(ATTR_ENTITY_ID): cv.entity_ids, vol.Required(ATTR_STATE): cv.string}
|
||||||
)
|
)
|
||||||
|
|
||||||
_FETCH_FIELDS = ",".join(
|
|
||||||
[
|
|
||||||
"room{name}",
|
|
||||||
"measurements",
|
|
||||||
"remoteCapabilities",
|
|
||||||
"acState",
|
|
||||||
"connectionStatus{isAlive}",
|
|
||||||
"temperatureUnit",
|
|
||||||
]
|
|
||||||
)
|
|
||||||
_INITIAL_FETCH_FIELDS = f"id,{_FETCH_FIELDS}"
|
|
||||||
|
|
||||||
FIELD_TO_FLAG = {
|
FIELD_TO_FLAG = {
|
||||||
"fanLevel": SUPPORT_FAN_MODE,
|
"fanLevel": SUPPORT_FAN_MODE,
|
||||||
"swing": SUPPORT_SWING_MODE,
|
"swing": SUPPORT_SWING_MODE,
|
||||||
@ -84,29 +77,38 @@ SENSIBO_TO_HA = {
|
|||||||
HA_TO_SENSIBO = {value: key for key, value in SENSIBO_TO_HA.items()}
|
HA_TO_SENSIBO = {value: key for key, value in SENSIBO_TO_HA.items()}
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
async def async_setup_platform(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config: ConfigType,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
discovery_info: DiscoveryInfoType = None,
|
||||||
|
):
|
||||||
"""Set up Sensibo devices."""
|
"""Set up Sensibo devices."""
|
||||||
client = pysensibo.SensiboClient(
|
_LOGGER.warning(
|
||||||
config[CONF_API_KEY], session=async_get_clientsession(hass), timeout=TIMEOUT
|
"Loading Sensibo via platform setup is deprecated; Please remove it from your configuration"
|
||||||
|
)
|
||||||
|
hass.async_create_task(
|
||||||
|
hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
context={"source": SOURCE_IMPORT},
|
||||||
|
data=config,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
devices = []
|
|
||||||
try:
|
|
||||||
async with async_timeout.timeout(TIMEOUT):
|
|
||||||
for dev in await client.async_get_devices(_INITIAL_FETCH_FIELDS):
|
|
||||||
if config[CONF_ID] == ALL or dev["id"] in config[CONF_ID]:
|
|
||||||
devices.append(
|
|
||||||
SensiboClimate(client, dev, hass.config.units.temperature_unit)
|
|
||||||
)
|
|
||||||
except (
|
|
||||||
aiohttp.client_exceptions.ClientConnectorError,
|
|
||||||
asyncio.TimeoutError,
|
|
||||||
pysensibo.SensiboError,
|
|
||||||
) as err:
|
|
||||||
_LOGGER.error("Failed to get devices from Sensibo servers")
|
|
||||||
raise PlatformNotReady from err
|
|
||||||
|
|
||||||
if not devices:
|
|
||||||
return
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
||||||
|
) -> None:
|
||||||
|
"""Set up the Sensibo climate entry."""
|
||||||
|
|
||||||
|
data = hass.data[DOMAIN][entry.entry_id]
|
||||||
|
client = data["client"]
|
||||||
|
devicelist = data["devices"]
|
||||||
|
|
||||||
|
devices = [
|
||||||
|
SensiboClimate(client, dev, hass.config.units.temperature_unit)
|
||||||
|
for dev in devicelist
|
||||||
|
]
|
||||||
|
|
||||||
async_add_entities(devices)
|
async_add_entities(devices)
|
||||||
|
|
||||||
@ -128,7 +130,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
|
|||||||
await asyncio.wait(update_tasks)
|
await asyncio.wait(update_tasks)
|
||||||
|
|
||||||
hass.services.async_register(
|
hass.services.async_register(
|
||||||
SENSIBO_DOMAIN,
|
DOMAIN,
|
||||||
SERVICE_ASSUME_STATE,
|
SERVICE_ASSUME_STATE,
|
||||||
async_assume_state,
|
async_assume_state,
|
||||||
schema=ASSUME_STATE_SCHEMA,
|
schema=ASSUME_STATE_SCHEMA,
|
||||||
|
91
homeassistant/components/sensibo/config_flow.py
Normal file
91
homeassistant/components/sensibo/config_flow.py
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
"""Adds config flow for Sensibo integration."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
|
import async_timeout
|
||||||
|
from pysensibo import SensiboClient, SensiboError
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant import config_entries
|
||||||
|
from homeassistant.const import CONF_API_KEY, CONF_NAME
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
|
||||||
|
from .const import _INITIAL_FETCH_FIELDS, DEFAULT_NAME, DOMAIN, TIMEOUT
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
DATA_SCHEMA = vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(CONF_API_KEY): cv.string,
|
||||||
|
vol.Required(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_validate_api(hass: HomeAssistant, api_key: str) -> bool:
|
||||||
|
"""Get data from API."""
|
||||||
|
client = SensiboClient(
|
||||||
|
api_key,
|
||||||
|
session=async_get_clientsession(hass),
|
||||||
|
timeout=TIMEOUT,
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
async with async_timeout.timeout(TIMEOUT):
|
||||||
|
if await client.async_get_devices(_INITIAL_FETCH_FIELDS):
|
||||||
|
return True
|
||||||
|
except (
|
||||||
|
aiohttp.ClientConnectionError,
|
||||||
|
asyncio.TimeoutError,
|
||||||
|
SensiboError,
|
||||||
|
) as err:
|
||||||
|
_LOGGER.error("Failed to get devices from Sensibo servers %s", err)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class SensiboConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
|
"""Handle a config flow for Sensibo integration."""
|
||||||
|
|
||||||
|
VERSION = 1
|
||||||
|
|
||||||
|
async def async_step_import(self, config: dict):
|
||||||
|
"""Import a configuration from config.yaml."""
|
||||||
|
|
||||||
|
self.context.update(
|
||||||
|
{"title_placeholders": {"Sensibo": f"YAML import {DOMAIN}"}}
|
||||||
|
)
|
||||||
|
if CONF_NAME not in config:
|
||||||
|
config[CONF_NAME] = DEFAULT_NAME
|
||||||
|
return await self.async_step_user(user_input=config)
|
||||||
|
|
||||||
|
async def async_step_user(self, user_input=None):
|
||||||
|
"""Handle the initial step."""
|
||||||
|
|
||||||
|
errors: dict[str, str] = {}
|
||||||
|
|
||||||
|
if user_input is not None:
|
||||||
|
|
||||||
|
api_key = user_input[CONF_API_KEY]
|
||||||
|
name = user_input[CONF_NAME]
|
||||||
|
|
||||||
|
await self.async_set_unique_id(api_key)
|
||||||
|
self._abort_if_unique_id_configured()
|
||||||
|
|
||||||
|
validate = await async_validate_api(self.hass, api_key)
|
||||||
|
if validate:
|
||||||
|
return self.async_create_entry(
|
||||||
|
title=name,
|
||||||
|
data={CONF_NAME: name, CONF_API_KEY: api_key},
|
||||||
|
)
|
||||||
|
errors["base"] = "cannot_connect"
|
||||||
|
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="user",
|
||||||
|
data_schema=DATA_SCHEMA,
|
||||||
|
errors=errors,
|
||||||
|
)
|
@ -1,3 +1,18 @@
|
|||||||
"""Constants for Sensibo."""
|
"""Constants for Sensibo."""
|
||||||
|
|
||||||
DOMAIN = "sensibo"
|
DOMAIN = "sensibo"
|
||||||
|
PLATFORMS = ["climate"]
|
||||||
|
ALL = ["all"]
|
||||||
|
DEFAULT_NAME = "Sensibo@Home"
|
||||||
|
TIMEOUT = 8
|
||||||
|
_FETCH_FIELDS = ",".join(
|
||||||
|
[
|
||||||
|
"room{name}",
|
||||||
|
"measurements",
|
||||||
|
"remoteCapabilities",
|
||||||
|
"acState",
|
||||||
|
"connectionStatus{isAlive}",
|
||||||
|
"temperatureUnit",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
_INITIAL_FETCH_FIELDS = f"id,{_FETCH_FIELDS}"
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
"name": "Sensibo",
|
"name": "Sensibo",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/sensibo",
|
"documentation": "https://www.home-assistant.io/integrations/sensibo",
|
||||||
"requirements": ["pysensibo==1.0.3"],
|
"requirements": ["pysensibo==1.0.3"],
|
||||||
"codeowners": ["@andrey-git"],
|
"config_flow": true,
|
||||||
"iot_class": "cloud_polling"
|
"codeowners": ["@andrey-git", "@gjohansson-ST"],
|
||||||
|
"iot_class": "cloud_polling",
|
||||||
|
"homekit": {
|
||||||
|
"models": ["Sensibo"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
18
homeassistant/components/sensibo/strings.json
Normal file
18
homeassistant/components/sensibo/strings.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]"
|
||||||
|
},
|
||||||
|
"error":{
|
||||||
|
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"api_key": "[%key:common::config_flow::data::api_key%]",
|
||||||
|
"name": "[%key:common::config_flow::data::name%]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
homeassistant/components/sensibo/translations/en.json
Normal file
18
homeassistant/components/sensibo/translations/en.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"abort": {
|
||||||
|
"already_configured": "Account is already configured"
|
||||||
|
},
|
||||||
|
"error":{
|
||||||
|
"cannot_connect": "Failed to connect"
|
||||||
|
},
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"api_key": "API Key",
|
||||||
|
"name": "Name"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -263,6 +263,7 @@ FLOWS = [
|
|||||||
"samsungtv",
|
"samsungtv",
|
||||||
"screenlogic",
|
"screenlogic",
|
||||||
"sense",
|
"sense",
|
||||||
|
"sensibo",
|
||||||
"sentry",
|
"sentry",
|
||||||
"sharkiq",
|
"sharkiq",
|
||||||
"shelly",
|
"shelly",
|
||||||
|
@ -369,6 +369,7 @@ HOMEKIT = {
|
|||||||
"Presence": "netatmo",
|
"Presence": "netatmo",
|
||||||
"Rachio": "rachio",
|
"Rachio": "rachio",
|
||||||
"SPK5": "rainmachine",
|
"SPK5": "rainmachine",
|
||||||
|
"Sensibo": "sensibo",
|
||||||
"Smart Bridge": "lutron_caseta",
|
"Smart Bridge": "lutron_caseta",
|
||||||
"Socket": "wemo",
|
"Socket": "wemo",
|
||||||
"TRADFRI": "tradfri",
|
"TRADFRI": "tradfri",
|
||||||
|
@ -1102,6 +1102,9 @@ pyrituals==0.0.6
|
|||||||
# homeassistant.components.ruckus_unleashed
|
# homeassistant.components.ruckus_unleashed
|
||||||
pyruckus==0.12
|
pyruckus==0.12
|
||||||
|
|
||||||
|
# homeassistant.components.sensibo
|
||||||
|
pysensibo==1.0.3
|
||||||
|
|
||||||
# homeassistant.components.serial
|
# homeassistant.components.serial
|
||||||
# homeassistant.components.zha
|
# homeassistant.components.zha
|
||||||
pyserial-asyncio==0.5
|
pyserial-asyncio==0.5
|
||||||
|
1
tests/components/sensibo/__init__.py
Normal file
1
tests/components/sensibo/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
"""Tests for the Sensibo integration."""
|
155
tests/components/sensibo/test_config_flow.py
Normal file
155
tests/components/sensibo/test_config_flow.py
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
"""Test the Sensibo config flow."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
|
from pysensibo import SensiboError
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant import config_entries
|
||||||
|
from homeassistant.const import CONF_API_KEY, CONF_NAME
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.data_entry_flow import (
|
||||||
|
RESULT_TYPE_ABORT,
|
||||||
|
RESULT_TYPE_CREATE_ENTRY,
|
||||||
|
RESULT_TYPE_FORM,
|
||||||
|
)
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
DOMAIN = "sensibo"
|
||||||
|
|
||||||
|
|
||||||
|
def devices():
|
||||||
|
"""Return list of test devices."""
|
||||||
|
return (yield from [{"id": "xyzxyz"}, {"id": "abcabc"}])
|
||||||
|
|
||||||
|
|
||||||
|
async def test_form(hass: HomeAssistant) -> None:
|
||||||
|
"""Test we get the form."""
|
||||||
|
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||||
|
)
|
||||||
|
assert result["step_id"] == "user"
|
||||||
|
assert result["type"] == RESULT_TYPE_FORM
|
||||||
|
assert result["errors"] == {}
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.sensibo.config_flow.SensiboClient.async_get_devices",
|
||||||
|
return_value=devices(),
|
||||||
|
), patch(
|
||||||
|
"homeassistant.components.sensibo.async_setup_entry",
|
||||||
|
return_value=True,
|
||||||
|
) as mock_setup_entry:
|
||||||
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
{
|
||||||
|
CONF_NAME: "Sensibo@Home",
|
||||||
|
CONF_API_KEY: "1234567890",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result2["type"] == RESULT_TYPE_CREATE_ENTRY
|
||||||
|
assert result2["data"] == {
|
||||||
|
"name": "Sensibo@Home",
|
||||||
|
"api_key": "1234567890",
|
||||||
|
}
|
||||||
|
|
||||||
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_import_flow_success(hass: HomeAssistant) -> None:
|
||||||
|
"""Test a successful import of yaml."""
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.sensibo.config_flow.SensiboClient.async_get_devices",
|
||||||
|
return_value=devices(),
|
||||||
|
), patch(
|
||||||
|
"homeassistant.components.sensibo.async_setup_entry",
|
||||||
|
return_value=True,
|
||||||
|
) as mock_setup_entry:
|
||||||
|
result2 = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
context={"source": config_entries.SOURCE_IMPORT},
|
||||||
|
data={
|
||||||
|
CONF_API_KEY: "1234567890",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result2["type"] == RESULT_TYPE_CREATE_ENTRY
|
||||||
|
assert result2["title"] == "Sensibo@Home"
|
||||||
|
assert result2["data"] == {
|
||||||
|
"name": "Sensibo@Home",
|
||||||
|
"api_key": "1234567890",
|
||||||
|
}
|
||||||
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_import_flow_already_exist(hass: HomeAssistant) -> None:
|
||||||
|
"""Test import of yaml already exist."""
|
||||||
|
|
||||||
|
MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
data={
|
||||||
|
CONF_NAME: "Sensibo@Home",
|
||||||
|
CONF_API_KEY: "1234567890",
|
||||||
|
},
|
||||||
|
unique_id="1234567890",
|
||||||
|
).add_to_hass(hass)
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.sensibo.async_setup_entry",
|
||||||
|
return_value=True,
|
||||||
|
), patch(
|
||||||
|
"homeassistant.components.sensibo.config_flow.SensiboClient.async_get_devices",
|
||||||
|
return_value=devices(),
|
||||||
|
):
|
||||||
|
result3 = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
context={"source": config_entries.SOURCE_IMPORT},
|
||||||
|
data={
|
||||||
|
CONF_API_KEY: "1234567890",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result3["type"] == RESULT_TYPE_ABORT
|
||||||
|
assert result3["reason"] == "already_configured"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"error_message",
|
||||||
|
[
|
||||||
|
(aiohttp.ClientConnectionError),
|
||||||
|
(asyncio.TimeoutError),
|
||||||
|
(SensiboError),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_flow_fails(hass: HomeAssistant, error_message) -> None:
|
||||||
|
"""Test config flow errors."""
|
||||||
|
|
||||||
|
result4 = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result4["type"] == RESULT_TYPE_FORM
|
||||||
|
assert result4["step_id"] == config_entries.SOURCE_USER
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.sensibo.config_flow.SensiboClient.async_get_devices",
|
||||||
|
side_effect=error_message,
|
||||||
|
):
|
||||||
|
result4 = await hass.config_entries.flow.async_configure(
|
||||||
|
result4["flow_id"],
|
||||||
|
user_input={
|
||||||
|
CONF_NAME: "Sensibo@Home",
|
||||||
|
CONF_API_KEY: "1234567890",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result4["errors"] == {"base": "cannot_connect"}
|
Loading…
x
Reference in New Issue
Block a user