1
0
mirror of https://github.com/home-assistant/core.git synced 2026-08-06 05:14:06 +01:00

Fix via_device race in melnor (#177733)

Co-authored-by: Markus Tuominen <3738613+Markus98@users.noreply.github.com>
This commit is contained in:
Erik Montnemery
2026-08-03 13:42:25 +02:00
committed by GitHub
parent de194a6cef
commit de32db8f4f
3 changed files with 47 additions and 1 deletions
@@ -7,7 +7,10 @@ from homeassistant.components.bluetooth.match import BluetoothCallbackMatcher
from homeassistant.const import CONF_ADDRESS, Platform
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.device_registry import CONNECTION_BLUETOOTH
from .const import DOMAIN
from .coordinator import MelnorConfigEntry, MelnorDataUpdateCoordinator
PLATFORMS: list[Platform] = [
@@ -54,6 +57,18 @@ async def async_setup_entry(hass: HomeAssistant, entry: MelnorConfigEntry) -> bo
await coordinator.async_config_entry_first_refresh()
entry.runtime_data = coordinator
# Register the parent device up front so zone entities can deterministically
# resolve its via_device_id, regardless of platform setup order.
dr.async_get(hass).async_get_or_create(
config_entry_id=entry.entry_id,
identifiers={(DOMAIN, device.mac)},
connections={(CONNECTION_BLUETOOTH, device.mac)},
manufacturer="Melnor",
model=device.model,
name=device.name,
)
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
+6 -1
View File
@@ -7,6 +7,7 @@ from melnor_bluetooth.device import Device, Valve
from homeassistant.components.number import EntityDescription
from homeassistant.core import callback
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.device_registry import CONNECTION_BLUETOOTH, DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
@@ -76,7 +77,11 @@ class MelnorZoneEntity(MelnorBluetoothEntity):
identifiers={(DOMAIN, f"{self._device.mac}-zone{self._valve.id}")},
manufacturer="Melnor",
name=f"Zone {valve.id + 1}",
via_device=(DOMAIN, self._device.mac),
via_device_id=dr.async_get_device_id_by_identifier(
coordinator.hass,
(DOMAIN, self._device.mac),
config_entry_id=coordinator.config_entry.entry_id,
),
)
+26
View File
@@ -35,3 +35,29 @@ async def test_device_registry(
identifiers={(DOMAIN, FAKE_ADDRESS_1)}
)
assert device_entry == snapshot
async def test_zone_device_via_device(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
) -> None:
"""Test that zone devices link to the parent device via via_device_id."""
entry = mock_config_entry(hass)
with (
patch_async_ble_device_from_address(),
patch_melnor_device(),
patch_async_register_callback(),
):
assert await hass.config_entries.async_setup(entry.entry_id)
parent_device = device_registry.async_get_device_by_identifier(
(DOMAIN, FAKE_ADDRESS_1), entry.entry_id
)
zone_device = device_registry.async_get_device_by_identifier(
(DOMAIN, f"{FAKE_ADDRESS_1}-zone0"), entry.entry_id
)
assert parent_device is not None
assert zone_device is not None
assert zone_device.via_device_id == parent_device.id