Remove Xiaomi Miio YAML import (#78995)
* Deprecate YAML import * Add logging for unexpected errors * remove unused import * fix tests * unused import * fix tests * fix snake_case * Do not add to standard key string
This commit is contained in:
parent
3aa24afad8
commit
a2080492de
5 changed files with 70 additions and 58 deletions
|
@ -383,10 +383,6 @@ async def async_setup_gateway_entry(hass: HomeAssistant, entry: ConfigEntry) ->
|
|||
|
||||
assert gateway_id
|
||||
|
||||
# For backwards compat
|
||||
if gateway_id.endswith("-gateway"):
|
||||
hass.config_entries.async_update_entry(entry, unique_id=entry.data["mac"])
|
||||
|
||||
# Connect to gateway
|
||||
gateway = ConnectXiaomiGateway(hass, entry)
|
||||
try:
|
||||
|
|
|
@ -13,7 +13,7 @@ import voluptuous as vol
|
|||
from homeassistant import config_entries
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntry
|
||||
from homeassistant.const import CONF_HOST, CONF_MODEL, CONF_NAME, CONF_TOKEN
|
||||
from homeassistant.const import CONF_HOST, CONF_MODEL, CONF_TOKEN
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.helpers.device_registry import format_mac
|
||||
|
@ -145,18 +145,6 @@ class XiaomiMiioFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
return await self.async_step_cloud()
|
||||
return self.async_show_form(step_id="reauth_confirm")
|
||||
|
||||
async def async_step_import(self, conf: dict[str, Any]) -> FlowResult:
|
||||
"""Import a configuration from config.yaml."""
|
||||
self.host = conf[CONF_HOST]
|
||||
self.token = conf[CONF_TOKEN]
|
||||
self.name = conf.get(CONF_NAME)
|
||||
self.model = conf.get(CONF_MODEL)
|
||||
|
||||
self.context.update(
|
||||
{"title_placeholders": {"name": f"YAML import {self.host}"}}
|
||||
)
|
||||
return await self.async_step_connect()
|
||||
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> FlowResult:
|
||||
|
@ -250,15 +238,22 @@ class XiaomiMiioFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
errors["base"] = "cloud_login_error"
|
||||
except MiCloudAccessDenied:
|
||||
errors["base"] = "cloud_login_error"
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unexpected exception in Miio cloud login")
|
||||
return self.async_abort(reason="unknown")
|
||||
|
||||
if errors:
|
||||
return self.async_show_form(
|
||||
step_id="cloud", data_schema=DEVICE_CLOUD_CONFIG, errors=errors
|
||||
)
|
||||
|
||||
devices_raw = await self.hass.async_add_executor_job(
|
||||
miio_cloud.get_devices, cloud_country
|
||||
)
|
||||
try:
|
||||
devices_raw = await self.hass.async_add_executor_job(
|
||||
miio_cloud.get_devices, cloud_country
|
||||
)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unexpected exception in Miio cloud get devices")
|
||||
return self.async_abort(reason="unknown")
|
||||
|
||||
if not devices_raw:
|
||||
errors["base"] = "cloud_no_devices"
|
||||
|
@ -353,6 +348,9 @@ class XiaomiMiioFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
except SetupException:
|
||||
if self.model is None:
|
||||
errors["base"] = "cannot_connect"
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unexpected exception in connect Xiaomi device")
|
||||
return self.async_abort(reason="unknown")
|
||||
|
||||
device_info = connect_device_class.device_info
|
||||
|
||||
|
@ -386,8 +384,8 @@ class XiaomiMiioFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
data[CONF_CLOUD_USERNAME] = self.cloud_username
|
||||
data[CONF_CLOUD_PASSWORD] = self.cloud_password
|
||||
data[CONF_CLOUD_COUNTRY] = self.cloud_country
|
||||
self.hass.config_entries.async_update_entry(existing_entry, data=data)
|
||||
await self.hass.config_entries.async_reload(existing_entry.entry_id)
|
||||
if self.hass.config_entries.async_update_entry(existing_entry, data=data):
|
||||
await self.hass.config_entries.async_reload(existing_entry.entry_id)
|
||||
return self.async_abort(reason="reauth_successful")
|
||||
|
||||
if self.name is None:
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]",
|
||||
"already_in_progress": "[%key:common::config_flow::abort::already_in_progress%]",
|
||||
"incomplete_info": "Incomplete information to setup device, no host or token supplied.",
|
||||
"not_xiaomi_miio": "Device is not (yet) supported by Xiaomi Miio."
|
||||
"not_xiaomi_miio": "Device is not (yet) supported by Xiaomi Miio.",
|
||||
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
"already_in_progress": "Configuration flow is already in progress",
|
||||
"incomplete_info": "Incomplete information to setup device, no host or token supplied.",
|
||||
"not_xiaomi_miio": "Device is not (yet) supported by Xiaomi Miio.",
|
||||
"reauth_successful": "Re-authentication was successful"
|
||||
"reauth_successful": "Re-authentication was successful",
|
||||
"unknown": "Unexpected error"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Failed to connect",
|
||||
|
|
|
@ -9,7 +9,7 @@ import pytest
|
|||
from homeassistant import config_entries, data_entry_flow
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.components.xiaomi_miio import const
|
||||
from homeassistant.const import CONF_HOST, CONF_MODEL, CONF_NAME, CONF_TOKEN
|
||||
from homeassistant.const import CONF_HOST, CONF_MODEL, CONF_TOKEN
|
||||
|
||||
from . import TEST_MAC
|
||||
|
||||
|
@ -67,7 +67,7 @@ TEST_CLOUD_DEVICES_2 = [
|
|||
|
||||
@pytest.fixture(name="xiaomi_miio_connect", autouse=True)
|
||||
def xiaomi_miio_connect_fixture():
|
||||
"""Mock denonavr connection and entry setup."""
|
||||
"""Mock miio connection and entry setup."""
|
||||
mock_info = get_mock_info()
|
||||
|
||||
with patch(
|
||||
|
@ -320,6 +320,22 @@ async def test_config_flow_gateway_cloud_login_error(hass):
|
|||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {"base": "cloud_login_error"}
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.config_flow.MiCloud.login",
|
||||
side_effect=Exception({}),
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
const.CONF_CLOUD_USERNAME: TEST_CLOUD_USER,
|
||||
const.CONF_CLOUD_PASSWORD: TEST_CLOUD_PASS,
|
||||
const.CONF_CLOUD_COUNTRY: TEST_CLOUD_COUNTRY,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == "abort"
|
||||
assert result["reason"] == "unknown"
|
||||
|
||||
|
||||
async def test_config_flow_gateway_cloud_no_devices(hass):
|
||||
"""Test a failed config flow using cloud with no devices."""
|
||||
|
@ -348,6 +364,22 @@ async def test_config_flow_gateway_cloud_no_devices(hass):
|
|||
assert result["step_id"] == "cloud"
|
||||
assert result["errors"] == {"base": "cloud_no_devices"}
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.config_flow.MiCloud.get_devices",
|
||||
side_effect=Exception({}),
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{
|
||||
const.CONF_CLOUD_USERNAME: TEST_CLOUD_USER,
|
||||
const.CONF_CLOUD_PASSWORD: TEST_CLOUD_PASS,
|
||||
const.CONF_CLOUD_COUNTRY: TEST_CLOUD_COUNTRY,
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] == "abort"
|
||||
assert result["reason"] == "unknown"
|
||||
|
||||
|
||||
async def test_config_flow_gateway_cloud_missing_token(hass):
|
||||
"""Test a failed config flow using cloud with a missing token."""
|
||||
|
@ -558,34 +590,6 @@ async def test_config_flow_step_unknown_device(hass):
|
|||
assert result["errors"] == {"base": "unknown_device"}
|
||||
|
||||
|
||||
async def test_import_flow_success(hass):
|
||||
"""Test a successful import form yaml for a device."""
|
||||
mock_info = get_mock_info(model=const.MODELS_SWITCH[0])
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.device.Device.info",
|
||||
return_value=mock_info,
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
const.DOMAIN,
|
||||
context={"source": config_entries.SOURCE_IMPORT},
|
||||
data={CONF_NAME: TEST_NAME, CONF_HOST: TEST_HOST, CONF_TOKEN: TEST_TOKEN},
|
||||
)
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == TEST_NAME
|
||||
assert result["data"] == {
|
||||
const.CONF_FLOW_TYPE: const.CONF_DEVICE,
|
||||
const.CONF_CLOUD_USERNAME: None,
|
||||
const.CONF_CLOUD_PASSWORD: None,
|
||||
const.CONF_CLOUD_COUNTRY: None,
|
||||
CONF_HOST: TEST_HOST,
|
||||
CONF_TOKEN: TEST_TOKEN,
|
||||
CONF_MODEL: const.MODELS_SWITCH[0],
|
||||
const.CONF_MAC: TEST_MAC,
|
||||
}
|
||||
|
||||
|
||||
async def test_config_flow_step_device_manual_model_error(hass):
|
||||
"""Test config flow, device connection error, model None."""
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
|
@ -618,6 +622,18 @@ async def test_config_flow_step_device_manual_model_error(hass):
|
|||
assert result["step_id"] == "connect"
|
||||
assert result["errors"] == {"base": "cannot_connect"}
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.device.Device.info",
|
||||
side_effect=Exception({}),
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
{CONF_MODEL: TEST_MODEL},
|
||||
)
|
||||
|
||||
assert result["type"] == "abort"
|
||||
assert result["reason"] == "unknown"
|
||||
|
||||
|
||||
async def test_config_flow_step_device_manual_model_succes(hass):
|
||||
"""Test config flow, device connection error, manual model."""
|
||||
|
@ -724,7 +740,7 @@ async def config_flow_device_success(hass, model_to_test):
|
|||
|
||||
async def config_flow_generic_roborock(hass):
|
||||
"""Test a successful config flow for a generic roborock vacuum."""
|
||||
DUMMY_MODEL = "roborock.vacuum.dummy"
|
||||
dummy_model = "roborock.vacuum.dummy"
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
const.DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
|
@ -743,7 +759,7 @@ async def config_flow_generic_roborock(hass):
|
|||
assert result["step_id"] == "manual"
|
||||
assert result["errors"] == {}
|
||||
|
||||
mock_info = get_mock_info(model=DUMMY_MODEL)
|
||||
mock_info = get_mock_info(model=dummy_model)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.xiaomi_miio.device.Device.info",
|
||||
|
@ -755,7 +771,7 @@ async def config_flow_generic_roborock(hass):
|
|||
)
|
||||
|
||||
assert result["type"] == "create_entry"
|
||||
assert result["title"] == DUMMY_MODEL
|
||||
assert result["title"] == dummy_model
|
||||
assert result["data"] == {
|
||||
const.CONF_FLOW_TYPE: const.CONF_DEVICE,
|
||||
const.CONF_CLOUD_USERNAME: None,
|
||||
|
@ -763,7 +779,7 @@ async def config_flow_generic_roborock(hass):
|
|||
const.CONF_CLOUD_COUNTRY: None,
|
||||
CONF_HOST: TEST_HOST,
|
||||
CONF_TOKEN: TEST_TOKEN,
|
||||
CONF_MODEL: DUMMY_MODEL,
|
||||
CONF_MODEL: dummy_model,
|
||||
const.CONF_MAC: TEST_MAC,
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue