Fix via_device race in advantage_air (#177705)

This commit is contained in:
Erik Montnemery
2026-08-03 10:02:03 +02:00
committed by Bram Kragten
parent eb56f79fca
commit da9ffd93b8
4 changed files with 63 additions and 4 deletions
@@ -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
@@ -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",
@@ -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"],
@@ -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."""