From 4bb6e02422eb0dca0251dd88c042a28db4b1e2ce Mon Sep 17 00:00:00 2001 From: Vibe Nuage Agent Date: Mon, 12 Oct 2026 13:38:44 +0000 Subject: [PATCH 1/3] fix: replace removed DeviceEntry.config_entry_id with compatible helper Co-authored-by: moehrem --- custom_components/diveracontrol/__init__.py | 9 +++-- .../diveracontrol/device_action.py | 4 +- custom_components/diveracontrol/utils.py | 40 +++++++++++++++---- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/custom_components/diveracontrol/__init__.py b/custom_components/diveracontrol/__init__.py index e98e0b9..7cc5dad 100644 --- a/custom_components/diveracontrol/__init__.py +++ b/custom_components/diveracontrol/__init__.py @@ -43,7 +43,10 @@ from .coordinator import DiveraCoordinator from .divera_api import DiveraAPIClient from .service import async_register_services -from .utils import get_cluster_coordinators_ucrs_from_config_hass +from .utils import ( + get_cluster_coordinators_ucrs_from_config_hass, + get_device_config_entry_ids, +) PLATFORMS: list[Platform] = [ Platform.CALENDAR, @@ -504,7 +507,7 @@ def _remove_old_entity_entries( and identifier[1] in config_entry.data.get(D_RELATIONS_KEY, {}) for identifier in d.identifiers ) - or not d.config_entry_id # Orphaned devices + or not get_device_config_entry_ids(d) # Orphaned devices ] # 3. Zusammenführen und Duplikate vermeiden @@ -521,7 +524,7 @@ def _remove_old_entity_entries( "Migration: removing old device %s (name=%s, config_entry_id=%s)", device.id, device.name_by_user or device.name, - device.config_entry_id, + get_device_config_entry_ids(device) or None, ) dev_reg.async_remove_device(device.id) diff --git a/custom_components/diveracontrol/device_action.py b/custom_components/diveracontrol/device_action.py index c97d9e1..b03f735 100644 --- a/custom_components/diveracontrol/device_action.py +++ b/custom_components/diveracontrol/device_action.py @@ -29,7 +29,7 @@ PERM_STATUS_USER, PERM_STATUS_VEHICLE, ) -from .utils import get_translation, get_ucr_data_from_device +from .utils import get_device_config_entry_ids, get_translation, get_ucr_data_from_device ACTION_TYPES: tuple[str, ...] = ( "request_refresh", @@ -187,7 +187,7 @@ async def async_get_actions( device_registry = dr.async_get(hass) device = device_registry.async_get(device_id) - if not device or not device.config_entry_id: + if not device or not get_device_config_entry_ids(device): return [] try: diff --git a/custom_components/diveracontrol/utils.py b/custom_components/diveracontrol/utils.py index 1eeee11..d8cadbf 100644 --- a/custom_components/diveracontrol/utils.py +++ b/custom_components/diveracontrol/utils.py @@ -14,6 +14,30 @@ _LOGGER = logging.getLogger(__name__) +def get_device_config_entry_ids(device: dr.DeviceEntry) -> tuple[str, ...]: + """Return all config entry ids linked to a device. + + Home Assistant 2025.12 replaced ``DeviceEntry.config_entry_id`` with + ``primary_config_entry`` and a ``config_entries`` list. This helper works + with both the old and the new API. + + Args: + device: Device registry entry. + + Returns: + Tuple of config entry ids linked to the device. + """ + entry_id = getattr(device, "config_entry_id", None) + if entry_id: + return (entry_id,) + primary = getattr(device, "primary_config_entry", None) + if primary: + return (primary, *( + e for e in getattr(device, "config_entries", ()) if e and e != primary + )) + return () + + def get_ucr_data_from_device( hass: HomeAssistant, device_id: str, @@ -36,18 +60,20 @@ def get_ucr_data_from_device( device_registry = dr.async_get(hass) device = device_registry.async_get(device_id) - if not device or not device.config_entry_id: + if not device or not get_device_config_entry_ids(device): raise HomeAssistantError( f"Device not found or has no config entries: {device_id}" ) - # Get config entry - config_entry_id = device.config_entry_id - if not config_entry_id: - raise HomeAssistantError(f"Config entry not found for device: {device_id}") + # Get config entry (prefer an entry belonging to this integration) + entry = None + for config_entry_id in get_device_config_entry_ids(device): + candidate = hass.config_entries.async_get_entry(config_entry_id) + if candidate and candidate.domain == DOMAIN: + entry = candidate + break - entry = hass.config_entries.async_get_entry(config_entry_id) - if not entry or entry.domain != DOMAIN: + if entry is None: raise HomeAssistantError(f"Invalid config entry for device: {device_id}") # Get cluster_id From b565b09a48b8801879015852bcf1a97f6395bff0 Mon Sep 17 00:00:00 2001 From: Vibe Nuage Agent Date: Mon, 12 Oct 2026 13:41:24 +0000 Subject: [PATCH 2/3] style: apply black formatting Co-authored-by: moehrem --- custom_components/diveracontrol/device_action.py | 6 +++++- custom_components/diveracontrol/utils.py | 7 ++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/custom_components/diveracontrol/device_action.py b/custom_components/diveracontrol/device_action.py index b03f735..d937f6a 100644 --- a/custom_components/diveracontrol/device_action.py +++ b/custom_components/diveracontrol/device_action.py @@ -29,7 +29,11 @@ PERM_STATUS_USER, PERM_STATUS_VEHICLE, ) -from .utils import get_device_config_entry_ids, get_translation, get_ucr_data_from_device +from .utils import ( + get_device_config_entry_ids, + get_translation, + get_ucr_data_from_device, +) ACTION_TYPES: tuple[str, ...] = ( "request_refresh", diff --git a/custom_components/diveracontrol/utils.py b/custom_components/diveracontrol/utils.py index d8cadbf..a876f53 100644 --- a/custom_components/diveracontrol/utils.py +++ b/custom_components/diveracontrol/utils.py @@ -32,9 +32,10 @@ def get_device_config_entry_ids(device: dr.DeviceEntry) -> tuple[str, ...]: return (entry_id,) primary = getattr(device, "primary_config_entry", None) if primary: - return (primary, *( - e for e in getattr(device, "config_entries", ()) if e and e != primary - )) + return ( + primary, + *(e for e in getattr(device, "config_entries", ()) if e and e != primary), + ) return () From a84f30ac0a25a94745436588835ec0c11fe169b7 Mon Sep 17 00:00:00 2001 From: Vibe Nuage Agent Date: Mon, 12 Oct 2026 13:45:50 +0000 Subject: [PATCH 3/3] fix: mypy type for device argument to accept ChildDeviceEntry Co-authored-by: moehrem --- custom_components/diveracontrol/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/diveracontrol/utils.py b/custom_components/diveracontrol/utils.py index a876f53..5dfcefd 100644 --- a/custom_components/diveracontrol/utils.py +++ b/custom_components/diveracontrol/utils.py @@ -14,7 +14,7 @@ _LOGGER = logging.getLogger(__name__) -def get_device_config_entry_ids(device: dr.DeviceEntry) -> tuple[str, ...]: +def get_device_config_entry_ids(device: Any) -> tuple[str, ...]: """Return all config entry ids linked to a device. Home Assistant 2025.12 replaced ``DeviceEntry.config_entry_id`` with