mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +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
|
||||
import logging
|
||||
from typing import Any
|
||||
from typing import Any, Self
|
||||
|
||||
from bleak_retry_connector import BleakError, BLEDevice
|
||||
import voluptuous as vol
|
||||
@ -68,6 +68,11 @@ class YalexsConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
|
||||
VERSION = 1
|
||||
|
||||
_address: str | None = None
|
||||
_local_name_is_unique = False
|
||||
active = False
|
||||
local_name: str | None = None
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Initialize the config flow."""
|
||||
self._discovery_info: BluetoothServiceInfoBleak | None = None
|
||||
@ -81,7 +86,7 @@ class YalexsConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
"""Handle the bluetooth discovery step."""
|
||||
await self.async_set_unique_id(discovery_info.address)
|
||||
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.context["title_placeholders"] = {
|
||||
"name": human_readable_name(
|
||||
@ -103,8 +108,8 @@ class YalexsConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
)
|
||||
|
||||
address = lock_cfg.address
|
||||
local_name = lock_cfg.local_name
|
||||
hass = self.hass
|
||||
self.local_name = lock_cfg.local_name
|
||||
self._local_name_is_unique = local_name_is_unique(self.local_name)
|
||||
|
||||
# We do not want to raise on progress as integration_discovery takes
|
||||
# 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)
|
||||
for entry in self._async_current_entries():
|
||||
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
|
||||
):
|
||||
return self.async_update_reload_and_abort(
|
||||
@ -124,27 +129,14 @@ class YalexsConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
)
|
||||
|
||||
self._discovery_info = async_find_existing_service_info(
|
||||
hass, local_name, address
|
||||
self.hass, self.local_name, address
|
||||
)
|
||||
if not self._discovery_info:
|
||||
return self.async_abort(reason="no_devices_found")
|
||||
|
||||
# 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.
|
||||
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")
|
||||
hass.config_entries.flow.async_abort(progress["flow_id"])
|
||||
self._address = address
|
||||
if self.hass.config_entries.flow.async_has_matching_flow(self):
|
||||
raise AbortFlow("already_in_progress")
|
||||
|
||||
self._lock_cfg = lock_cfg
|
||||
self.context["title_placeholders"] = {
|
||||
@ -154,6 +146,24 @@ class YalexsConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
}
|
||||
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(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
@ -234,7 +244,7 @@ class YalexsConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
errors: dict[str, str] = {}
|
||||
|
||||
if user_input is not None:
|
||||
self.context["active"] = True
|
||||
self.active = True
|
||||
address = user_input[CONF_ADDRESS]
|
||||
discovery_info = self._discovered_devices[address]
|
||||
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["step_id"] == "user"
|
||||
assert result["errors"] == {}
|
||||
flows = [
|
||||
flow
|
||||
for flow in hass.config_entries.flow.async_progress()
|
||||
if flow["handler"] == DOMAIN
|
||||
]
|
||||
flows = list(hass.config_entries.flow._handler_progress_index[DOMAIN])
|
||||
assert len(flows) == 1
|
||||
assert flows[0]["context"]["unique_id"] == YALE_ACCESS_LOCK_DISCOVERY_INFO.address
|
||||
assert flows[0]["context"]["local_name"] == YALE_ACCESS_LOCK_DISCOVERY_INFO.name
|
||||
assert flows[0].unique_id == YALE_ACCESS_LOCK_DISCOVERY_INFO.address
|
||||
assert flows[0].local_name == YALE_ACCESS_LOCK_DISCOVERY_INFO.name
|
||||
|
||||
with patch(
|
||||
"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["step_id"] == "user"
|
||||
assert result["errors"] == {}
|
||||
flows = [
|
||||
flow
|
||||
for flow in hass.config_entries.flow.async_progress()
|
||||
if flow["handler"] == DOMAIN
|
||||
]
|
||||
flows = list(hass.config_entries.flow._handler_progress_index[DOMAIN])
|
||||
assert len(flows) == 1
|
||||
assert flows[0]["context"]["unique_id"] == LOCK_DISCOVERY_INFO_UUID_ADDRESS.address
|
||||
assert flows[0]["context"]["local_name"] == LOCK_DISCOVERY_INFO_UUID_ADDRESS.name
|
||||
assert flows[0].unique_id == LOCK_DISCOVERY_INFO_UUID_ADDRESS.address
|
||||
assert flows[0].local_name == LOCK_DISCOVERY_INFO_UUID_ADDRESS.name
|
||||
|
||||
with patch(
|
||||
"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["step_id"] == "user"
|
||||
assert result["errors"] == {}
|
||||
flows = [
|
||||
flow
|
||||
for flow in hass.config_entries.flow.async_progress()
|
||||
if flow["handler"] == DOMAIN
|
||||
]
|
||||
flows = list(hass.config_entries.flow._handler_progress_index[DOMAIN])
|
||||
assert len(flows) == 1
|
||||
assert flows[0]["context"]["unique_id"] == OLD_FIRMWARE_LOCK_DISCOVERY_INFO.address
|
||||
assert flows[0]["context"]["local_name"] == OLD_FIRMWARE_LOCK_DISCOVERY_INFO.name
|
||||
assert flows[0].unique_id == OLD_FIRMWARE_LOCK_DISCOVERY_INFO.address
|
||||
assert flows[0].local_name == OLD_FIRMWARE_LOCK_DISCOVERY_INFO.name
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.yalexs_ble.util.async_discovered_service_info",
|
||||
|
Loading…
x
Reference in New Issue
Block a user