Update the ip/port in the homekit_controller config entry when it changes (#52554)

This commit is contained in:
J. Nick Koston 2021-07-05 15:16:49 -05:00 committed by GitHub
parent 7d87efc996
commit 3191fef8d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 6 deletions

View file

@ -236,9 +236,20 @@ 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))
updated_ip_port = {
"AccessoryIP": discovery_info["host"],
"AccessoryPort": discovery_info["port"],
}
# 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, {}):
if existing_entry:
self.hass.config_entries.async_update_entry(
existing_entry, data={**existing_entry.data, **updated_ip_port}
)
conn = self.hass.data[KNOWN_DEVICES][hkid]
# When we rediscover the device, let aiohomekit know
# that the device is available and we should not wait
@ -262,8 +273,7 @@ class HomekitControllerFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
await self.hass.config_entries.async_remove(existing.entry_id)
# Set unique-id and error out if it's already configured
await self.async_set_unique_id(normalize_hkid(hkid))
self._abort_if_unique_id_configured()
self._abort_if_unique_id_configured(updates=updated_ip_port)
self.context["hkid"] = hkid

View file

@ -1,7 +1,7 @@
"""Tests for homekit_controller config flow."""
from unittest import mock
import unittest.mock
from unittest.mock import patch
from unittest.mock import AsyncMock, patch
import aiohomekit
from aiohomekit.model import Accessories, Accessory
@ -11,6 +11,7 @@ import pytest
from homeassistant import config_entries
from homeassistant.components.homekit_controller import config_flow
from homeassistant.components.homekit_controller.const import KNOWN_DEVICES
from homeassistant.helpers import device_registry
from tests.common import MockConfigEntry, mock_device_registry
@ -383,11 +384,16 @@ async def test_discovery_invalid_config_entry(hass, controller):
async def test_discovery_already_configured(hass, controller):
"""Already configured."""
MockConfigEntry(
entry = MockConfigEntry(
domain="homekit_controller",
data={"AccessoryPairingID": "00:00:00:00:00:00"},
data={
"AccessoryIP": "4.4.4.4",
"AccessoryPort": 66,
"AccessoryPairingID": "00:00:00:00:00:00",
},
unique_id="00:00:00:00:00:00",
).add_to_hass(hass)
)
entry.add_to_hass(hass)
device = setup_mock_accessory(controller)
discovery_info = get_device_discovery_info(device)
@ -403,6 +409,49 @@ async def test_discovery_already_configured(hass, controller):
)
assert result["type"] == "abort"
assert result["reason"] == "already_configured"
assert entry.data["AccessoryIP"] == discovery_info["host"]
assert entry.data["AccessoryPort"] == discovery_info["port"]
async def test_discovery_already_configured_update_csharp(hass, controller):
"""Already configured and csharp changes."""
entry = MockConfigEntry(
domain="homekit_controller",
data={
"AccessoryIP": "4.4.4.4",
"AccessoryPort": 66,
"AccessoryPairingID": "AA:BB:CC:DD:EE:FF",
},
unique_id="aa:bb:cc:dd:ee:ff",
)
entry.add_to_hass(hass)
connection_mock = AsyncMock()
connection_mock.pairing.connect.reconnect_soon = AsyncMock()
connection_mock.async_refresh_entity_map = AsyncMock()
hass.data[KNOWN_DEVICES] = {"AA:BB:CC:DD:EE:FF": connection_mock}
device = setup_mock_accessory(controller)
discovery_info = get_device_discovery_info(device)
# Set device as already paired
discovery_info["properties"]["sf"] = 0x00
discovery_info["properties"]["c#"] = 99999
discovery_info["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"] == "abort"
assert result["reason"] == "already_configured"
await hass.async_block_till_done()
assert entry.data["AccessoryIP"] == discovery_info["host"]
assert entry.data["AccessoryPort"] == discovery_info["port"]
assert connection_mock.async_refresh_entity_map.await_count == 1
@pytest.mark.parametrize("exception,expected", PAIRING_START_ABORT_ERRORS)