core/homeassistant/components/statistics/config_flow.py

151 lines
4.4 KiB
Python

"""Config flow for statistics."""
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, cast
import voluptuous as vol
from homeassistant.components.binary_sensor import DOMAIN as BINARY_SENSOR_DOMAIN
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
from homeassistant.const import CONF_ENTITY_ID, CONF_NAME
from homeassistant.core import split_entity_id
from homeassistant.helpers.schema_config_entry_flow import (
SchemaCommonFlowHandler,
SchemaConfigFlowHandler,
SchemaFlowError,
SchemaFlowFormStep,
)
from homeassistant.helpers.selector import (
BooleanSelector,
DurationSelector,
DurationSelectorConfig,
EntitySelector,
EntitySelectorConfig,
NumberSelector,
NumberSelectorConfig,
NumberSelectorMode,
SelectSelector,
SelectSelectorConfig,
SelectSelectorMode,
TextSelector,
)
from . import DOMAIN
from .sensor import (
CONF_KEEP_LAST_SAMPLE,
CONF_MAX_AGE,
CONF_PERCENTILE,
CONF_PRECISION,
CONF_SAMPLES_MAX_BUFFER_SIZE,
CONF_STATE_CHARACTERISTIC,
DEFAULT_NAME,
DEFAULT_PRECISION,
STATS_BINARY_SUPPORT,
STATS_NUMERIC_SUPPORT,
)
async def get_state_characteristics(handler: SchemaCommonFlowHandler) -> vol.Schema:
"""Return schema with state characteristics."""
is_binary = (
split_entity_id(handler.options[CONF_ENTITY_ID])[0] == BINARY_SENSOR_DOMAIN
)
if is_binary:
options = STATS_BINARY_SUPPORT
else:
options = STATS_NUMERIC_SUPPORT
return vol.Schema(
{
vol.Required(CONF_STATE_CHARACTERISTIC): SelectSelector(
SelectSelectorConfig(
options=list(options),
translation_key=CONF_STATE_CHARACTERISTIC,
sort=True,
mode=SelectSelectorMode.DROPDOWN,
)
),
}
)
async def validate_options(
handler: SchemaCommonFlowHandler, user_input: dict[str, Any]
) -> dict[str, Any]:
"""Validate options selected."""
if (
user_input.get(CONF_SAMPLES_MAX_BUFFER_SIZE) is None
and user_input.get(CONF_MAX_AGE) is None
):
raise SchemaFlowError("missing_max_age_or_sampling_size")
if (
user_input.get(CONF_KEEP_LAST_SAMPLE) is True
and user_input.get(CONF_MAX_AGE) is None
):
raise SchemaFlowError("missing_keep_last_sample")
handler.parent_handler._async_abort_entries_match({**handler.options, **user_input}) # noqa: SLF001
return user_input
DATA_SCHEMA_SETUP = vol.Schema(
{
vol.Required(CONF_NAME, default=DEFAULT_NAME): TextSelector(),
vol.Required(CONF_ENTITY_ID): EntitySelector(
EntitySelectorConfig(domain=[BINARY_SENSOR_DOMAIN, SENSOR_DOMAIN])
),
}
)
DATA_SCHEMA_OPTIONS = vol.Schema(
{
vol.Optional(CONF_SAMPLES_MAX_BUFFER_SIZE): NumberSelector(
NumberSelectorConfig(min=0, step=1, mode=NumberSelectorMode.BOX)
),
vol.Optional(CONF_MAX_AGE): DurationSelector(
DurationSelectorConfig(enable_day=False, allow_negative=False)
),
vol.Optional(CONF_KEEP_LAST_SAMPLE, default=False): BooleanSelector(),
vol.Optional(CONF_PERCENTILE, default=50): NumberSelector(
NumberSelectorConfig(min=1, max=99, step=1, mode=NumberSelectorMode.BOX)
),
vol.Optional(CONF_PRECISION, default=DEFAULT_PRECISION): NumberSelector(
NumberSelectorConfig(min=0, step=1, mode=NumberSelectorMode.BOX)
),
}
)
CONFIG_FLOW = {
"user": SchemaFlowFormStep(
schema=DATA_SCHEMA_SETUP,
next_step="state_characteristic",
),
"state_characteristic": SchemaFlowFormStep(
schema=get_state_characteristics, next_step="options"
),
"options": SchemaFlowFormStep(
schema=DATA_SCHEMA_OPTIONS,
validate_user_input=validate_options,
),
}
OPTIONS_FLOW = {
"init": SchemaFlowFormStep(
DATA_SCHEMA_OPTIONS,
validate_user_input=validate_options,
),
}
class StatisticsConfigFlowHandler(SchemaConfigFlowHandler, domain=DOMAIN):
"""Handle a config flow for Statistics."""
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[CONF_NAME])