1
mirror of https://github.com/home-assistant/core synced 2024-07-27 18:58:57 +02:00

Set unique id on homekit_controller config entries (#30035)

* Set unique id on config entries

* Changes from review
This commit is contained in:
Jc2k 2019-12-19 08:45:23 +00:00 committed by Paulus Schoutsen
parent 9e5de1a106
commit c3144eddbb
3 changed files with 55 additions and 36 deletions

View File

@ -9,8 +9,7 @@ from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.entity import Entity
# We need an import from .config_flow, without it .config_flow is never loaded.
from .config_flow import HomekitControllerFlowHandler # noqa: F401
from .config_flow import normalize_hkid
from .connection import HKDevice, get_accessory_information
from .const import CONTROLLER, DOMAIN, ENTITY_MAP, KNOWN_DEVICES
from .storage import EntityMapStorage
@ -181,6 +180,12 @@ async def async_setup_entry(hass, entry):
conn = HKDevice(hass, entry, entry.data)
hass.data[KNOWN_DEVICES][conn.unique_id] = conn
# For backwards compat
if entry.unique_id is None:
hass.config_entries.async_update_entry(
entry, unique_id=normalize_hkid(conn.unique_id)
)
if not await conn.async_setup():
del hass.data[KNOWN_DEVICES][conn.unique_id]
raise ConfigEntryNotReady

View File

@ -46,6 +46,11 @@ def load_old_pairings(hass):
return old_pairings
def normalize_hkid(hkid):
"""Normalize a hkid so that it is safe to compare with other normalized hkids."""
return hkid.lower()
@callback
def find_existing_host(hass, serial):
"""Return a set of the configured hosts."""
@ -77,6 +82,9 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow):
key = user_input["device"]
self.hkid = self.devices[key]["id"]
self.model = self.devices[key]["md"]
await self.async_set_unique_id(
normalize_hkid(self.hkid), raise_on_progress=False
)
return await self.async_step_pair()
all_hosts = await self.hass.async_add_executor_job(self.controller.discover, 5)
@ -120,18 +128,6 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow):
status_flags = int(properties["sf"])
paired = not status_flags & 0x01
_LOGGER.debug("Discovered device %s (%s - %s)", name, model, hkid)
# pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
self.context["hkid"] = hkid
self.context["title_placeholders"] = {"name": name}
# If multiple HomekitControllerFlowHandler end up getting created
# for the same accessory dont let duplicates hang around
active_flows = self._async_in_progress()
if any(hkid == flow["context"]["hkid"] for flow in active_flows):
return self.async_abort(reason="already_in_progress")
# The configuration number increases every time the characteristic map
# needs updating. Some devices use a slightly off-spec name so handle
# both cases.
@ -143,21 +139,27 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow):
)
config_num = None
if paired:
if hkid in self.hass.data.get(KNOWN_DEVICES, {}):
# The device is already paired and known to us
# According to spec we should monitor c# (config_num) for
# changes. If it changes, we check for new entities
conn = self.hass.data[KNOWN_DEVICES][hkid]
if conn.config_num != config_num:
_LOGGER.debug(
"HomeKit info %s: c# incremented, refreshing entities", hkid
)
self.hass.async_create_task(
conn.async_refresh_entity_map(config_num)
)
return self.async_abort(reason="already_configured")
# If the device is already paired and known to us we should monitor c#
# (config_num) for changes. If it changes, we check for new entities
if paired and hkid in self.hass.data.get(KNOWN_DEVICES, {}):
conn = self.hass.data[KNOWN_DEVICES][hkid]
if conn.config_num != config_num:
_LOGGER.debug(
"HomeKit info %s: c# incremented, refreshing entities", hkid
)
self.hass.async_create_task(conn.async_refresh_entity_map(config_num))
return self.async_abort(reason="already_configured")
_LOGGER.debug("Discovered device %s (%s - %s)", name, model, hkid)
await self.async_set_unique_id(normalize_hkid(hkid))
self._abort_if_unique_id_configured()
# pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
self.context["hkid"] = hkid
self.context["title_placeholders"] = {"name": name}
if paired:
old_pairings = await self.hass.async_add_executor_job(
load_old_pairings, self.hass
)

View File

@ -74,6 +74,7 @@ async def test_discovery_works(hass):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
# User initiates pairing - device enters pairing mode and displays code
@ -122,6 +123,7 @@ async def test_discovery_works_upper_case(hass):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
# User initiates pairing - device enters pairing mode and displays code
@ -169,6 +171,7 @@ async def test_discovery_works_missing_csharp(hass):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
# User initiates pairing - device enters pairing mode and displays code
@ -234,6 +237,7 @@ async def test_pair_already_paired_1(hass):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
@ -259,6 +263,7 @@ async def test_discovery_ignored_model(hass):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
@ -286,6 +291,7 @@ async def test_discovery_invalid_config_entry(hass):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
# Discovery of a HKID that is in a pairable state but for which there is
@ -315,10 +321,7 @@ async def test_discovery_already_configured(hass):
result = await flow.async_step_zeroconf(discovery_info)
assert result["type"] == "abort"
assert result["reason"] == "already_configured"
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
}
assert flow.context == {}
assert conn.async_config_num_changed.call_count == 0
@ -343,10 +346,7 @@ async def test_discovery_already_configured_config_change(hass):
result = await flow.async_step_zeroconf(discovery_info)
assert result["type"] == "abort"
assert result["reason"] == "already_configured"
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
}
assert flow.context == {}
assert conn.async_refresh_entity_map.call_args == mock.call(2)
@ -369,6 +369,7 @@ async def test_pair_unable_to_pair(hass):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
# User initiates pairing - device enters pairing mode and displays code
@ -402,6 +403,7 @@ async def test_pair_abort_errors_on_start(hass, exception, expected):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
# User initiates pairing - device refuses to enter pairing mode
@ -414,6 +416,7 @@ async def test_pair_abort_errors_on_start(hass, exception, expected):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
@ -436,6 +439,7 @@ async def test_pair_form_errors_on_start(hass, exception, expected):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
# User initiates pairing - device refuses to enter pairing mode
@ -448,6 +452,7 @@ async def test_pair_form_errors_on_start(hass, exception, expected):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
@ -470,6 +475,7 @@ async def test_pair_abort_errors_on_finish(hass, exception, expected):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
# User initiates pairing - device enters pairing mode and displays code
@ -486,6 +492,7 @@ async def test_pair_abort_errors_on_finish(hass, exception, expected):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
@ -508,6 +515,7 @@ async def test_pair_form_errors_on_finish(hass, exception, expected):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
# User initiates pairing - device enters pairing mode and displays code
@ -524,6 +532,7 @@ async def test_pair_form_errors_on_finish(hass, exception, expected):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
@ -712,6 +721,7 @@ async def test_parse_new_homekit_json(hass):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
@ -763,6 +773,7 @@ async def test_parse_old_homekit_json(hass):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}
@ -823,4 +834,5 @@ async def test_parse_overlapping_homekit_json(hass):
assert flow.context == {
"hkid": "00:00:00:00:00:00",
"title_placeholders": {"name": "TestDevice"},
"unique_id": "00:00:00:00:00:00",
}