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 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# # 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 # (config_num) for changes. If it changes, we check for new entities
if paired and hkid in self.hass.data.get(KNOWN_DEVICES, {}): 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] conn = self.hass.data[KNOWN_DEVICES][hkid]
# When we rediscover the device, let aiohomekit know # When we rediscover the device, let aiohomekit know
# that the device is available and we should not wait # 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) await self.hass.config_entries.async_remove(existing.entry_id)
# Set unique-id and error out if it's already configured # 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(updates=updated_ip_port)
self._abort_if_unique_id_configured()
self.context["hkid"] = hkid self.context["hkid"] = hkid

View file

@ -1,7 +1,7 @@
"""Tests for homekit_controller config flow.""" """Tests for homekit_controller config flow."""
from unittest import mock from unittest import mock
import unittest.mock import unittest.mock
from unittest.mock import patch from unittest.mock import AsyncMock, patch
import aiohomekit import aiohomekit
from aiohomekit.model import Accessories, Accessory from aiohomekit.model import Accessories, Accessory
@ -11,6 +11,7 @@ import pytest
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.components.homekit_controller import config_flow from homeassistant.components.homekit_controller import config_flow
from homeassistant.components.homekit_controller.const import KNOWN_DEVICES
from homeassistant.helpers import device_registry from homeassistant.helpers import device_registry
from tests.common import MockConfigEntry, mock_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): async def test_discovery_already_configured(hass, controller):
"""Already configured.""" """Already configured."""
MockConfigEntry( entry = MockConfigEntry(
domain="homekit_controller", 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", unique_id="00:00:00:00:00:00",
).add_to_hass(hass) )
entry.add_to_hass(hass)
device = setup_mock_accessory(controller) device = setup_mock_accessory(controller)
discovery_info = get_device_discovery_info(device) 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["type"] == "abort"
assert result["reason"] == "already_configured" 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) @pytest.mark.parametrize("exception,expected", PAIRING_START_ABORT_ERRORS)