Skip to content

Commit 16d14b4

Browse files
Add state from to
1 parent ede41b0 commit 16d14b4

3 files changed

Lines changed: 80 additions & 35 deletions

File tree

custom_components/label_state/config_flow.py

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
from __future__ import annotations
44

55
from collections.abc import Callable, Coroutine, Mapping
6+
from enum import StrEnum
67
from typing import Any, cast
78

89
import voluptuous as vol
9-
from homeassistant.const import CONF_TYPE
1010
from homeassistant.helpers import selector
1111
from homeassistant.helpers.schema_config_entry_flow import (
1212
SchemaCommonFlowHandler,
@@ -15,7 +15,27 @@
1515
SchemaFlowMenuStep,
1616
)
1717

18-
from .const import CONF_LABEL, CONF_LOWER_LIMIT, CONF_STATE, CONF_UPPER_LIMIT, DOMAIN
18+
from .const import (
19+
CONF_LABEL,
20+
CONF_LOWER_LIMIT,
21+
CONF_STATE_FROM,
22+
CONF_STATE_TO,
23+
CONF_UPPER_LIMIT,
24+
DOMAIN,
25+
)
26+
27+
STATE_TYPES = [
28+
"numeric_state",
29+
"state",
30+
]
31+
32+
33+
class StateTypes(StrEnum):
34+
"""Available state types."""
35+
36+
NUMERIC_STATE = "numeric_state"
37+
STATE = "state"
38+
1939

