mirror of
https://github.com/home-assistant/core.git
synced 2026-10-06 06:15:47 -04:00
Import
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import asyncio
|
||||
from collections.abc import Collection
|
||||
import logging
|
||||
from typing import Any
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
@@ -136,6 +136,31 @@ def groups_with_entity(hass: HomeAssistant, entity_id: str) -> list[str]:
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Set up a config entry."""
|
||||
if "old_entity_id" in entry.options:
|
||||
# This means we are migrating from a Min/Max helper to a Group sensor
|
||||
old_entity = entry.options["old_entity_id"]
|
||||
entity_reg = er.async_get(hass)
|
||||
old_entity_entry = entity_reg.async_get(old_entity)
|
||||
if not old_entity_entry:
|
||||
# User has manually removed it before we came here
|
||||
# Skip the migration and just continue with setting up the group sensor
|
||||
_LOGGER.warning(
|
||||
"Old entity %s has been manually removed before migration", old_entity
|
||||
)
|
||||
else:
|
||||
if TYPE_CHECKING:
|
||||
assert old_entity_entry.config_entry_id
|
||||
await hass.config_entries.async_unload(old_entity_entry.config_entry_id)
|
||||
entity_reg.async_update_entity_platform(
|
||||
old_entity,
|
||||
DOMAIN,
|
||||
new_config_entry_id=entry.entry_id,
|
||||
new_unique_id=entry.entry_id,
|
||||
)
|
||||
new_options = dict(entry.options)
|
||||
new_options.pop("old_entity_id")
|
||||
hass.config_entries.async_update_entry(entry, options=new_options)
|
||||
await hass.config_entries.async_remove(old_entity_entry.config_entry_id)
|
||||
await hass.config_entries.async_forward_entry_setups(
|
||||
entry, (entry.options["group_type"],)
|
||||
)
|
||||
|
||||
@@ -134,6 +134,12 @@ SENSOR_CONFIG_SCHEMA = basic_group_config_schema(
|
||||
["sensor", "number", "input_number"]
|
||||
).extend(SENSOR_CONFIG_EXTENDS)
|
||||
|
||||
SENSOR_IMPORT_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Required("old_entity_id"): selector.TextSelector(),
|
||||
}
|
||||
).extend(SENSOR_CONFIG_SCHEMA.schema)
|
||||
|
||||
|
||||
async def light_switch_options_schema(
|
||||
domain: str, handler: SchemaCommonFlowHandler | None
|
||||
@@ -197,8 +203,30 @@ def set_group_type(
|
||||
return _set_group_type
|
||||
|
||||
|
||||
def validate_import() -> Callable[
|
||||
[SchemaCommonFlowHandler, dict[str, Any]], Coroutine[Any, Any, dict[str, Any]]
|
||||
]:
|
||||
"""Validate import from Min/Max integration.
|
||||
|
||||
Should be removed when deprecation of Min/Max integration has ended.
|
||||
"""
|
||||
|
||||
async def _validate_and_set_type(
|
||||
handler: SchemaCommonFlowHandler, user_input: dict[str, Any]
|
||||
) -> dict[str, Any]:
|
||||
"""Add group type to user input."""
|
||||
validated_input = SENSOR_IMPORT_SCHEMA(user_input)
|
||||
return {CONF_GROUP_TYPE: "sensor", **validated_input}
|
||||
|
||||
return _validate_and_set_type
|
||||
|
||||
|
||||
CONFIG_FLOW = {
|
||||
"user": SchemaFlowMenuStep(GROUP_TYPES),
|
||||
"import": SchemaFlowFormStep(
|
||||
None,
|
||||
validate_user_input=validate_import(),
|
||||
),
|
||||
"binary_sensor": SchemaFlowFormStep(
|
||||
BINARY_SENSOR_CONFIG_SCHEMA,
|
||||
preview="group",
|
||||
|
||||
@@ -1,22 +1,19 @@
|
||||
"""Repairs platform for the Min/Max integration."""
|
||||
|
||||
from types import MappingProxyType
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import data_entry_flow
|
||||
from homeassistant.components.group import (
|
||||
CONF_ENTITIES,
|
||||
CONF_GROUP_TYPE,
|
||||
CONF_HIDE_MEMBERS,
|
||||
CONF_IGNORE_NON_NUMERIC,
|
||||
DOMAIN as GROUP_DOMAIN,
|
||||
)
|
||||
from homeassistant.components.repairs import ConfirmRepairFlow, RepairsFlow
|
||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||
from homeassistant.config_entries import SOURCE_USER, ConfigEntry, ConfigEntryDisabler
|
||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResult, FlowResultType
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from .const import CONF_ENTITY_IDS, CONF_ROUND_DIGITS, DOMAIN
|
||||
@@ -32,13 +29,13 @@ class MigrateToGroupSensorFlow(RepairsFlow):
|
||||
|
||||
async def async_step_init(
|
||||
self, user_input: dict[str, str] | None = None
|
||||
) -> data_entry_flow.FlowResult:
|
||||
) -> FlowResult:
|
||||
"""Handle the first step of a fix flow."""
|
||||
return await self.async_step_migrate()
|
||||
|
||||
async def async_step_migrate(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> data_entry_flow.FlowResult:
|
||||
) -> FlowResult:
|
||||
"""Handle the migration step of a fix flow."""
|
||||
entity_reg = er.async_get(self.hass)
|
||||
old_entity = entity_reg.async_get_entity_id(
|
||||
@@ -53,40 +50,18 @@ class MigrateToGroupSensorFlow(RepairsFlow):
|
||||
config.pop(CONF_ROUND_DIGITS)
|
||||
# Set group sensor defaults
|
||||
config[CONF_HIDE_MEMBERS] = False
|
||||
config[CONF_IGNORE_NON_NUMERIC] = False
|
||||
config[CONF_GROUP_TYPE] = SENSOR_DOMAIN
|
||||
# config[CONF_IGNORE_NON_NUMERIC] = False
|
||||
# config[CONF_GROUP_TYPE] = SENSOR_DOMAIN
|
||||
config["old_entity_id"] = old_entity
|
||||
|
||||
new_config_entry = ConfigEntry(
|
||||
data={},
|
||||
discovery_keys=MappingProxyType({}),
|
||||
domain=GROUP_DOMAIN,
|
||||
minor_version=1,
|
||||
options=config,
|
||||
source=SOURCE_USER,
|
||||
subentries_data=[],
|
||||
title=self.entry.title,
|
||||
unique_id=None,
|
||||
version=1,
|
||||
disabled_by=ConfigEntryDisabler.USER,
|
||||
import_result = await self.hass.config_entries.flow.async_init(
|
||||
GROUP_DOMAIN,
|
||||
context={"source": SOURCE_IMPORT},
|
||||
data=config,
|
||||
)
|
||||
|
||||
if not await self.hass.config_entries.async_unload(self.entry.entry_id):
|
||||
return self.async_abort(reason="unload_failed")
|
||||
await self.hass.config_entries.async_add(new_config_entry)
|
||||
try:
|
||||
entity_reg.async_update_entity_platform(
|
||||
old_entity,
|
||||
GROUP_DOMAIN,
|
||||
new_config_entry_id=new_config_entry.entry_id,
|
||||
new_unique_id=new_config_entry.entry_id,
|
||||
)
|
||||
except ValueError:
|
||||
return self.async_abort(reason="entity_update_failed")
|
||||
await self.hass.config_entries.async_set_disabled_by(
|
||||
entry_id=new_config_entry.entry_id, disabled_by=None
|
||||
)
|
||||
await self.hass.config_entries.async_remove(self.entry.entry_id)
|
||||
|
||||
if import_result["type"] != FlowResultType.CREATE_ENTRY:
|
||||
return self.async_abort(reason="could_not_import")
|
||||
return self.async_create_entry(data={})
|
||||
|
||||
entity_info = entity_reg.async_get(old_entity)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"migrate_to_group_sensor": {
|
||||
"fix_flow": {
|
||||
"abort": {
|
||||
"could_not_import": "Failed to import the config entry for the Group helper, please manually remove the Min/Max helper and create your new Group helper.",
|
||||
"entity_not_found": "Entity could not be found as it has been removed, aborting the repair.",
|
||||
"entity_update_failed": "Failed to update the entity to a Group sensor, please manually remove the obsolete entity.",
|
||||
"unload_failed": "Failed to unload the Min/Max helper, please restart repairing the issue."
|
||||
|
||||
@@ -15,13 +15,12 @@
|
||||
]),
|
||||
'group_type': 'sensor',
|
||||
'hide_members': False,
|
||||
'ignore_non_numeric': False,
|
||||
'name': 'My min_max',
|
||||
'type': 'max',
|
||||
}),
|
||||
'pref_disable_new_entities': False,
|
||||
'pref_disable_polling': False,
|
||||
'source': 'user',
|
||||
'source': 'import',
|
||||
'subentries': list([
|
||||
]),
|
||||
'title': 'My min_max',
|
||||
|
||||
Reference in New Issue
Block a user