mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
Dismiss existing discoveries when a HomeKit device is paired (#62632)
This commit is contained in:
parent
79627526c7
commit
ef5e5c3f96
@ -9,7 +9,7 @@ import voluptuous as vol
|
|||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
from homeassistant.components import zeroconf
|
from homeassistant.components import zeroconf
|
||||||
from homeassistant.core import callback
|
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 (
|
from homeassistant.helpers.device_registry import (
|
||||||
CONNECTION_NETWORK_MAC,
|
CONNECTION_NETWORK_MAC,
|
||||||
async_get_registry as async_get_device_registry,
|
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.
|
# The hkid is a unique random number that looks like a pairing code.
|
||||||
# It changes if a device is factory reset.
|
# It changes if a device is factory reset.
|
||||||
hkid = properties[zeroconf.ATTR_PROPERTIES_ID]
|
hkid = properties[zeroconf.ATTR_PROPERTIES_ID]
|
||||||
|
normalized_hkid = normalize_hkid(hkid)
|
||||||
|
|
||||||
model = properties["md"]
|
model = properties["md"]
|
||||||
name = discovery_info.name.replace("._hap._tcp.local.", "")
|
name = discovery_info.name.replace("._hap._tcp.local.", "")
|
||||||
status_flags = int(properties["sf"])
|
status_flags = int(properties["sf"])
|
||||||
@ -240,7 +242,9 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
config_num = None
|
config_num = None
|
||||||
|
|
||||||
# Set unique-id and error out if it's already configured
|
# 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 = {
|
updated_ip_port = {
|
||||||
"AccessoryIP": discovery_info.host,
|
"AccessoryIP": discovery_info.host,
|
||||||
"AccessoryPort": discovery_info.port,
|
"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
|
# Set unique-id and error out if it's already configured
|
||||||
self._abort_if_unique_id_configured(updates=updated_ip_port)
|
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:
|
if paired:
|
||||||
# Device is paired but not to us - ignore it
|
# 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["type"] == "form"
|
||||||
assert result["step_id"] == "pair"
|
assert result["step_id"] == "pair"
|
||||||
assert get_flow_context(hass, result) == {
|
assert get_flow_context(hass, result) == {
|
||||||
"hkid": "00:00:00:00:00:00",
|
|
||||||
"source": config_entries.SOURCE_ZEROCONF,
|
"source": config_entries.SOURCE_ZEROCONF,
|
||||||
"title_placeholders": {"name": "TestDevice"},
|
"title_placeholders": {"name": "TestDevice"},
|
||||||
"unique_id": "00:00:00:00:00:00",
|
"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) == {
|
assert get_flow_context(hass, result) == {
|
||||||
"hkid": "00:00:00:00:00:00",
|
|
||||||
"title_placeholders": {"name": "TestDevice"},
|
"title_placeholders": {"name": "TestDevice"},
|
||||||
"unique_id": "00:00:00:00:00:00",
|
"unique_id": "00:00:00:00:00:00",
|
||||||
"source": config_entries.SOURCE_ZEROCONF,
|
"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 result["errors"]["pairing_code"] == expected
|
||||||
|
|
||||||
assert get_flow_context(hass, result) == {
|
assert get_flow_context(hass, result) == {
|
||||||
"hkid": "00:00:00:00:00:00",
|
|
||||||
"title_placeholders": {"name": "TestDevice"},
|
"title_placeholders": {"name": "TestDevice"},
|
||||||
"unique_id": "00:00:00:00:00:00",
|
"unique_id": "00:00:00:00:00:00",
|
||||||
"source": config_entries.SOURCE_ZEROCONF,
|
"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) == {
|
assert get_flow_context(hass, result) == {
|
||||||
"hkid": "00:00:00:00:00:00",
|
|
||||||
"title_placeholders": {"name": "TestDevice"},
|
"title_placeholders": {"name": "TestDevice"},
|
||||||
"unique_id": "00:00:00:00:00:00",
|
"unique_id": "00:00:00:00:00:00",
|
||||||
"source": config_entries.SOURCE_ZEROCONF,
|
"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 result["type"] == "form"
|
||||||
assert get_flow_context(hass, result) == {
|
assert get_flow_context(hass, result) == {
|
||||||
"hkid": "00:00:00:00:00:00",
|
|
||||||
"title_placeholders": {"name": "TestDevice"},
|
"title_placeholders": {"name": "TestDevice"},
|
||||||
"unique_id": "00:00:00:00:00:00",
|
"unique_id": "00:00:00:00:00:00",
|
||||||
"source": config_entries.SOURCE_ZEROCONF,
|
"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) == {
|
assert get_flow_context(hass, result) == {
|
||||||
"hkid": "00:00:00:00:00:00",
|
|
||||||
"title_placeholders": {"name": "TestDevice"},
|
"title_placeholders": {"name": "TestDevice"},
|
||||||
"unique_id": "00:00:00:00:00:00",
|
"unique_id": "00:00:00:00:00:00",
|
||||||
"source": config_entries.SOURCE_ZEROCONF,
|
"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 result["type"] == "form"
|
||||||
assert get_flow_context(hass, result) == {
|
assert get_flow_context(hass, result) == {
|
||||||
"hkid": "00:00:00:00:00:00",
|
|
||||||
"title_placeholders": {"name": "TestDevice"},
|
"title_placeholders": {"name": "TestDevice"},
|
||||||
"unique_id": "00:00:00:00:00:00",
|
"unique_id": "00:00:00:00:00:00",
|
||||||
"source": config_entries.SOURCE_ZEROCONF,
|
"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 result["errors"]["pairing_code"] == expected
|
||||||
|
|
||||||
assert get_flow_context(hass, result) == {
|
assert get_flow_context(hass, result) == {
|
||||||
"hkid": "00:00:00:00:00:00",
|
|
||||||
"title_placeholders": {"name": "TestDevice"},
|
"title_placeholders": {"name": "TestDevice"},
|
||||||
"unique_id": "00:00:00:00:00:00",
|
"unique_id": "00:00:00:00:00:00",
|
||||||
"source": config_entries.SOURCE_ZEROCONF,
|
"source": config_entries.SOURCE_ZEROCONF,
|
||||||
@ -820,7 +812,6 @@ async def test_unignore_works(hass, controller):
|
|||||||
assert result["type"] == "form"
|
assert result["type"] == "form"
|
||||||
assert result["step_id"] == "pair"
|
assert result["step_id"] == "pair"
|
||||||
assert get_flow_context(hass, result) == {
|
assert get_flow_context(hass, result) == {
|
||||||
"hkid": "00:00:00:00:00:00",
|
|
||||||
"title_placeholders": {"name": "TestDevice"},
|
"title_placeholders": {"name": "TestDevice"},
|
||||||
"unique_id": "00:00:00:00:00:00",
|
"unique_id": "00:00:00:00:00:00",
|
||||||
"source": config_entries.SOURCE_UNIGNORE,
|
"source": config_entries.SOURCE_UNIGNORE,
|
||||||
@ -852,3 +843,44 @@ async def test_unignore_ignores_missing_devices(hass, controller):
|
|||||||
|
|
||||||
assert result["type"] == "abort"
|
assert result["type"] == "abort"
|
||||||
assert result["reason"] == "no_devices"
|
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…
x
Reference in New Issue
Block a user