From 181eca6c8200c20d99eb1ff977950b24cda65383 Mon Sep 17 00:00:00 2001 From: starkillerOG Date: Fri, 9 May 2025 14:47:38 +0200 Subject: [PATCH] Reolink clean device registry mac (#144554) --- homeassistant/components/reolink/__init__.py | 10 +++- tests/components/reolink/test_init.py | 52 +++++++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/reolink/__init__.py b/homeassistant/components/reolink/__init__.py index f7d13c1d90f..433af396d63 100644 --- a/homeassistant/components/reolink/__init__.py +++ b/homeassistant/components/reolink/__init__.py @@ -23,7 +23,7 @@ from homeassistant.helpers import ( device_registry as dr, entity_registry as er, ) -from homeassistant.helpers.device_registry import format_mac +from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, format_mac from homeassistant.helpers.event import async_call_later from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -380,6 +380,14 @@ def migrate_entity_ids( if ch is None or is_chime: continue # Do not consider the NVR itself or chimes + # Check for wrongfully added MAC of the NVR/Hub to the camera + # Can be removed in HA 2025.12 + host_connnection = (CONNECTION_NETWORK_MAC, host.api.mac_address) + if host_connnection in device.connections: + new_connections = device.connections.copy() + new_connections.remove(host_connnection) + device_reg.async_update_device(device.id, new_connections=new_connections) + ch_device_ids[device.id] = ch if host.api.supported(ch, "UID") and device_uid[1] != host.api.camera_uid(ch): if host.api.supported(None, "UID"): diff --git a/tests/components/reolink/test_init.py b/tests/components/reolink/test_init.py index 5915bd06608..6b57c1c253f 100644 --- a/tests/components/reolink/test_init.py +++ b/tests/components/reolink/test_init.py @@ -39,7 +39,7 @@ from homeassistant.helpers import ( entity_registry as er, issue_registry as ir, ) -from homeassistant.helpers.device_registry import format_mac +from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, format_mac from homeassistant.setup import async_setup_component from .conftest import ( @@ -51,6 +51,7 @@ from .conftest import ( TEST_HOST, TEST_HOST_MODEL, TEST_MAC, + TEST_MAC_CAM, TEST_NVR_NAME, TEST_PORT, TEST_PRIVACY, @@ -614,6 +615,55 @@ async def test_migrate_with_already_existing_entity( assert entity_registry.async_get_entity_id(domain, DOMAIN, new_id) +async def test_cleanup_mac_connection( + hass: HomeAssistant, + config_entry: MockConfigEntry, + reolink_connect: MagicMock, + entity_registry: er.EntityRegistry, + device_registry: dr.DeviceRegistry, +) -> None: + """Test cleanup of the MAC of a IPC which was set to the MAC of the host.""" + reolink_connect.channels = [0] + reolink_connect.baichuan.mac_address.return_value = None + entity_id = f"{TEST_UID}_{TEST_UID_CAM}_record_audio" + dev_id = f"{TEST_UID}_{TEST_UID_CAM}" + domain = Platform.SWITCH + + dev_entry = device_registry.async_get_or_create( + identifiers={(DOMAIN, dev_id)}, + connections={(CONNECTION_NETWORK_MAC, TEST_MAC)}, + config_entry_id=config_entry.entry_id, + disabled_by=None, + ) + + entity_registry.async_get_or_create( + domain=domain, + platform=DOMAIN, + unique_id=entity_id, + config_entry=config_entry, + suggested_object_id=entity_id, + disabled_by=None, + device_id=dev_entry.id, + ) + + assert entity_registry.async_get_entity_id(domain, DOMAIN, entity_id) + device = device_registry.async_get_device(identifiers={(DOMAIN, dev_id)}) + assert device + assert device.connections == {(CONNECTION_NETWORK_MAC, TEST_MAC)} + + # setup CH 0 and host entities/device + with patch("homeassistant.components.reolink.PLATFORMS", [domain]): + assert await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + assert entity_registry.async_get_entity_id(domain, DOMAIN, entity_id) + device = device_registry.async_get_device(identifiers={(DOMAIN, dev_id)}) + assert device + assert device.connections == set() + + reolink_connect.baichuan.mac_address.return_value = TEST_MAC_CAM + + async def test_no_repair_issue( hass: HomeAssistant, config_entry: MockConfigEntry, issue_registry: ir.IssueRegistry ) -> None: