Compare commits

...
Sign in to create a new pull request.

2 commits

Author SHA1 Message Date
G Johansson
bfc03b633a min_max config flow 2024-01-03 19:43:39 +00:00
G Johansson
896b2c8779 Start deprecation min_max 2024-01-03 19:31:07 +00:00
4 changed files with 126 additions and 44 deletions

View file

@ -1,6 +1,7 @@
"""Config flow for Group integration."""
from __future__ import annotations
from collections import ChainMap
from collections.abc import Callable, Coroutine, Mapping
from functools import partial
from typing import Any, cast
@ -15,6 +16,7 @@ from homeassistant.helpers import entity_registry as er, selector
from homeassistant.helpers.schema_config_entry_flow import (
SchemaCommonFlowHandler,
SchemaConfigFlowHandler,
SchemaFlowError,
SchemaFlowFormStep,
SchemaFlowMenuStep,
SchemaOptionsFlowHandler,
@ -45,6 +47,38 @@ _STATISTIC_MEASURES = [
]
def import_sensor() -> (
Callable[
[SchemaCommonFlowHandler, dict[str, Any]], Coroutine[Any, Any, dict[str, Any]]
]
):
"""Import sensor."""
# Missing Make sure the new group config entry adopts the existing min_max entities by changing the config entry and unique_id
# Missing Remove the min_max config entry
async def _set_group_type(
handler: SchemaCommonFlowHandler, user_input: dict[str, Any]
) -> dict[str, Any]:
"""Add group type to user input and test not imported."""
hass = handler.parent_handler.hass
entries = hass.config_entries.async_entries(DOMAIN)
match_dict = {"group_type": "sensor", **user_input}
for entry in entries:
if all(
item
in ChainMap(
entry.options, # type: ignore[arg-type]
entry.data, # type: ignore[arg-type]
).items()
for item in match_dict.items()
):
raise SchemaFlowError("already_configured")
return {"group_type": "sensor", **user_input}
return _set_group_type
async def basic_group_options_schema(
domain: str | list[str], handler: SchemaCommonFlowHandler | None
) -> vol.Schema:
@ -263,6 +297,10 @@ OPTIONS_FLOW = {
partial(light_switch_options_schema, "switch"),
preview="group",
),
"import": SchemaFlowFormStep(
SENSOR_CONFIG_SCHEMA,
validate_user_input=import_sensor(),
),
}
PREVIEW_OPTIONS_SCHEMA: dict[str, vol.Schema] = {}

View file

@ -6,62 +6,24 @@ from typing import Any, cast
import voluptuous as vol
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.core import callback
from homeassistant.data_entry_flow import AbortFlow
from homeassistant.helpers import selector
from homeassistant.helpers.schema_config_entry_flow import (
SchemaConfigFlowHandler,
SchemaFlowFormStep,
)
from .const import CONF_ENTITY_IDS, CONF_ROUND_DIGITS, DOMAIN
_STATISTIC_MEASURES = [
"min",
"max",
"mean",
"median",
"last",
"range",
"sum",
]
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
),
),
}
)
from .const import DOMAIN
CONFIG_SCHEMA = vol.Schema(
{
vol.Required("name"): selector.TextSelector(),
}
).extend(OPTIONS_SCHEMA.schema)
)
CONFIG_FLOW = {
"user": SchemaFlowFormStep(CONFIG_SCHEMA),
}
OPTIONS_FLOW = {
"init": SchemaFlowFormStep(OPTIONS_SCHEMA),
"user": SchemaFlowFormStep(vol.Schema({})),
}
@ -69,8 +31,12 @@ class ConfigFlowHandler(SchemaConfigFlowHandler, domain=DOMAIN):
"""Handle a config or options flow for Min/Max."""
config_flow = CONFIG_FLOW
options_flow = OPTIONS_FLOW
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 ""
@callback
def async_config_flow_finished(self, options: Mapping[str, Any]) -> None:
"""Abort the flow as it should not be setup."""
raise AbortFlow(reason="being_removed")

View file

@ -1,6 +1,9 @@
{
"title": "Combine the state of several sensors",
"config": {
"abort": {
"being_removed": "Combine the state of several sensors ss being removed. Please configure a Group Sensor instead which provides this functionality."
},
"step": {
"user": {
"title": "[%key:component::min_max::title%]",

View file

@ -700,3 +700,78 @@ async def test_option_flow_sensor_preview_config_entry_removed(
msg = await client.receive_json()
assert not msg["success"]
assert msg["error"] == {"code": "home_assistant_error", "message": "Unknown error"}
async def test_import(hass: HomeAssistant) -> None:
"""Test import config flow."""
members = ["sensor.one", "sensor.two"]
for member in members:
hass.states.async_set(member, "on", {})
with patch(
"homeassistant.components.group.async_setup_entry", wraps=async_setup_entry
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={
"ignore_non_numeric": False,
"entities": ["sensor.one", "sensor.two"],
"hide_members": False,
"type": "sum",
"name": "Sensor Group sum",
},
)
await hass.async_block_till_done()
assert result["type"] == FlowResultType.CREATE_ENTRY
assert result["title"] == "Sensor Group sum"
assert result["data"] == {}
assert result["options"] == {
"entities": members,
"group_type": "sensor",
"hide_members": False,
"name": "Sensor Group sum",
"ignore_non_numeric": False,
"type": "sum",
}
async def test_import_already_exist(hass: HomeAssistant) -> None:
"""Test import config flow."""
members = ["sensor.one", "sensor.two"]
for member in members:
hass.states.async_set(member, "on", {})
group_config_entry = MockConfigEntry(
data={},
domain=DOMAIN,
options={
"entities": members,
"group_type": "sensor",
"hide_members": False,
"ignore_non_numeric": False,
"type": "sum",
"name": "Sensor Group sum",
},
title="Sensor Group sum",
)
group_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={
"ignore_non_numeric": False,
"entities": members,
"hide_members": False,
"type": "sum",
"name": "Sensor Group sum",
},
)
await hass.async_block_till_done()
assert result["type"] == FlowResultType.FORM
assert result["errors"] == {"base": "already_configured"}