diff --git a/homeassistant/components/nexia/__init__.py b/homeassistant/components/nexia/__init__.py index 8d0d509f8a2b..ace24d65d8bc 100644 --- a/homeassistant/components/nexia/__init__.py +++ b/homeassistant/components/nexia/__init__.py @@ -61,6 +61,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: NexiaConfigEntry) -> boo coordinator = NexiaDataUpdateCoordinator(hass, entry, nexia_home) await coordinator.async_config_entry_first_refresh() entry.runtime_data = coordinator + + # Register thermostat devices before forwarding platforms so zone sub-devices + # can resolve their via_device_id regardless of platform setup order. + device_registry = dr.async_get(hass) + for thermostat_id in nexia_home.get_thermostat_ids(): + device_registry.async_get_or_create( + config_entry_id=entry.entry_id, + identifiers={(DOMAIN, thermostat_id)}, # type: ignore[arg-type] # until fix issue #139773 + ) + await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True diff --git a/homeassistant/components/nexia/entity.py b/homeassistant/components/nexia/entity.py index 04af39d6f84e..068419f68b52 100644 --- a/homeassistant/components/nexia/entity.py +++ b/homeassistant/components/nexia/entity.py @@ -5,12 +5,8 @@ from typing import TYPE_CHECKING, override from nexia.thermostat import NexiaThermostat from nexia.zone import NexiaThermostatZone -from homeassistant.const import ( - ATTR_IDENTIFIERS, - ATTR_NAME, - ATTR_SUGGESTED_AREA, - ATTR_VIA_DEVICE, -) +from homeassistant.const import ATTR_IDENTIFIERS, ATTR_NAME, ATTR_SUGGESTED_AREA +from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.dispatcher import ( async_dispatcher_connect, @@ -113,7 +109,11 @@ class NexiaThermostatZoneEntity(NexiaThermostatEntity): ATTR_IDENTIFIERS: {(DOMAIN, zone.zone_id)}, # type: ignore[arg-type] # until fix issue #139773 ATTR_NAME: zone_name, ATTR_SUGGESTED_AREA: zone_name, - ATTR_VIA_DEVICE: (DOMAIN, zone.thermostat.thermostat_id), # type: ignore[typeddict-item] # until fix issue #139773 + "via_device_id": dr.async_get_device_id_by_identifier( + self.coordinator.hass, + (DOMAIN, zone.thermostat.thermostat_id), # type: ignore[arg-type] # until fix issue #139773 + config_entry_id=self.coordinator.config_entry.entry_id, + ), } self._zone_signal = f"{SIGNAL_ZONE_UPDATE}-{zone.zone_id}" diff --git a/tests/components/nexia/test_init.py b/tests/components/nexia/test_init.py index 4546cd71e6a6..ef8734075c59 100644 --- a/tests/components/nexia/test_init.py +++ b/tests/components/nexia/test_init.py @@ -76,3 +76,25 @@ async def test_migrate_entry_minor_version_1_2(hass: HomeAssistant) -> None: assert entry.version == 1 assert entry.minor_version == 2 assert entry.unique_id == "123456" + + +async def test_device_via_device_links( + hass: HomeAssistant, + patch_nexia_home: NexiaHome, + device_registry: dr.DeviceRegistry, +) -> None: + """Test a zone device links to its thermostat via via_device_id.""" + config_entry = await setup_integration(hass, patch_nexia_home) + + thermostat_device = device_registry.async_get_device_by_identifier( + (DOMAIN, 2000000), # type: ignore[arg-type] # until fix issue #139773 + config_entry.entry_id, + ) + assert thermostat_device is not None + + zone_device = device_registry.async_get_device_by_identifier( + (DOMAIN, 100), # type: ignore[arg-type] # until fix issue #139773 + config_entry.entry_id, + ) + assert zone_device is not None + assert zone_device.via_device_id == thermostat_device.id