updated apps
This commit is contained in:
@@ -1,119 +1,118 @@
|
||||
import logging
|
||||
|
||||
from awesomeversion import AwesomeVersion
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
CONF_DEVICE,
|
||||
__version__ as HA_VERSION, # noqa: N812
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.const import CONF_DEVICE
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import device_registry
|
||||
from homeassistant.helpers.device_registry import DeviceEntry, DeviceInfo
|
||||
from homeassistant.helpers.device import async_entity_id_to_device
|
||||
from homeassistant.helpers.device_registry import DeviceEntry
|
||||
from homeassistant.helpers.entity import Entity
|
||||
import homeassistant.helpers.entity_registry as er
|
||||
from homeassistant.helpers.entity_registry import RegistryEntry
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
|
||||
from custom_components.powercalc.common import SourceEntity
|
||||
from custom_components.powercalc.const import CONF_SENSOR_TYPE, SensorType
|
||||
from custom_components.powercalc.sensors.abstract import BaseEntity
|
||||
from custom_components.powercalc.const import CONF_AREA
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def attach_entities_to_source_device(
|
||||
async def attach_entities_to_resolved_device(
|
||||
config_entry: ConfigEntry | None,
|
||||
entities_to_add: list[Entity],
|
||||
hass: HomeAssistant,
|
||||
source_entity: SourceEntity | None,
|
||||
sensor_config: ConfigType | None = None,
|
||||
) -> None:
|
||||
"""Set the entity to same device as the source entity, if any available."""
|
||||
|
||||
device_entry = source_entity.device_entry if source_entity else None
|
||||
if not device_entry and config_entry:
|
||||
device_id = config_entry.data.get(CONF_DEVICE)
|
||||
if device_id:
|
||||
device_entry = device_registry.async_get(hass).async_get(device_id)
|
||||
"""Set entities to the configured or source device, if any available."""
|
||||
|
||||
device_entry = get_device_entry(hass, sensor_config, source_entity, config_entry)
|
||||
if not device_entry:
|
||||
if config_entry:
|
||||
sensor_type = SensorType(config_entry.data.get(CONF_SENSOR_TYPE, SensorType.VIRTUAL_POWER))
|
||||
if sensor_type == SensorType.GROUP:
|
||||
remove_stale_devices(hass, config_entry, None)
|
||||
return
|
||||
|
||||
if config_entry:
|
||||
bind_config_entry_to_device(hass, config_entry, device_entry)
|
||||
|
||||
for entity in (entity for entity in entities_to_add if isinstance(entity, BaseEntity)):
|
||||
for entity in entities_to_add:
|
||||
try:
|
||||
if AwesomeVersion(HA_VERSION) >= AwesomeVersion("2025.8.0") and config_entry:
|
||||
entity.device_entry = device_entry
|
||||
else:
|
||||
entity.source_device_id = device_entry.id # type: ignore
|
||||
entity.device_entry = device_entry
|
||||
except AttributeError: # pragma: no cover
|
||||
_LOGGER.error("%s: Cannot set device id on entity", entity.entity_id)
|
||||
|
||||
|
||||
def bind_config_entry_to_device(hass: HomeAssistant, config_entry: ConfigEntry, device_entry: DeviceEntry) -> None:
|
||||
"""
|
||||
When the user selected a specific device in the config flow, bind the config entry to that device
|
||||
This will let HA bind all the powercalc entities for that config entry to the concerning device
|
||||
"""
|
||||
|
||||
if config_entry.entry_id not in device_entry.config_entries:
|
||||
device_reg = device_registry.async_get(hass)
|
||||
device_reg.async_update_device(
|
||||
device_entry.id,
|
||||
add_config_entry_id=config_entry.entry_id,
|
||||
)
|
||||
|
||||
remove_stale_devices(hass, config_entry, device_entry.id)
|
||||
|
||||
|
||||
def remove_stale_devices(
|
||||
def get_device_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
device_id: str | None,
|
||||
) -> None:
|
||||
"""Remove powercalc config entries from old devices."""
|
||||
device_reg = device_registry.async_get(hass)
|
||||
device_entries = device_registry.async_entries_for_config_entry(
|
||||
device_reg,
|
||||
config_entry.entry_id,
|
||||
)
|
||||
|
||||
stale_devices = [device_entry for device_entry in device_entries if device_entry.id != device_id]
|
||||
|
||||
for device_entry in stale_devices:
|
||||
device_reg.async_update_device(
|
||||
device_entry.id,
|
||||
remove_config_entry_id=config_entry.entry_id,
|
||||
)
|
||||
|
||||
|
||||
def get_device_info(
|
||||
hass: HomeAssistant,
|
||||
sensor_config: ConfigType,
|
||||
source_entity: SourceEntity | None,
|
||||
) -> DeviceInfo | None:
|
||||
sensor_config: ConfigType | None = None,
|
||||
source_entity: SourceEntity | None = None,
|
||||
config_entry: ConfigEntry | None = None,
|
||||
) -> DeviceEntry | None:
|
||||
"""
|
||||
Get device info for a given powercalc entity configuration.
|
||||
Get device entry for a given powercalc entity configuration.
|
||||
Prefer user configured device, when it is not set fallback to the same device as the source entity
|
||||
"""
|
||||
device_id = sensor_config.get(CONF_DEVICE)
|
||||
device = None
|
||||
device_id = None
|
||||
if sensor_config is not None:
|
||||
device_id = sensor_config.get(CONF_DEVICE)
|
||||
if device_id is None and config_entry is not None:
|
||||
device_id = config_entry.data.get(CONF_DEVICE)
|
||||
if device_id is not None:
|
||||
device_reg = device_registry.async_get(hass)
|
||||
device = device_reg.async_get(device_id)
|
||||
elif source_entity:
|
||||
device = source_entity.device_entry
|
||||
return device_registry.async_get(hass).async_get(device_id)
|
||||
|
||||
if device is None:
|
||||
return None
|
||||
if source_entity:
|
||||
return source_entity.device_entry or async_entity_id_to_device(hass, source_entity.entity_id)
|
||||
|
||||
if not device.identifiers and not device.connections:
|
||||
return None
|
||||
return None
|
||||
|
||||
return DeviceInfo(
|
||||
identifiers=device.identifiers,
|
||||
connections=device.connections,
|
||||
)
|
||||
|
||||
@callback
|
||||
def bind_entity_to_registry_metadata(
|
||||
hass: HomeAssistant,
|
||||
entity_id: str | None,
|
||||
device_entry: DeviceEntry | None,
|
||||
sensor_config: ConfigType | None,
|
||||
) -> None:
|
||||
"""Bind a Powercalc entity to configured registry metadata."""
|
||||
if entity_id is None:
|
||||
return
|
||||
|
||||
entity_reg = er.async_get(hass)
|
||||
entity_entry = entity_reg.async_get(entity_id)
|
||||
if entity_entry is None:
|
||||
return
|
||||
|
||||
bind_entity_to_device(entity_reg, entity_entry, device_entry)
|
||||
bind_entity_to_area(entity_reg, entity_entry, sensor_config.get(CONF_AREA) if sensor_config else None)
|
||||
|
||||
|
||||
@callback
|
||||
def bind_entity_to_device(
|
||||
entity_reg: er.EntityRegistry,
|
||||
entity_entry: RegistryEntry,
|
||||
device_entry: DeviceEntry | None,
|
||||
) -> None:
|
||||
"""Bind a Powercalc entity to the resolved device."""
|
||||
# Home Assistant only consumes entity.device_entry while creating registry
|
||||
# entries for config-entry platforms. YAML/platform entities need this
|
||||
# registry update after they have been added.
|
||||
if device_entry is None:
|
||||
return
|
||||
|
||||
if entity_entry.config_entry_id is not None or entity_entry.device_id == device_entry.id:
|
||||
return
|
||||
|
||||
_LOGGER.debug("Binding %s to device %s", entity_entry.entity_id, device_entry.id)
|
||||
entity_reg.async_update_entity(entity_entry.entity_id, device_id=device_entry.id)
|
||||
|
||||
|
||||
@callback
|
||||
def bind_entity_to_area(
|
||||
entity_reg: er.EntityRegistry,
|
||||
entity_entry: RegistryEntry,
|
||||
area_id: str | None,
|
||||
) -> None:
|
||||
"""Bind a Powercalc entity to the configured area."""
|
||||
if not area_id:
|
||||
return
|
||||
|
||||
if entity_entry.area_id == area_id:
|
||||
return
|
||||
|
||||
_LOGGER.debug("Binding %s to area %s", entity_entry.entity_id, area_id)
|
||||
entity_reg.async_update_entity(entity_entry.entity_id, area_id=area_id)
|
||||
|
||||
Reference in New Issue
Block a user