From 56e07efe319459a67d2f5c30866f9a28bf75c6e4 Mon Sep 17 00:00:00 2001
From: "J. Nick Koston" <nick@koston.org>
Date: Tue, 4 Feb 2025 13:48:59 -0600
Subject: [PATCH] Copy area from remote parent device when creating Bluetooth
 devices (#137340)

---
 homeassistant/components/bluetooth/__init__.py | 13 ++++++-------
 tests/components/bluetooth/test_config_flow.py |  9 +++++++--
 2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/homeassistant/components/bluetooth/__init__.py b/homeassistant/components/bluetooth/__init__.py
index c423e9e747b..c46ef22803e 100644
--- a/homeassistant/components/bluetooth/__init__.py
+++ b/homeassistant/components/bluetooth/__init__.py
@@ -5,7 +5,7 @@ from __future__ import annotations
 import datetime
 import logging
 import platform
-from typing import TYPE_CHECKING
+from typing import TYPE_CHECKING, Any
 
 from bleak_retry_connector import BleakSlotManager
 from bluetooth_adapters import (
@@ -302,7 +302,6 @@ async def async_update_device(
     entry: ConfigEntry,
     adapter: str,
     details: AdapterDetails,
-    via_device_domain: str | None = None,
     via_device_id: str | None = None,
 ) -> None:
     """Update device registry entry.
@@ -322,10 +321,11 @@ async def async_update_device(
         sw_version=details.get(ADAPTER_SW_VERSION),
         hw_version=details.get(ADAPTER_HW_VERSION),
     )
-    if via_device_id:
-        device_registry.async_update_device(
-            device_entry.id, via_device_id=via_device_id
-        )
+    if via_device_id and (via_device_entry := device_registry.async_get(via_device_id)):
+        kwargs: dict[str, Any] = {"via_device_id": via_device_id}
+        if not device_entry.area_id and via_device_entry.area_id:
+            kwargs["area_id"] = via_device_entry.area_id
+        device_registry.async_update_device(device_entry.id, **kwargs)
 
 
 async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
@@ -360,7 +360,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
             entry,
             source_entry.title,
             details,
-            source_domain,
             entry.data.get(CONF_SOURCE_DEVICE_ID),
         )
         return True
diff --git a/tests/components/bluetooth/test_config_flow.py b/tests/components/bluetooth/test_config_flow.py
index b8f90b3a4aa..35c1ca1eafe 100644
--- a/tests/components/bluetooth/test_config_flow.py
+++ b/tests/components/bluetooth/test_config_flow.py
@@ -20,7 +20,7 @@ from homeassistant.components.bluetooth.const import (
 )
 from homeassistant.core import HomeAssistant
 from homeassistant.data_entry_flow import FlowResultType
-from homeassistant.helpers import device_registry as dr
+from homeassistant.helpers import area_registry as ar, device_registry as dr
 from homeassistant.setup import async_setup_component
 
 from . import FakeRemoteScanner, MockBleakClient, _get_manager
@@ -537,7 +537,9 @@ async def test_async_step_user_linux_adapter_is_ignored(hass: HomeAssistant) ->
 
 @pytest.mark.usefixtures("enable_bluetooth")
 async def test_async_step_integration_discovery_remote_adapter(
-    hass: HomeAssistant, device_registry: dr.DeviceRegistry
+    hass: HomeAssistant,
+    device_registry: dr.DeviceRegistry,
+    area_registry: ar.AreaRegistry,
 ) -> None:
     """Test remote adapter configuration via integration discovery."""
     entry = MockConfigEntry(domain="test")
@@ -547,10 +549,12 @@ async def test_async_step_integration_discovery_remote_adapter(
     )
     scanner = FakeRemoteScanner("esp32", "esp32", connector, True)
     manager = _get_manager()
+    area_entry = area_registry.async_get_or_create("test")
     cancel_scanner = manager.async_register_scanner(scanner)
     device_entry = device_registry.async_get_or_create(
         config_entry_id=entry.entry_id,
         identifiers={("test", "BB:BB:BB:BB:BB:BB")},
+        suggested_area=area_entry.id,
     )
 
     result = await hass.config_entries.flow.async_init(
@@ -585,6 +589,7 @@ async def test_async_step_integration_discovery_remote_adapter(
     )
     assert ble_device_entry is not None
     assert ble_device_entry.via_device_id == device_entry.id
+    assert ble_device_entry.area_id == area_entry.id
 
     await hass.config_entries.async_unload(new_entry.entry_id)
     await hass.config_entries.async_unload(entry.entry_id)
-- 
GitLab