2040
OPTIONS_SCHEMA_NUMERIC_STATE = vol.Schema(
2141
{
@@ -36,7 +56,8 @@
3656
OPTIONS_SCHEMA_STATE = vol.Schema(
3757
{
3858
vol.Required(CONF_LABEL): selector.LabelSelector(),
39-
vol.Required(CONF_STATE): selector.TextSelector(),
59+
vol.Optional(CONF_STATE_FROM): selector.TextSelector(),
60+
vol.Optional(CONF_STATE_TO): selector.TextSelector(),
4061
}
4162
)
4263

@@ -53,10 +74,9 @@
5374
).extend(OPTIONS_SCHEMA_STATE.schema)
5475

5576

56-
LABEL_TYPES = [
57-
"numeric_state",
58-
"state",
59-
]
77+
async def choose_options_step(options: dict[str, Any]) -> str:
78+
"""Return next step_id for options flow according to label_type."""
79+
return cast(str, options["state_type"])
6080

6181

6282
def _validate_upper_or_lower(options: dict[str, Any]) -> None:
@@ -68,56 +88,63 @@ def _validate_upper_or_lower(options: dict[str, Any]) -> None:
6888
raise vol.Invalid("An upper or lower limit must be set")
6989

7090

91+
def _validate_from_or_to(options: dict[str, Any]) -> None:
92+
"""Validate upper or lower limit."""
93+
state_from = options.get(CONF_STATE_FROM)
94+
state_to = options.get(CONF_STATE_TO)
95+
96+
if state_from is None and state_to is None:
97+
raise vol.Invalid("An from or to must be specified")
98+
99+
71100
def validate_user_input(
72-
label_type: str,
101+
state_type: str,
73102
) -> Callable[
74103
[SchemaCommonFlowHandler, dict[str, Any]],
75104
Coroutine[Any, Any, dict[str, Any]],
76105
]:
77106
"""Do post validation of user input.
78107
79108
For numeric state: Validate an upper or lower limit is set.
80-
For all domaines: Set label type.
109+
For state: Validate a from or to is set.
110+
For all domaines: Set state type.
81111
"""
82112

83113
async def _validate_user_input(
84114
_: SchemaCommonFlowHandler,
85115
user_input: dict[str, Any],
86116
) -> dict[str, Any]:
87117
"""Validate based on label type and add label type to user input."""
88-
if label_type == "numeric_state":
118+
if state_type == StateTypes.NUMERIC_STATE:
89119
_validate_upper_or_lower(user_input)
90-
return {"label_type": label_type} | user_input
120+
if state_type == StateTypes.STATE:
121+
_validate_from_or_to(user_input)
122+
return {"state_type": state_type} | user_input
91123

92124
return _validate_user_input
93125

94126

95127
CONFIG_FLOW = {
96-
"user": SchemaFlowMenuStep(LABEL_TYPES),
97-
"numeric_state": SchemaFlowFormStep(
128+
"user": SchemaFlowMenuStep(STATE_TYPES),
129+
StateTypes.NUMERIC_STATE: SchemaFlowFormStep(
98130
CONFIG_SCHEMA_NUMERIC_STATE,
99-
validate_user_input=validate_user_input("numeric_state"),
131+
validate_user_input=validate_user_input(StateTypes.NUMERIC_STATE),
100132
),
101-
"state": SchemaFlowFormStep(
133+
StateTypes.STATE: SchemaFlowFormStep(
102134
CONFIG_SCHEMA_STATE,
103-
validate_user_input=validate_user_input("state"),
135+
validate_user_input=validate_user_input(StateTypes.STATE),
104136
),
105137
}
106138

107139

108-
async def choose_options_step(options: dict[str, Any]) -> str:
109-
"""Return next step_id for options flow according to label_type."""
110-
return cast(str, options["label_type"])
111-
112-
113140
OPTIONS_FLOW = {
114141
"init": SchemaFlowFormStep(next_step=choose_options_step),
115-
"numeric_state": SchemaFlowFormStep(
142+
StateTypes.NUMERIC_STATE: SchemaFlowFormStep(
116143
OPTIONS_SCHEMA_NUMERIC_STATE,
117-
validate_user_input=validate_user_input("numeric_state"),
144+
validate_user_input=validate_user_input(StateTypes.NUMERIC_STATE),
118145
),
119-
"state": SchemaFlowFormStep(
120-
OPTIONS_SCHEMA_STATE, validate_user_input=validate_user_input("state")
146+
StateTypes.STATE: SchemaFlowFormStep(
147+
OPTIONS_SCHEMA_STATE, validate_user_input=validate_user_input(StateTypes.STATE)
121148
),
122149
}
123150

custom_components/label_state/const.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
PLATFORMS = [Platform.SENSOR]
2424

2525
CONF_LABEL = "label"
26-
CONF_STATE = "state"
26+
CONF_STATE_FROM = "state_from"
27+
CONF_STATE_TO = "state_to"
2728
CONF_LOWER_LIMIT = "lower_limit"
2829
CONF_UPPER_LIMIT = "upper_limit"
2930

custom_components/label_state/translations/en.json

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
"config": {
33
"step": {
44
"user": {
5-
"title": "Add Label State",
5+
"title": "Label State",
66
"description": "Create a binary sensor that is true if any sensor with a label meets the criteria.",
77
"menu_options": {
88
"numeric_state": "Numeric state",
99
"state": "State"
1010
}
1111
},
1212
"numeric_state": {
13-
"title": "Add Label State",
13+
"title": "Label State",
1414
"description": "Create a binary sensor that is true if any sensor with a label meets the criteria.",
1515
"data": {
1616
"label": "Label",
@@ -19,27 +19,44 @@
1919
"upper_limit": "Upper limit"
2020
},
2121
"data_description": {
22-
"lower_limit": "Above",
23-
"upper_limit": "Below"
22+
"lower_limit": "Sensor will be true when any labelled sensor goes above this value",
23+
"upper_limit": "Sensor will be true when any labelled sensor goes below this value"
2424
}
2525
},
2626
"state": {
27-
"title": "Add Label State",
27+
"title": "Label State",
2828
"description": "Create a binary sensor that is true if any sensor with a label meets the criteria.",
2929
"data": {
3030
"label": "Label",
3131
"name": "Name",
32-
"state": "State"
32+
"state_from": "From",
33+
"state_to": "To"
3334
}
3435
}
3536
}
3637
},
3738
"options": {
3839
"step": {
39-
"init": {
40+
"numeric_state": {
41+
"title": "Label State",
42+
"description": "Create a binary sensor that is true if any sensor with a label meets the criteria.",
43+
"data": {
44+
"label": "Label",
45+
"lower_limit": "Lower limit",
46+
"upper_limit": "Upper limit"
47+
},
48+
"data_description": {
49+
"lower_limit": "Sensor will be true when any labelled sensor goes above this value",
50+
"upper_limit": "Sensor will be true when any labelled sensor goes below this value"
51+
}
52+
},
53+
"state": {
54+
"title": "Label State",
55+
"description": "Create a binary sensor that is true if any sensor with a label meets the criteria.",
4056
"data": {
41-
"entity_id": "Input entity",
42-
"type": "Statistic characteristic"
57+
"label": "Label",
58+
"state_from": "From",
59+
"state_to": "To"
4360
}
4461
}
4562
}

0 commit comments

Comments
 (0)