mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Use ConfigFlow.has_matching_flow to deduplicate yalexs_ble flows (#126899)
This commit is contained in:
parent
616c0ebaa4
commit
46812777e2
@ -4,7 +4,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from collections.abc import Mapping
|
from collections.abc import Mapping
|
||||||
import logging
|
import logging
|
||||||
from typing import Any
|
from typing import Any, Self
|
||||||
|
|
||||||
from bleak_retry_connector import BleakError, BLEDevice
|
from bleak_retry_connector import BleakError, BLEDevice
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
@ -68,6 +68,11 @@ class YalexsConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
|
|
||||||
VERSION = 1
|
VERSION = 1
|
||||||
|
|
||||||
|
_address: str | None = None
|
||||||
|
_local_name_is_unique = False
|
||||||
|
active = False
|
||||||
|
local_name: str | None = None
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
"""Initialize the config flow."""
|
"""Initialize the config flow."""
|
||||||
self._discovery_info: BluetoothServiceInfoBleak | None = None
|
self._discovery_info: BluetoothServiceInfoBleak | None = None
|
||||||
@ -81,7 +86,7 @@ class YalexsConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
"""Handle the bluetooth discovery step."""
|
"""Handle the bluetooth discovery step."""
|
||||||
await self.async_set_unique_id(discovery_info.address)
|
await self.async_set_unique_id(discovery_info.address)
|
||||||
self._abort_if_unique_id_configured()
|
self._abort_if_unique_id_configured()
|
||||||
self.context["local_name"] = discovery_info.name
|
self.local_name = discovery_info.name
|
||||||
self._discovery_info = discovery_info
|
self._discovery_info = discovery_info
|
||||||
self.context["title_placeholders"] = {
|
self.context["title_placeholders"] = {
|
||||||
"name": human_readable_name(
|
"name": human_readable_name(
|
||||||
@ -103,8 +108,8 @@ class YalexsConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
)
|
)
|
||||||
|
|
||||||
address = lock_cfg.address
|
address = lock_cfg.address
|
||||||
local_name = lock_cfg.local_name
|
self.local_name = lock_cfg.local_name
|
||||||
hass = self.hass
|
self._local_name_is_unique = local_name_is_unique(self.local_name)
|
||||||
|
|
||||||
# We do not want to raise on progress as integration_discovery takes
|
# We do not want to raise on progress as integration_discovery takes
|
||||||
# precedence over other discovery flows since we already have the keys.
|
# precedence over other discovery flows since we already have the keys.
|
||||||
@ -116,7 +121,7 @@ class YalexsConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
self._abort_if_unique_id_configured(updates=new_data)
|
self._abort_if_unique_id_configured(updates=new_data)
|
||||||
for entry in self._async_current_entries():
|
for entry in self._async_current_entries():
|
||||||
if (
|
if (
|
||||||
local_name_is_unique(lock_cfg.local_name)
|
self._local_name_is_unique
|
||||||
and entry.data.get(CONF_LOCAL_NAME) == lock_cfg.local_name
|
and entry.data.get(CONF_LOCAL_NAME) == lock_cfg.local_name
|
||||||
):
|
):
|
||||||
return self.async_update_reload_and_abort(
|
return self.async_update_reload_and_abort(
|
||||||
@ -124,27 +129,14 @@ class YalexsConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self._discovery_info = async_find_existing_service_info(
|
self._discovery_info = async_find_existing_service_info(
|
||||||
hass, local_name, address
|
self.hass, self.local_name, address
|
||||||
)
|
)
|
||||||
if not self._discovery_info:
|
if not self._discovery_info:
|
||||||
return self.async_abort(reason="no_devices_found")
|
return self.async_abort(reason="no_devices_found")
|
||||||
|
|
||||||
# Integration discovery should abort other flows unless they
|
self._address = address
|
||||||
# are already in the process of being set up since this discovery
|
if self.hass.config_entries.flow.async_has_matching_flow(self):
|
||||||
# will already have all the keys and the user can simply confirm.
|
|
||||||
for progress in self._async_in_progress(include_uninitialized=True):
|
|
||||||
context = progress["context"]
|
|
||||||
if (
|
|
||||||
local_name_is_unique(local_name)
|
|
||||||
and context.get("local_name") == local_name
|
|
||||||
) or context.get("unique_id") == address:
|
|
||||||
if context.get("active"):
|
|
||||||
# The user has already started interacting with this flow
|
|
||||||
# and entered the keys. We abort the discovery flow since
|
|
||||||
# we assume they do not want to use the discovered keys for
|
|
||||||
# some reason.
|
|
||||||
raise AbortFlow("already_in_progress")
|
raise AbortFlow("already_in_progress")
|
||||||
hass.config_entries.flow.async_abort(progress["flow_id"])
|
|
||||||
|
|
||||||
self._lock_cfg = lock_cfg
|
self._lock_cfg = lock_cfg
|
||||||
self.context["title_placeholders"] = {
|
self.context["title_placeholders"] = {
|
||||||
@ -154,6 +146,24 @@ class YalexsConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
}
|
}
|
||||||
return await self.async_step_integration_discovery_confirm()
|
return await self.async_step_integration_discovery_confirm()
|
||||||
|
|
||||||
|
def is_matching(self, other_flow: Self) -> bool:
|
||||||
|
"""Return True if other_flow is matching this flow."""
|
||||||
|
# Integration discovery should abort other flows unless they
|
||||||
|
# are already in the process of being set up since this discovery
|
||||||
|
# will already have all the keys and the user can simply confirm.
|
||||||
|
if (
|
||||||
|
self._local_name_is_unique and other_flow.local_name == self.local_name
|
||||||
|
) or other_flow.unique_id == self._address:
|
||||||
|
if other_flow.active:
|
||||||
|
# The user has already started interacting with this flow
|
||||||
|
# and entered the keys. We abort the discovery flow since
|
||||||
|
# we assume they do not want to use the discovered keys for
|
||||||
|
# some reason.
|
||||||
|
return True
|
||||||
|
self.hass.config_entries.flow.async_abort(other_flow.flow_id)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
async def async_step_integration_discovery_confirm(
|
async def async_step_integration_discovery_confirm(
|
||||||
self, user_input: dict[str, Any] | None = None
|
self, user_input: dict[str, Any] | None = None
|
||||||
) -> ConfigFlowResult:
|
) -> ConfigFlowResult:
|
||||||
@ -234,7 +244,7 @@ class YalexsConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||||||
errors: dict[str, str] = {}
|
errors: dict[str, str] = {}
|
||||||
|
|
||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
self.context["active"] = True
|
self.active = True
|
||||||
address = user_input[CONF_ADDRESS]
|
address = user_input[CONF_ADDRESS]
|
||||||
discovery_info = self._discovered_devices[address]
|
discovery_info = self._discovered_devices[address]
|
||||||
local_name = discovery_info.name
|
local_name = discovery_info.name
|
||||||
|
@ -513,14 +513,10 @@ async def test_integration_discovery_takes_precedence_over_bluetooth(
|
|||||||
assert result["type"] is FlowResultType.FORM
|
assert result["type"] is FlowResultType.FORM
|
||||||
assert result["step_id"] == "user"
|
assert result["step_id"] == "user"
|
||||||
assert result["errors"] == {}
|
assert result["errors"] == {}
|
||||||
flows = [
|
flows = list(hass.config_entries.flow._handler_progress_index[DOMAIN])
|
||||||
flow
|
|
||||||
for flow in hass.config_entries.flow.async_progress()
|
|
||||||
if flow["handler"] == DOMAIN
|
|
||||||
]
|
|
||||||
assert len(flows) == 1
|
assert len(flows) == 1
|
||||||
assert flows[0]["context"]["unique_id"] == YALE_ACCESS_LOCK_DISCOVERY_INFO.address
|
assert flows[0].unique_id == YALE_ACCESS_LOCK_DISCOVERY_INFO.address
|
||||||
assert flows[0]["context"]["local_name"] == YALE_ACCESS_LOCK_DISCOVERY_INFO.name
|
assert flows[0].local_name == YALE_ACCESS_LOCK_DISCOVERY_INFO.name
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.yalexs_ble.util.async_discovered_service_info",
|
"homeassistant.components.yalexs_ble.util.async_discovered_service_info",
|
||||||
@ -728,14 +724,10 @@ async def test_integration_discovery_takes_precedence_over_bluetooth_uuid_addres
|
|||||||
assert result["type"] is FlowResultType.FORM
|
assert result["type"] is FlowResultType.FORM
|
||||||
assert result["step_id"] == "user"
|
assert result["step_id"] == "user"
|
||||||
assert result["errors"] == {}
|
assert result["errors"] == {}
|
||||||
flows = [
|
flows = list(hass.config_entries.flow._handler_progress_index[DOMAIN])
|
||||||
flow
|
|
||||||
for flow in hass.config_entries.flow.async_progress()
|
|
||||||
if flow["handler"] == DOMAIN
|
|
||||||
]
|
|
||||||
assert len(flows) == 1
|
assert len(flows) == 1
|
||||||
assert flows[0]["context"]["unique_id"] == LOCK_DISCOVERY_INFO_UUID_ADDRESS.address
|
assert flows[0].unique_id == LOCK_DISCOVERY_INFO_UUID_ADDRESS.address
|
||||||
assert flows[0]["context"]["local_name"] == LOCK_DISCOVERY_INFO_UUID_ADDRESS.name
|
assert flows[0].local_name == LOCK_DISCOVERY_INFO_UUID_ADDRESS.name
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.yalexs_ble.util.async_discovered_service_info",
|
"homeassistant.components.yalexs_ble.util.async_discovered_service_info",
|
||||||
@ -808,14 +800,10 @@ async def test_integration_discovery_takes_precedence_over_bluetooth_non_unique_
|
|||||||
assert result["type"] is FlowResultType.FORM
|
assert result["type"] is FlowResultType.FORM
|
||||||
assert result["step_id"] == "user"
|
assert result["step_id"] == "user"
|
||||||
assert result["errors"] == {}
|
assert result["errors"] == {}
|
||||||
flows = [
|
flows = list(hass.config_entries.flow._handler_progress_index[DOMAIN])
|
||||||
flow
|
|
||||||
for flow in hass.config_entries.flow.async_progress()
|
|
||||||
if flow["handler"] == DOMAIN
|
|
||||||
]
|
|
||||||
assert len(flows) == 1
|
assert len(flows) == 1
|
||||||
assert flows[0]["context"]["unique_id"] == OLD_FIRMWARE_LOCK_DISCOVERY_INFO.address
|
assert flows[0].unique_id == OLD_FIRMWARE_LOCK_DISCOVERY_INFO.address
|
||||||
assert flows[0]["context"]["local_name"] == OLD_FIRMWARE_LOCK_DISCOVERY_INFO.name
|
assert flows[0].local_name == OLD_FIRMWARE_LOCK_DISCOVERY_INFO.name
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.yalexs_ble.util.async_discovered_service_info",
|
"homeassistant.components.yalexs_ble.util.async_discovered_service_info",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user