Fix via_device race in sense (#177757)

This commit is contained in:
Erik Montnemery
2026-08-03 16:53:19 +02:00
committed by GitHub
parent ebe25237a1
commit 96f3fe3122
3 changed files with 49 additions and 1 deletions
@@ -15,10 +15,12 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_TIMEOUT, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import (
ACTIVE_UPDATE_RATE,
DOMAIN,
SENSE_CONNECT_EXCEPTIONS,
SENSE_TIMEOUT_EXCEPTIONS,
SENSE_WEBSOCKET_EXCEPTIONS,
@@ -117,6 +119,19 @@ async def async_setup_entry(hass: HomeAssistant, entry: SenseConfigEntry) -> boo
rt=realtime_coordinator,
)
# Register the monitor device up front so child devices can reference it via
# via_device_id; child entities are added by concurrently-loaded platforms
# before any of them registers the monitor device.
sense_monitor_id = gateway.sense_monitor_id
dr.async_get(hass).async_get_or_create(
config_entry_id=entry.entry_id,
name=f"Sense {sense_monitor_id}",
identifiers={(DOMAIN, sense_monitor_id)},
model="Sense",
manufacturer="Sense Labs, Inc.",
configuration_url="https://home.sense.com",
)
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
return True
+6 -1
View File
@@ -3,6 +3,7 @@
from sense_energy import ASyncSenseable
from sense_energy.sense_api import SenseDevice
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
@@ -67,5 +68,9 @@ class SenseDeviceEntity(CoordinatorEntity[SenseCoordinator]):
model="Sense",
manufacturer="Sense Labs, Inc.",
configuration_url="https://home.sense.com",
via_device=(DOMAIN, sense_monitor_id),
via_device_id=dr.async_get_device_id_by_identifier(
coordinator.hass,
(DOMAIN, sense_monitor_id),
config_entry_id=coordinator.config_entry.entry_id,
),
)
+28
View File
@@ -12,12 +12,40 @@ from sense_energy import (
SenseWebsocketException,
)
from homeassistant.components.sense.const import DOMAIN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from .const import DEVICE_1_ID, MONITOR_ID
from tests.common import MockConfigEntry
@pytest.mark.usefixtures("mock_sense")
async def test_device_via_device_link(
hass: HomeAssistant,
config_entry: MockConfigEntry,
device_registry: dr.DeviceRegistry,
) -> None:
"""Test child devices link to the monitor device via via_device_id."""
config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
monitor_device = device_registry.async_get_device_by_identifier(
(DOMAIN, MONITOR_ID), config_entry.entry_id
)
assert monitor_device is not None
child_device = device_registry.async_get_device_by_identifier(
(DOMAIN, f"{MONITOR_ID}:{DEVICE_1_ID}"), config_entry.entry_id
)
assert child_device is not None
assert child_device.via_device_id == monitor_device.id
@pytest.mark.parametrize(
"exception",
[