Dismiss existing discoveries when a HomeKit device is paired (#62632)
This commit is contained in:
parent
79627526c7
commit
ef5e5c3f96
2 changed files with 56 additions and 12 deletions
|
@ -9,7 +9,7 @@ import voluptuous as vol
|
|||
from homeassistant import config_entries
|
||||
from homeassistant.components import zeroconf
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
from homeassistant.data_entry_flow import AbortFlow, FlowResult
|
||||
from homeassistant.helpers.device_registry import (
|
||||
CONNECTION_NETWORK_MAC,
|
||||
async_get_registry as async_get_device_registry,
|
||||
|
@ -223,6 +223,8 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
# The hkid is a unique random number that looks like a pairing code.
|
||||
# It changes if a device is factory reset.
|
||||
hkid = properties[zeroconf.ATTR_PROPERTIES_ID]
|
||||
normalized_hkid = normalize_hkid(hkid)
|
||||
|
||||
model = properties["md"]
|
||||
name = discovery_info.name.replace("._hap._tcp.local.", "")
|
||||
status_flags = int(properties["sf"])
|
||||
|
@ -240,7 +242,9 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
config_num = None
|
||||
|
||||
# Set unique-id and error out if it's already configured
|
||||
existing_entry = await self.async_set_unique_id(normalize_hkid(hkid))
|
||||
existing_entry = await self.async_set_unique_id(
|
||||
normalized_hkid, raise_on_progress=False
|
||||
)
|
||||
updated_ip_port = {
|
||||
"AccessoryIP": discovery_info.host,
|
||||
"AccessoryPort": discovery_info.port,
|
||||
|
@ -303,7 +307,15 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
# Set unique-id and error out if it's already configured
|
||||
self._abort_if_unique_id_configured(updates=updated_ip_port)
|
||||
|
||||
self.context["hkid"] = hkid
|
||||
for progress in self._async_in_progress(include_uninitialized=True):
|
||||
if progress["context"].get("unique_id") == normalized_hkid:
|
||||
if paired:
|
||||
# If the device gets paired, we want to dismiss
|
||||
# an existing discovery since we can no longer
|
||||
# pair with it
|
||||
self.hass.config_entries.flow.async_abort(progress["flow_id"])
|
||||
else:
|
||||
raise AbortFlow("already_in_progress")
|
||||
|
||||
if paired:
|
||||
# Device is paired but not to us - ignore it
|
||||
|
|
|
@ -206,7 +206,6 @@ async def test_discovery_works(hass, controller, upper_case_props, missing_cshar
|
|||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "pair"
|
||||
assert get_flow_context(hass, result) == {
|
||||
"hkid": "00:00:00:00:00:00",
|
||||
"source": config_entries.SOURCE_ZEROCONF,
|
||||
"title_placeholders": {"name": "TestDevice"},
|
||||
"unique_id": "00:00:00:00:00:00",
|
||||
|
@ -577,7 +576,6 @@ async def test_pair_form_errors_on_start(hass, controller, exception, expected):
|
|||
)
|
||||
|
||||
assert get_flow_context(hass, result) == {
|
||||
"hkid": "00:00:00:00:00:00",
|
||||
"title_placeholders": {"name": "TestDevice"},
|
||||
"unique_id": "00:00:00:00:00:00",
|
||||
"source": config_entries.SOURCE_ZEROCONF,
|
||||
|
@ -593,7 +591,6 @@ async def test_pair_form_errors_on_start(hass, controller, exception, expected):
|
|||
assert result["errors"]["pairing_code"] == expected
|
||||
|
||||
assert get_flow_context(hass, result) == {
|
||||
"hkid": "00:00:00:00:00:00",
|
||||
"title_placeholders": {"name": "TestDevice"},
|
||||
"unique_id": "00:00:00:00:00:00",
|
||||
"source": config_entries.SOURCE_ZEROCONF,
|
||||
|
@ -627,7 +624,6 @@ async def test_pair_abort_errors_on_finish(hass, controller, exception, expected
|
|||
)
|
||||
|
||||
assert get_flow_context(hass, result) == {
|
||||
"hkid": "00:00:00:00:00:00",
|
||||
"title_placeholders": {"name": "TestDevice"},
|
||||
"unique_id": "00:00:00:00:00:00",
|
||||
"source": config_entries.SOURCE_ZEROCONF,
|
||||
|
@ -641,7 +637,6 @@ async def test_pair_abort_errors_on_finish(hass, controller, exception, expected
|
|||
|
||||
assert result["type"] == "form"
|
||||
assert get_flow_context(hass, result) == {
|
||||
"hkid": "00:00:00:00:00:00",
|
||||
"title_placeholders": {"name": "TestDevice"},
|
||||
"unique_id": "00:00:00:00:00:00",
|
||||
"source": config_entries.SOURCE_ZEROCONF,
|
||||
|
@ -669,7 +664,6 @@ async def test_pair_form_errors_on_finish(hass, controller, exception, expected)
|
|||
)
|
||||
|
||||
assert get_flow_context(hass, result) == {
|
||||
"hkid": "00:00:00:00:00:00",
|
||||
"title_placeholders": {"name": "TestDevice"},
|
||||
"unique_id": "00:00:00:00:00:00",
|
||||
"source": config_entries.SOURCE_ZEROCONF,
|
||||
|
@ -683,7 +677,6 @@ async def test_pair_form_errors_on_finish(hass, controller, exception, expected)
|
|||
|
||||
assert result["type"] == "form"
|
||||
assert get_flow_context(hass, result) == {
|
||||
"hkid": "00:00:00:00:00:00",
|
||||
"title_placeholders": {"name": "TestDevice"},
|
||||
"unique_id": "00:00:00:00:00:00",
|
||||
"source": config_entries.SOURCE_ZEROCONF,
|
||||
|
@ -697,7 +690,6 @@ async def test_pair_form_errors_on_finish(hass, controller, exception, expected)
|
|||
assert result["errors"]["pairing_code"] == expected
|
||||
|
||||
assert get_flow_context(hass, result) == {
|
||||
"hkid": "00:00:00:00:00:00",
|
||||
"title_placeholders": {"name": "TestDevice"},
|
||||
"unique_id": "00:00:00:00:00:00",
|
||||
"source": config_entries.SOURCE_ZEROCONF,
|
||||
|
@ -820,7 +812,6 @@ async def test_unignore_works(hass, controller):
|
|||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "pair"
|
||||
assert get_flow_context(hass, result) == {
|
||||
"hkid": "00:00:00:00:00:00",
|
||||
"title_placeholders": {"name": "TestDevice"},
|
||||
"unique_id": "00:00:00:00:00:00",
|
||||
"source": config_entries.SOURCE_UNIGNORE,
|
||||
|
@ -852,3 +843,44 @@ async def test_unignore_ignores_missing_devices(hass, controller):
|
|||
|
||||
assert result["type"] == "abort"
|
||||
assert result["reason"] == "no_devices"
|
||||
|
||||
|
||||
async def test_discovery_dismiss_existing_flow_on_paired(hass, controller):
|
||||
"""Test that existing flows get dismissed once paired to something else."""
|
||||
device = setup_mock_accessory(controller)
|
||||
discovery_info = get_device_discovery_info(device)
|
||||
|
||||
# Set device as already not paired
|
||||
discovery_info.properties["sf"] = 0x01
|
||||
discovery_info.properties["c#"] = 99999
|
||||
discovery_info.properties[zeroconf.ATTR_PROPERTIES_ID] = "AA:BB:CC:DD:EE:FF"
|
||||
|
||||
# Device is discovered
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
"homekit_controller",
|
||||
context={"source": config_entries.SOURCE_ZEROCONF},
|
||||
data=discovery_info,
|
||||
)
|
||||
assert result["type"] == "form"
|
||||
assert result["step_id"] == "pair"
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
len(hass.config_entries.flow.async_progress_by_handler("homekit_controller"))
|
||||
== 1
|
||||
)
|
||||
|
||||
# Set device as already paired
|
||||
discovery_info.properties["sf"] = 0x00
|
||||
# Device is discovered again after pairing to someone else
|
||||
result2 = await hass.config_entries.flow.async_init(
|
||||
"homekit_controller",
|
||||
context={"source": config_entries.SOURCE_ZEROCONF},
|
||||
data=discovery_info,
|
||||
)
|
||||
assert result2["type"] == "abort"
|
||||
assert result2["reason"] == "already_paired"
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
len(hass.config_entries.flow.async_progress_by_handler("homekit_controller"))
|
||||
== 0
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue