diff --git a/homeassistant/components/advantage_air/__init__.py b/homeassistant/components/advantage_air/__init__.py index 4114f612fe95..7d2a5515f794 100644 --- a/homeassistant/components/advantage_air/__init__.py +++ b/homeassistant/components/advantage_air/__init__.py @@ -4,7 +4,7 @@ from advantage_air import advantage_air from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT, Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers import config_validation as cv +from homeassistant.helpers import config_validation as cv, device_registry as dr from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.typing import ConfigType @@ -50,6 +50,18 @@ async def async_setup_entry( entry.runtime_data = coordinator + # Register the system device so child devices can resolve it as their + # via_device parent regardless of platform setup order. + system = coordinator.data["system"] + dr.async_get(hass).async_get_or_create( + config_entry_id=entry.entry_id, + identifiers={(DOMAIN, system["rid"])}, + manufacturer="Advantage Air", + model=system["sysType"], + name=system["name"], + sw_version=system["myAppRev"], + ) + await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True diff --git a/homeassistant/components/advantage_air/entity.py b/homeassistant/components/advantage_air/entity.py index c0f4cd5512c2..975cc901871c 100644 --- a/homeassistant/components/advantage_air/entity.py +++ b/homeassistant/components/advantage_air/entity.py @@ -5,6 +5,7 @@ from typing import Any from advantage_air import ApiError from homeassistant.exceptions import HomeAssistantError +from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -49,7 +50,11 @@ class AdvantageAirAcEntity(AdvantageAirEntity): self._attr_unique_id += f"-{ac_key}" self._attr_device_info = DeviceInfo( - via_device=(DOMAIN, self.coordinator.data["system"]["rid"]), + via_device_id=dr.async_get_device_id_by_identifier( + self.coordinator.hass, + (DOMAIN, self.coordinator.data["system"]["rid"]), + config_entry_id=self.coordinator.config_entry.entry_id, + ), identifiers={(DOMAIN, self._attr_unique_id)}, manufacturer="Advantage Air", model=self.coordinator.data["system"]["sysType"], @@ -105,7 +110,11 @@ class AdvantageAirThingEntity(AdvantageAirEntity): self._attr_unique_id += f"-{self._id}" self._attr_device_info = DeviceInfo( - via_device=(DOMAIN, self.coordinator.data["system"]["rid"]), + via_device_id=dr.async_get_device_id_by_identifier( + self.coordinator.hass, + (DOMAIN, self.coordinator.data["system"]["rid"]), + config_entry_id=self.coordinator.config_entry.entry_id, + ), identifiers={(DOMAIN, self._attr_unique_id)}, manufacturer="Advantage Air", model="MyPlace", diff --git a/homeassistant/components/advantage_air/light.py b/homeassistant/components/advantage_air/light.py index d3c94da3fd1a..a76f30a33e9c 100644 --- a/homeassistant/components/advantage_air/light.py +++ b/homeassistant/components/advantage_air/light.py @@ -4,6 +4,7 @@ from typing import Any, override from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity from homeassistant.core import HomeAssistant +from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback @@ -55,7 +56,11 @@ class AdvantageAirLight(AdvantageAirEntity, LightEntity): self._attr_unique_id += f"-{self._id}" self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, self._attr_unique_id)}, - via_device=(DOMAIN, self.coordinator.data["system"]["rid"]), + via_device_id=dr.async_get_device_id_by_identifier( + self.coordinator.hass, + (DOMAIN, self.coordinator.data["system"]["rid"]), + config_entry_id=self.coordinator.config_entry.entry_id, + ), manufacturer="Advantage Air", model=light.get("moduleType"), name=light["name"], diff --git a/tests/components/advantage_air/test_init.py b/tests/components/advantage_air/test_init.py index e700485c75a1..ff5c8ebc506b 100644 --- a/tests/components/advantage_air/test_init.py +++ b/tests/components/advantage_air/test_init.py @@ -3,9 +3,12 @@ from unittest.mock import AsyncMock from advantage_air import ApiError +import pytest +from homeassistant.components.advantage_air.const import DOMAIN from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant +from homeassistant.helpers import device_registry as dr from . import add_mock_config, patch_get @@ -21,6 +24,36 @@ async def test_async_setup_entry(hass: HomeAssistant, mock_get: AsyncMock) -> No assert entry.state is ConfigEntryState.NOT_LOADED +@pytest.mark.usefixtures("mock_get") +@pytest.mark.parametrize( + "child_identifier", + [ + "uniqueid-ac1", # AC device + "uniqueid-100", # myLights light device + "uniqueid-203", # myThings device + ], +) +async def test_child_devices_via_device( + hass: HomeAssistant, + device_registry: dr.DeviceRegistry, + child_identifier: str, +) -> None: + """Test child devices link to the system device via via_device_id.""" + + entry = await add_mock_config(hass) + + parent = device_registry.async_get_device_by_identifier( + (DOMAIN, "uniqueid"), entry.entry_id + ) + assert parent is not None + + child = device_registry.async_get_device_by_identifier( + (DOMAIN, child_identifier), entry.entry_id + ) + assert child is not None + assert child.via_device_id == parent.id + + async def test_async_setup_entry_failure(hass: HomeAssistant) -> None: """Test a unsuccessful setup entry."""