329 files

This commit is contained in:
Home Assistant Version Control
2026-08-06 13:56:25 +00:00
parent 0df89406fa
commit 7afe7add1d
330 changed files with 13098 additions and 5942 deletions
@@ -1,8 +1,7 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any
from homeassistant.config_entries import ConfigFlowResult
from homeassistant.const import CONF_DEVICE
from homeassistant.helpers import selector, translation
import voluptuous as vol
@@ -21,6 +20,7 @@ from custom_components.powercalc.const import (
LIBRARY_URL,
CalculationStrategy,
)
from custom_components.powercalc.device_binding import get_devices_for_config_entry
from custom_components.powercalc.discovery import (
get_power_profile_by_source_device,
get_power_profile_by_source_entity,
@@ -29,6 +29,7 @@ from custom_components.powercalc.flow_helper.common import FlowType, PowercalcFo
from custom_components.powercalc.flow_helper.dynamic_field_builder import build_dynamic_field_schema
from custom_components.powercalc.flow_helper.schema import (
SCHEMA_ENERGY_SENSOR_TOGGLE,
SCHEMA_STANDBY_ENERGY_SENSOR_TOGGLE,
SCHEMA_UTILITY_METER_TOGGLE,
build_sub_profile_schema,
)
@@ -58,6 +59,7 @@ SCHEMA_POWER_AUTODISCOVERED = vol.Schema(
SCHEMA_POWER_OPTIONS_LIBRARY = vol.Schema(
{
**SCHEMA_ENERGY_SENSOR_TOGGLE.schema,
**SCHEMA_STANDBY_ENERGY_SENSOR_TOGGLE.schema,
**SCHEMA_UTILITY_METER_TOGGLE.schema,
},
)
@@ -208,6 +210,9 @@ class LibraryFlow:
if Step.LIBRARY_CUSTOM_FIELDS not in handled_steps and profile.has_custom_fields:
return await self.async_step_library_custom_fields()
if Step.SELECT_DEVICE not in handled_steps and profile.discovery_by == DiscoveryBy.CONFIG_ENTRY:
return await self.async_step_select_device()
if Step.AVAILABILITY_ENTITY not in handled_steps and profile.discovery_by == DiscoveryBy.DEVICE:
result = await self.async_step_availability_entity()
if result:
@@ -218,6 +223,35 @@ class LibraryFlow:
return None
async def async_step_select_device(self, user_input: dict[str, Any] | None = None) -> ConfigFlowResult:
"""Ask which device should receive the entities created for a config-entry profile."""
assert self.flow.source_entity is not None
assert self.flow.source_entity.config_entry_id is not None
devices = get_devices_for_config_entry(self.flow.hass, self.flow.source_entity.config_entry_id)
return await self.flow.handle_form_step(
PowercalcFormStep(
step=Step.SELECT_DEVICE,
schema=vol.Schema(
{
vol.Required(CONF_DEVICE): selector.SelectSelector(
selector.SelectSelectorConfig(
options=[
selector.SelectOptionDict(
value=device.id,
label=device.name_by_user or device.name or device.id,
)
for device in devices
],
mode=selector.SelectSelectorMode.DROPDOWN,
),
),
},
),
next_step=Step.POST_LIBRARY,
),
user_input,
)
async def _async_next_strategy_step(self, profile: PowerProfile) -> ConfigFlowResult | None:
"""Return the next step needed to configure the calculation strategy, or None when nothing is left to ask."""
handled_steps = self.flow.handled_steps
@@ -397,7 +431,7 @@ class LibraryFlow:
def _get_library_device_types(self) -> set[DeviceType] | None:
"""Determine which device types should be shown in the library selectors."""
if self._get_library_discovery_by() == DiscoveryBy.DEVICE:
if self._get_library_discovery_by() in (DiscoveryBy.CONFIG_ENTRY, DiscoveryBy.DEVICE):
return None
if self.flow.source_entity:
@@ -407,9 +441,19 @@ class LibraryFlow:
def _get_library_discovery_by(self) -> DiscoveryBy | None:
"""Determine whether listing should be filtered by discovery mode."""
if self.flow.source_entity and self.flow.source_entity.entity_id == DUMMY_ENTITY_ID:
return DiscoveryBy.DEVICE
return None
source_entity = self.flow.source_entity
if not source_entity:
return None
if source_entity.config_entry_id:
return DiscoveryBy.CONFIG_ENTRY
if source_entity.entity_id != DUMMY_ENTITY_ID:
return None
profile = self.flow.selected_profile
if profile and profile.discovery_by == DiscoveryBy.CONFIG_ENTRY:
return DiscoveryBy.CONFIG_ENTRY
return DiscoveryBy.DEVICE
class LibraryConfigFlow(LibraryFlow):
@@ -546,19 +590,22 @@ class LibraryConfigFlow(LibraryFlow):
def _get_profile_source(self, profile: PowerProfile) -> str:
"""Build the autodiscovery source description."""
source_entity = self.flow.source_entity
if source_entity and profile.discovery_by == DiscoveryBy.CONFIG_ENTRY:
config_entry_id = source_entity.config_entry_id
if config_entry_id:
return source_entity.name or config_entry_id
translations = translation.async_get_cached_translations(
self.flow.hass,
self.flow.hass.config.language,
"common",
DOMAIN,
)
if (
profile.discovery_by == DiscoveryBy.DEVICE
and self.flow.source_entity
and self.flow.source_entity.device_entry
):
device_entry = source_entity.device_entry if source_entity else None
if profile.discovery_by == DiscoveryBy.DEVICE and device_entry:
label = translations.get(f"component.{DOMAIN}.common.source_device")
return f"{label}: {self.flow.source_entity.device_entry.name}"
return f"{label}: {device_entry.name}"
return f"{translations.get(f'component.{DOMAIN}.common.source_entity')}: {self.flow.source_entity_id}"