197 files

This commit is contained in:
Home Assistant Version Control
2026-08-21 18:53:37 +00:00
parent 89d9f5e49b
commit 383e9ed04e
197 changed files with 4386 additions and 1837 deletions
+31 -15
View File
@@ -1,8 +1,7 @@
from dataclasses import dataclass
import math
import re
from typing import NamedTuple
from homeassistant.components.light import ATTR_SUPPORTED_COLOR_MODES, ColorMode
from homeassistant.const import CONF_ENTITY_ID, CONF_NAME, CONF_UNIQUE_ID
from homeassistant.core import HomeAssistant, split_entity_id
import homeassistant.helpers.device_registry as dr
@@ -29,17 +28,45 @@ from .const import (
from .errors import SensorConfigurationError
class SourceEntity(NamedTuple):
@dataclass(frozen=True)
class SourceEntity:
"""The appliance a powercalc sensor measures, resolved from the entity and device registry."""
object_id: str
entity_id: str
domain: str
unique_id: str | None = None
name: str | None = None
supported_color_modes: list[ColorMode] | None = None
entity_entry: er.RegistryEntry | None = None
device_entry: dr.DeviceEntry | None = None
config_entry_id: str | None = None
@property
def is_dummy(self) -> bool:
"""Whether this source has no real entity behind it, such as a daily fixed energy or group sensor."""
return self.entity_id == DUMMY_ENTITY_ID
@property
def device_id(self) -> str | None:
"""The ID of the device this source belongs to, when it is bound to one."""
return self.device_entry.id if self.device_entry else None
@property
def log_identifier(self) -> str:
"""Build a label identifying this source, used as prefix for log messages about it."""
if self.config_entry_id:
return _label("config_entry", self.config_entry_id, self.name)
if self.entity_id and not self.is_dummy:
return self.entity_id
if self.device_entry:
return _label("device", self.device_entry.id, self.device_entry.name_by_user or self.device_entry.name)
return self.object_id # pragma: no cover
def _label(prefix: str, identifier: str, name: str | None) -> str:
"""Build `prefix id (name)`, omitting the name when the registry does not have one."""
return f"{prefix} {identifier} ({name})" if name else f"{prefix} {identifier}"
EXCLUDE_FROM_PARENT_CONFIG = (
CONF_NAME,
@@ -85,19 +112,9 @@ def create_source_entity(entity_id: str, hass: HomeAssistant) -> SourceEntity:
)
unique_id = None
supported_color_modes: list[ColorMode] = []
if entity_entry:
source_entity_domain = entity_entry.domain
unique_id = entity_entry.unique_id
if entity_entry.capabilities:
supported_color_modes = entity_entry.capabilities.get(
ATTR_SUPPORTED_COLOR_MODES,
[],
)
entity_state = hass.states.get(entity_id)
if entity_state:
supported_color_modes = entity_state.attributes.get(ATTR_SUPPORTED_COLOR_MODES, [])
return SourceEntity(
source_object_id,
@@ -111,7 +128,6 @@ def create_source_entity(entity_id: str, hass: HomeAssistant) -> SourceEntity:
entity_entry,
device_entry,
),
supported_color_modes or [],
entity_entry,
device_entry,
)