Skip to content

Commit

Permalink
Update the ip/port in the homekit_controller config entry when it cha…
Browse files Browse the repository at this point in the history
…nges (#52554)
  • Loading branch information
bdraco authored Jul 5, 2021
1 parent 7d87efc commit 3191fef
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 6 deletions.
14 changes: 12 additions & 2 deletions homeassistant/components/homekit_controller/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,20 @@ async def async_step_zeroconf(self, discovery_info):
)
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
Expand All @@ -262,8 +273,7 @@ async def async_step_zeroconf(self, discovery_info):
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

Expand Down
57 changes: 53 additions & 4 deletions tests/components/homekit_controller/test_config_flow.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -11,6 +11,7 @@

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
Expand Down Expand Up @@ -383,17 +384,60 @@ 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)

# Set device as already paired
discovery_info["properties"]["sf"] = 0x00

# 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"
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(
Expand All @@ -403,6 +447,11 @@ async def test_discovery_already_configured(hass, controller):
)
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)
Expand Down

0 comments on commit 3191fef

Please sign in to comment.