Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions custom_components/diveracontrol/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand All @@ -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)

Expand Down
8 changes: 6 additions & 2 deletions custom_components/diveracontrol/device_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@
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",
Expand Down Expand Up @@ -187,7 +191,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:
Expand Down
41 changes: 34 additions & 7 deletions custom_components/diveracontrol/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,31 @@
_LOGGER = logging.getLogger(__name__)


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
``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,
Expand All @@ -36,18 +61,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
Expand Down
Loading