mirror of
https://github.com/home-assistant/core.git
synced 2026-10-06 06:15:47 -04:00
Mods to repair flow
This commit is contained in:
@@ -1,79 +1,33 @@
|
||||
"""The min_max component."""
|
||||
|
||||
from datetime import datetime
|
||||
import logging
|
||||
from types import MappingProxyType
|
||||
|
||||
from homeassistant.components.group import (
|
||||
CONF_ENTITIES,
|
||||
CONF_GROUP_TYPE,
|
||||
CONF_HIDE_MEMBERS,
|
||||
CONF_IGNORE_NON_NUMERIC,
|
||||
DOMAIN as GROUP_DOMAIN,
|
||||
)
|
||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||
from homeassistant.config_entries import SOURCE_USER, ConfigEntry, ConfigEntryState
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.event import async_call_later
|
||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
||||
|
||||
from .const import CONF_ENTITY_IDS, CONF_ROUND_DIGITS, DOMAIN
|
||||
from .const import DOMAIN
|
||||
|
||||
PLATFORMS = [Platform.SENSOR]
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Set up Min/Max from a config entry."""
|
||||
|
||||
# Create group config from entry options
|
||||
config = dict(entry.options)
|
||||
config[CONF_ENTITIES] = config.pop(CONF_ENTITY_IDS)
|
||||
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
|
||||
|
||||
new_config_entry = ConfigEntry(
|
||||
data={},
|
||||
discovery_keys=MappingProxyType({}),
|
||||
domain=GROUP_DOMAIN,
|
||||
minor_version=1,
|
||||
options=config,
|
||||
source=SOURCE_USER,
|
||||
subentries_data=[],
|
||||
title=entry.title,
|
||||
unique_id=None,
|
||||
version=1,
|
||||
async_create_issue(
|
||||
hass,
|
||||
DOMAIN,
|
||||
"migrate_to_group_sensor",
|
||||
is_fixable=True,
|
||||
is_persistent=False,
|
||||
severity=IssueSeverity.WARNING,
|
||||
translation_key="migrate_to_group_sensor",
|
||||
translation_placeholders={"title": entry.title},
|
||||
data={"entry_id": entry.entry_id},
|
||||
)
|
||||
|
||||
entity_reg = er.async_get(hass)
|
||||
if old_entity := entity_reg.async_get_entity_id(
|
||||
SENSOR_DOMAIN, DOMAIN, entry.entry_id
|
||||
):
|
||||
entity_reg.async_update_entity_platform(
|
||||
old_entity, GROUP_DOMAIN, new_config_entry_id=new_config_entry.entry_id
|
||||
)
|
||||
# If entity is not existing, it has already been migrated
|
||||
# and we should not create it again
|
||||
await hass.config_entries.async_add(new_config_entry)
|
||||
|
||||
# Wait for config entry setup to finish before removing the old config entry
|
||||
async def remove_old_entry(now: datetime) -> None:
|
||||
"""Remove the old config entry after migration."""
|
||||
if entry.state == ConfigEntryState.LOADED:
|
||||
await hass.config_entries.async_remove(entry.entry_id)
|
||||
else:
|
||||
async_call_later(hass, 5, remove_old_entry)
|
||||
|
||||
async_call_later(hass, 5, remove_old_entry)
|
||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Unload a config entry."""
|
||||
|
||||
return True
|
||||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
|
||||
@@ -1,19 +1,82 @@
|
||||
"""Config flow for Min/Max integration."""
|
||||
|
||||
from typing import Any
|
||||
from collections.abc import Mapping
|
||||
from typing import Any, cast
|
||||
|
||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
||||
import voluptuous as vol
|
||||
|
||||
from .const import DOMAIN
|
||||
from homeassistant.components.input_number import DOMAIN as INPUT_NUMBER_DOMAIN
|
||||
from homeassistant.components.number import DOMAIN as NUMBER_DOMAIN
|
||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||
from homeassistant.const import CONF_TYPE
|
||||
from homeassistant.helpers import selector
|
||||
from homeassistant.helpers.schema_config_entry_flow import (
|
||||
SchemaCommonFlowHandler,
|
||||
SchemaConfigFlowHandler,
|
||||
SchemaFlowFormStep,
|
||||
)
|
||||
|
||||
from .const import CONF_ENTITY_IDS, CONF_ROUND_DIGITS, DOMAIN
|
||||
|
||||
_STATISTIC_MEASURES = [
|
||||
"min",
|
||||
"max",
|
||||
"mean",
|
||||
"median",
|
||||
"last",
|
||||
"range",
|
||||
"sum",
|
||||
]
|
||||
|
||||
|
||||
class MinMaxConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a config flow for min_max integration."""
|
||||
OPTIONS_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_ENTITY_IDS): selector.EntitySelector(
|
||||
selector.EntitySelectorConfig(
|
||||
domain=[SENSOR_DOMAIN, NUMBER_DOMAIN, INPUT_NUMBER_DOMAIN],
|
||||
multiple=True,
|
||||
),
|
||||
),
|
||||
vol.Required(CONF_TYPE): selector.SelectSelector(
|
||||
selector.SelectSelectorConfig(
|
||||
options=_STATISTIC_MEASURES, translation_key=CONF_TYPE
|
||||
),
|
||||
),
|
||||
vol.Required(CONF_ROUND_DIGITS, default=2): selector.NumberSelector(
|
||||
selector.NumberSelectorConfig(
|
||||
min=0, max=6, mode=selector.NumberSelectorMode.BOX
|
||||
),
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
VERSION = 1
|
||||
CONFIG_SCHEMA = vol.Schema({})
|
||||
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Handle the user step."""
|
||||
return self.async_abort(reason="migrated_to_groups")
|
||||
|
||||
async def migrate_to_groups(
|
||||
handler: SchemaCommonFlowHandler, user_input: dict[str, Any]
|
||||
) -> dict[str, Any]:
|
||||
"""Abort flow as migrate to groups."""
|
||||
handler.parent_handler.async_abort(reason="migrated_to_groups")
|
||||
return user_input
|
||||
|
||||
|
||||
CONFIG_FLOW = {
|
||||
"user": SchemaFlowFormStep(CONFIG_SCHEMA, validate_user_input=migrate_to_groups),
|
||||
}
|
||||
|
||||
OPTIONS_FLOW = {
|
||||
"init": SchemaFlowFormStep(OPTIONS_SCHEMA),
|
||||
}
|
||||
|
||||
|
||||
class ConfigFlowHandler(SchemaConfigFlowHandler, domain=DOMAIN):
|
||||
"""Handle a config or options flow for Min/Max."""
|
||||
|
||||
config_flow = CONFIG_FLOW
|
||||
options_flow = OPTIONS_FLOW
|
||||
options_flow_reloads = True
|
||||
|
||||
def async_config_entry_title(self, options: Mapping[str, Any]) -> str:
|
||||
"""Return config entry title."""
|
||||
return cast(str, options["name"]) if "name" in options else ""
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
"""Repairs platform for the Workday integration."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from types import MappingProxyType
|
||||
from typing import 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
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from .const import CONF_ENTITY_IDS, CONF_ROUND_DIGITS, DOMAIN
|
||||
|
||||
|
||||
class MigrateToGroupSensorFlow(RepairsFlow):
|
||||
"""Handler for an issue fixing flow."""
|
||||
|
||||
def __init__(self, entry: ConfigEntry) -> None:
|
||||
"""Create flow."""
|
||||
self.entry = entry
|
||||
super().__init__()
|
||||
|
||||
async def async_step_init(
|
||||
self, user_input: dict[str, str] | None = None
|
||||
) -> data_entry_flow.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:
|
||||
"""Handle the migration step of a fix flow."""
|
||||
errors: dict[str, str] = {}
|
||||
if user_input is not None:
|
||||
config = dict(self.entry.options)
|
||||
config[CONF_ENTITIES] = config.pop(CONF_ENTITY_IDS)
|
||||
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
|
||||
|
||||
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,
|
||||
)
|
||||
|
||||
entity_reg = er.async_get(self.hass)
|
||||
if old_entity := entity_reg.async_get_entity_id(
|
||||
SENSOR_DOMAIN, DOMAIN, self.entry.entry_id
|
||||
):
|
||||
entity_reg.async_update_entity_platform(
|
||||
old_entity,
|
||||
GROUP_DOMAIN,
|
||||
new_config_entry_id=new_config_entry.entry_id,
|
||||
)
|
||||
|
||||
await self.hass.config_entries.async_add(new_config_entry)
|
||||
await self.hass.config_entries.async_remove(self.entry.entry_id)
|
||||
|
||||
return self.async_create_entry(data={})
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="migrate",
|
||||
data_schema=vol.Schema({}),
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
|
||||
async def async_create_fix_flow(
|
||||
hass: HomeAssistant,
|
||||
issue_id: str,
|
||||
data: dict[str, Any] | None,
|
||||
) -> RepairsFlow:
|
||||
"""Create flow."""
|
||||
if data and (entry_id := data.get("entry_id")):
|
||||
entry_id = cast(str, entry_id)
|
||||
entry = hass.config_entries.async_get_entry(entry_id)
|
||||
assert entry
|
||||
return MigrateToGroupSensorFlow(entry)
|
||||
|
||||
return ConfirmRepairFlow()
|
||||
@@ -14,6 +14,7 @@ from homeassistant.components.sensor import (
|
||||
SensorEntity,
|
||||
SensorStateClass,
|
||||
)
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
ATTR_UNIT_OF_MEASUREMENT,
|
||||
@@ -26,9 +27,12 @@ from homeassistant.const import (
|
||||
)
|
||||
from homeassistant.core import Event, EventStateChangedData, HomeAssistant, callback
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers import config_validation as cv, entity_registry as er
|
||||
from homeassistant.helpers.entity import get_device_class
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.entity_platform import (
|
||||
AddConfigEntryEntitiesCallback,
|
||||
AddEntitiesCallback,
|
||||
)
|
||||
from homeassistant.helpers.event import async_track_state_change_event
|
||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
||||
from homeassistant.helpers.reload import async_setup_reload_service
|
||||
@@ -78,6 +82,32 @@ PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddConfigEntryEntitiesCallback,
|
||||
) -> None:
|
||||
"""Initialize min/max/mean config entry."""
|
||||
registry = er.async_get(hass)
|
||||
entity_ids = er.async_validate_entity_ids(
|
||||
registry, config_entry.options[CONF_ENTITY_IDS]
|
||||
)
|
||||
sensor_type = config_entry.options[CONF_TYPE]
|
||||
round_digits = int(config_entry.options[CONF_ROUND_DIGITS])
|
||||
|
||||
async_add_entities(
|
||||
[
|
||||
MinMaxSensor(
|
||||
entity_ids,
|
||||
config_entry.title,
|
||||
sensor_type,
|
||||
round_digits,
|
||||
config_entry.entry_id,
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
async def yaml_deprecation_notice(hass: HomeAssistant, config: ConfigType) -> None:
|
||||
"""Raise repair issue for YAML configuration deprecation."""
|
||||
platform_config = config.copy()
|
||||
|
||||
Reference in New Issue
Block a user