Adapt next step based on filter type
This commit is contained in:
parent
2e8f7c1998
commit
cb04224b3f
3 changed files with 250 additions and 112 deletions
|
@ -22,7 +22,6 @@ from homeassistant.helpers.selector import (
|
|||
NumberSelector,
|
||||
NumberSelectorConfig,
|
||||
NumberSelectorMode,
|
||||
Selector,
|
||||
SelectSelector,
|
||||
SelectSelectorConfig,
|
||||
SelectSelectorMode,
|
||||
|
@ -63,85 +62,9 @@ FILTERS = [
|
|||
]
|
||||
|
||||
|
||||
async def get_options_schema(handler: SchemaCommonFlowHandler) -> vol.Schema:
|
||||
"""Return schema for options."""
|
||||
filter_schema: dict[vol.Marker, Selector] = {}
|
||||
|
||||
if handler.options[CONF_FILTER_NAME] == FILTER_NAME_OUTLIER:
|
||||
filter_schema = {
|
||||
vol.Optional(
|
||||
CONF_FILTER_WINDOW_SIZE, default=DEFAULT_WINDOW_SIZE
|
||||
): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step=1, mode=NumberSelectorMode.BOX)
|
||||
),
|
||||
vol.Optional(
|
||||
CONF_FILTER_RADIUS, default=DEFAULT_FILTER_RADIUS
|
||||
): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step="any", mode=NumberSelectorMode.BOX)
|
||||
),
|
||||
}
|
||||
|
||||
elif handler.options[CONF_FILTER_NAME] == FILTER_NAME_LOWPASS:
|
||||
filter_schema = {
|
||||
vol.Optional(
|
||||
CONF_FILTER_WINDOW_SIZE, default=DEFAULT_WINDOW_SIZE
|
||||
): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step=1, mode=NumberSelectorMode.BOX)
|
||||
),
|
||||
vol.Optional(
|
||||
CONF_FILTER_TIME_CONSTANT, default=DEFAULT_FILTER_TIME_CONSTANT
|
||||
): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step=1, mode=NumberSelectorMode.BOX)
|
||||
),
|
||||
}
|
||||
|
||||
elif handler.options[CONF_FILTER_NAME] == FILTER_NAME_RANGE:
|
||||
filter_schema = {
|
||||
vol.Optional(CONF_FILTER_LOWER_BOUND): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step="any", mode=NumberSelectorMode.BOX)
|
||||
),
|
||||
vol.Optional(CONF_FILTER_UPPER_BOUND): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step="any", mode=NumberSelectorMode.BOX)
|
||||
),
|
||||
}
|
||||
|
||||
elif handler.options[CONF_FILTER_NAME] == FILTER_NAME_TIME_SMA:
|
||||
filter_schema = {
|
||||
vol.Optional(CONF_TIME_SMA_TYPE, default=TIME_SMA_LAST): SelectSelector(
|
||||
SelectSelectorConfig(
|
||||
options=[TIME_SMA_LAST],
|
||||
mode=SelectSelectorMode.DROPDOWN,
|
||||
translation_key=CONF_TIME_SMA_TYPE,
|
||||
)
|
||||
),
|
||||
vol.Required(CONF_FILTER_WINDOW_SIZE): DurationSelector(
|
||||
DurationSelectorConfig(enable_day=False, allow_negative=False)
|
||||
),
|
||||
}
|
||||
|
||||
elif handler.options[CONF_FILTER_NAME] == FILTER_NAME_THROTTLE:
|
||||
filter_schema = {
|
||||
vol.Optional(
|
||||
CONF_FILTER_WINDOW_SIZE, default=DEFAULT_WINDOW_SIZE
|
||||
): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step=1, mode=NumberSelectorMode.BOX)
|
||||
),
|
||||
}
|
||||
|
||||
elif handler.options[CONF_FILTER_NAME] == FILTER_NAME_TIME_THROTTLE:
|
||||
filter_schema = {
|
||||
vol.Required(CONF_FILTER_WINDOW_SIZE): DurationSelector(
|
||||
DurationSelectorConfig(enable_day=False, allow_negative=False)
|
||||
),
|
||||
}
|
||||
|
||||
base_schema: dict[vol.Marker, Selector] = {
|
||||
vol.Optional(CONF_FILTER_PRECISION, default=DEFAULT_PRECISION): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step=1, mode=NumberSelectorMode.BOX)
|
||||
)
|
||||
}
|
||||
|
||||
return vol.Schema({**filter_schema, **base_schema})
|
||||
async def get_next_step(user_input: dict[str, Any]) -> str:
|
||||
"""Return next step for options."""
|
||||
return cast(str, user_input[CONF_FILTER_NAME])
|
||||
|
||||
|
||||
async def validate_options(
|
||||
|
@ -181,21 +104,130 @@ DATA_SCHEMA_SETUP = vol.Schema(
|
|||
}
|
||||
)
|
||||
|
||||
BASE_OPTIONS_SCHEMA = {
|
||||
vol.Optional(CONF_FILTER_PRECISION, default=DEFAULT_PRECISION): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step=1, mode=NumberSelectorMode.BOX)
|
||||
)
|
||||
}
|
||||
|
||||
OUTLIER_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Optional(
|
||||
CONF_FILTER_WINDOW_SIZE, default=DEFAULT_WINDOW_SIZE
|
||||
): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step=1, mode=NumberSelectorMode.BOX)
|
||||
),
|
||||
vol.Optional(CONF_FILTER_RADIUS, default=DEFAULT_FILTER_RADIUS): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step="any", mode=NumberSelectorMode.BOX)
|
||||
),
|
||||
}
|
||||
).extend(BASE_OPTIONS_SCHEMA)
|
||||
|
||||
LOWPASS_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Optional(
|
||||
CONF_FILTER_WINDOW_SIZE, default=DEFAULT_WINDOW_SIZE
|
||||
): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step=1, mode=NumberSelectorMode.BOX)
|
||||
),
|
||||
vol.Optional(
|
||||
CONF_FILTER_TIME_CONSTANT, default=DEFAULT_FILTER_TIME_CONSTANT
|
||||
): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step=1, mode=NumberSelectorMode.BOX)
|
||||
),
|
||||
}
|
||||
).extend(BASE_OPTIONS_SCHEMA)
|
||||
|
||||
RANGE_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_FILTER_LOWER_BOUND): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step="any", mode=NumberSelectorMode.BOX)
|
||||
),
|
||||
vol.Optional(CONF_FILTER_UPPER_BOUND): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step="any", mode=NumberSelectorMode.BOX)
|
||||
),
|
||||
}
|
||||
).extend(BASE_OPTIONS_SCHEMA)
|
||||
|
||||
TIME_SMA_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_TIME_SMA_TYPE, default=TIME_SMA_LAST): SelectSelector(
|
||||
SelectSelectorConfig(
|
||||
options=[TIME_SMA_LAST],
|
||||
mode=SelectSelectorMode.DROPDOWN,
|
||||
translation_key=CONF_TIME_SMA_TYPE,
|
||||
)
|
||||
),
|
||||
vol.Required(CONF_FILTER_WINDOW_SIZE): DurationSelector(
|
||||
DurationSelectorConfig(enable_day=False, allow_negative=False)
|
||||
),
|
||||
}
|
||||
).extend(BASE_OPTIONS_SCHEMA)
|
||||
|
||||
THROTTLE_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Optional(
|
||||
CONF_FILTER_WINDOW_SIZE, default=DEFAULT_WINDOW_SIZE
|
||||
): NumberSelector(
|
||||
NumberSelectorConfig(min=0, step=1, mode=NumberSelectorMode.BOX)
|
||||
),
|
||||
}
|
||||
).extend(BASE_OPTIONS_SCHEMA)
|
||||
|
||||
TIME_THROTTLE_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_FILTER_WINDOW_SIZE): DurationSelector(
|
||||
DurationSelectorConfig(enable_day=False, allow_negative=False)
|
||||
),
|
||||
}
|
||||
).extend(BASE_OPTIONS_SCHEMA)
|
||||
|
||||
CONFIG_FLOW = {
|
||||
"user": SchemaFlowFormStep(
|
||||
schema=DATA_SCHEMA_SETUP,
|
||||
next_step="options",
|
||||
next_step=get_next_step,
|
||||
),
|
||||
"options": SchemaFlowFormStep(
|
||||
schema=get_options_schema,
|
||||
validate_user_input=validate_options,
|
||||
"lowpass": SchemaFlowFormStep(
|
||||
schema=LOWPASS_SCHEMA, validate_user_input=validate_options
|
||||
),
|
||||
"outlier": SchemaFlowFormStep(
|
||||
schema=OUTLIER_SCHEMA, validate_user_input=validate_options
|
||||
),
|
||||
"range": SchemaFlowFormStep(
|
||||
schema=RANGE_SCHEMA, validate_user_input=validate_options
|
||||
),
|
||||
"time_simple_moving_average": SchemaFlowFormStep(
|
||||
schema=TIME_SMA_SCHEMA, validate_user_input=validate_options
|
||||
),
|
||||
"throttle": SchemaFlowFormStep(
|
||||
schema=THROTTLE_SCHEMA, validate_user_input=validate_options
|
||||
),
|
||||
"time_throttle": SchemaFlowFormStep(
|
||||
schema=TIME_THROTTLE_SCHEMA, validate_user_input=validate_options
|
||||
),
|
||||
}
|
||||
OPTIONS_FLOW = {
|
||||
"init": SchemaFlowFormStep(
|
||||
get_options_schema,
|
||||
validate_user_input=validate_options,
|
||||
schema=None,
|
||||
next_step=get_next_step,
|
||||
),
|
||||
"lowpass": SchemaFlowFormStep(
|
||||
schema=LOWPASS_SCHEMA, validate_user_input=validate_options
|
||||
),
|
||||
"outlier": SchemaFlowFormStep(
|
||||
schema=OUTLIER_SCHEMA, validate_user_input=validate_options
|
||||
),
|
||||
"range": SchemaFlowFormStep(
|
||||
schema=RANGE_SCHEMA, validate_user_input=validate_options
|
||||
),
|
||||
"time_simple_moving_average": SchemaFlowFormStep(
|
||||
schema=TIME_SMA_SCHEMA, validate_user_input=validate_options
|
||||
),
|
||||
"throttle": SchemaFlowFormStep(
|
||||
schema=THROTTLE_SCHEMA, validate_user_input=validate_options
|
||||
),
|
||||
"time_throttle": SchemaFlowFormStep(
|
||||
schema=TIME_THROTTLE_SCHEMA, validate_user_input=validate_options
|
||||
),
|
||||
}
|
||||
|
||||
|
|
|
@ -17,26 +17,79 @@
|
|||
"filter": "Select filter to configure."
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"outlier": {
|
||||
"description": "Read the documentation for further details on how to configure the filter sensor using these options.",
|
||||
"data": {
|
||||
"window_size": "Window size",
|
||||
"precision": "Precision",
|
||||
"radius": "Radius",
|
||||
"time_constant": "Time constant",
|
||||
"lower_bound": "Lower bound",
|
||||
"upper_bound": "Upper bound",
|
||||
"type": "Type"
|
||||
"radius": "Radius"
|
||||
},
|
||||
"data_description": {
|
||||
"window_size": "Size of the window of previous states.",
|
||||
"precision": "Defines the number of decimal places of the calculated sensor value.",
|
||||
"radius": "Band radius from median of previous states.",
|
||||
"time_constant": "Loosely relates to the amount of time it takes for a state to influence the output.",
|
||||
"radius": "Band radius from median of previous states."
|
||||
}
|
||||
},
|
||||
"lowpass": {
|
||||
"description": "[%key:component::filter::config::step::outlier::description%]",
|
||||
"data": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data::precision%]",
|
||||
"time_constant": "Time constant"
|
||||
},
|
||||
"data_description": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data_description::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data_description::precision%]",
|
||||
"time_constant": "Loosely relates to the amount of time it takes for a state to influence the output."
|
||||
}
|
||||
},
|
||||
"range": {
|
||||
"description": "[%key:component::filter::config::step::outlier::description%]",
|
||||
"data": {
|
||||
"precision": "[%key:component::filter::config::step::outlier::data::precision%]",
|
||||
"lower_bound": "Lower bound",
|
||||
"upper_bound": "Upper bound"
|
||||
},
|
||||
"data_description": {
|
||||
"precision": "[%key:component::filter::config::step::outlier::data_description::precision%]",
|
||||
"lower_bound": "Lower bound for filter range.",
|
||||
"upper_bound": "Upper bound for filter range.",
|
||||
"upper_bound": "Upper bound for filter range."
|
||||
}
|
||||
},
|
||||
"time_simple_moving_average": {
|
||||
"description": "[%key:component::filter::config::step::outlier::description%]",
|
||||
"data": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data::precision%]",
|
||||
"type": "Type"
|
||||
},
|
||||
"data_description": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data_description::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data_description::precision%]",
|
||||
"type": "Defines the type of Simple Moving Average."
|
||||
}
|
||||
},
|
||||
"throttle": {
|
||||
"description": "[%key:component::filter::config::step::outlier::description%]",
|
||||
"data": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data::precision%]"
|
||||
},
|
||||
"data_description": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data_description::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data_description::precision%]"
|
||||
}
|
||||
},
|
||||
"time_throttle": {
|
||||
"description": "[%key:component::filter::config::step::outlier::description%]",
|
||||
"data": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data::precision%]"
|
||||
},
|
||||
"data_description": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data_description::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data_description::precision%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -45,25 +98,78 @@
|
|||
"already_configured": "[%key:common::config_flow::abort::already_configured_account%]"
|
||||
},
|
||||
"step": {
|
||||
"init": {
|
||||
"description": "[%key:component::filter::config::step::options::description%]",
|
||||
"outlier": {
|
||||
"description": "[%key:component::filter::config::step::outlier::description%]",
|
||||
"data": {
|
||||
"window_size": "[%key:component::filter::config::step::options::data::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::options::data::precision%]",
|
||||
"radius": "[%key:component::filter::config::step::options::data::radius%]",
|
||||
"time_constant": "[%key:component::filter::config::step::options::data::time_constant%]",
|
||||
"lower_bound": "[%key:component::filter::config::step::options::data::lower_bound%]",
|
||||
"upper_bound": "[%key:component::filter::config::step::options::data::upper_bound%]",
|
||||
"type": "[%key:component::filter::config::step::options::data::type%]"
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data::precision%]",
|
||||
"radius": "[%key:component::filter::config::step::outlier::data::radius%]"
|
||||
},
|
||||
"data_description": {
|
||||
"window_size": "[%key:component::filter::config::step::options::data_description::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::options::data_description::precision%]",
|
||||
"radius": "[%key:component::filter::config::step::options::data_description::radius%]",
|
||||
"time_constant": "[%key:component::filter::config::step::options::data_description::time_constant%]",
|
||||
"lower_bound": "[%key:component::filter::config::step::options::data_description::lower_bound%]",
|
||||
"upper_bound": "[%key:component::filter::config::step::options::data_description::upper_bound%]",
|
||||
"type": "[%key:component::filter::config::step::options::data_description::type%]"
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data_description::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data_description::precision%]",
|
||||
"radius": "[%key:component::filter::config::step::outlier::data_description::radius%]"
|
||||
}
|
||||
},
|
||||
"lowpass": {
|
||||
"description": "[%key:component::filter::config::step::outlier::description%]",
|
||||
"data": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data::precision%]",
|
||||
"time_constant": "[%key:component::filter::config::step::lowpass::data::time_constant%]"
|
||||
},
|
||||
"data_description": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data_description::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data_description::precision%]",
|
||||
"time_constant": "[%key:component::filter::config::step::lowpass::data_description::time_constant%]"
|
||||
}
|
||||
},
|
||||
"range": {
|
||||
"description": "[%key:component::filter::config::step::outlier::description%]",
|
||||
"data": {
|
||||
"precision": "[%key:component::filter::config::step::outlier::data::precision%]",
|
||||
"lower_bound": "[%key:component::filter::config::step::range::data::lower_bound%]",
|
||||
"upper_bound": "[%key:component::filter::config::step::range::data::upper_bound%]"
|
||||
},
|
||||
"data_description": {
|
||||
"precision": "[%key:component::filter::config::step::outlier::data_description::precision%]",
|
||||
"lower_bound": "[%key:component::filter::config::step::range::data_description::lower_bound%]",
|
||||
"upper_bound": "[%key:component::filter::config::step::range::data_description::upper_bound%]"
|
||||
}
|
||||
},
|
||||
"time_simple_moving_average": {
|
||||
"description": "[%key:component::filter::config::step::outlier::description%]",
|
||||
"data": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data::precision%]",
|
||||
"type": "[%key:component::filter::config::step::time_simple_moving_average::data::type%]"
|
||||
},
|
||||
"data_description": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data_description::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data_description::precision%]",
|
||||
"type": "[%key:component::filter::config::step::time_simple_moving_average::data_description::type%]"
|
||||
}
|
||||
},
|
||||
"throttle": {
|
||||
"description": "[%key:component::filter::config::step::outlier::description%]",
|
||||
"data": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data::precision%]"
|
||||
},
|
||||
"data_description": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data_description::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data_description::precision%]"
|
||||
}
|
||||
},
|
||||
"time_throttle": {
|
||||
"description": "[%key:component::filter::config::step::outlier::description%]",
|
||||
"data": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data::precision%]"
|
||||
},
|
||||
"data_description": {
|
||||
"window_size": "[%key:component::filter::config::step::outlier::data_description::window_size%]",
|
||||
"precision": "[%key:component::filter::config::step::outlier::data_description::precision%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ async def test_options_flow(
|
|||
result = await hass.config_entries.options.async_init(loaded_entry.entry_id)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "init"
|
||||
assert result["step_id"] == "outlier"
|
||||
|
||||
result = await hass.config_entries.options.async_configure(
|
||||
result["flow_id"],
|
||||
|
|
Loading…
Add table
Reference in a new issue