1 """Support to enter a value into a text box."""
3 from __future__
import annotations
6 from typing
import Any, Self
8 import voluptuous
as vol
17 CONF_UNIT_OF_MEASUREMENT,
29 _LOGGER = logging.getLogger(__name__)
33 CONF_INITIAL =
"initial"
38 CONF_PATTERN =
"pattern"
42 MODE_PASSWORD =
"password"
44 ATTR_VALUE = CONF_VALUE
47 ATTR_PATTERN = CONF_PATTERN
49 SERVICE_SET_VALUE =
"set_value"
53 STORAGE_FIELDS: VolDictType = {
54 vol.Required(CONF_NAME): vol.All(str, vol.Length(min=1)),
55 vol.Optional(CONF_MIN, default=CONF_MIN_VALUE): vol.Coerce(int),
56 vol.Optional(CONF_MAX, default=CONF_MAX_VALUE): vol.Coerce(int),
57 vol.Optional(CONF_INITIAL,
""): cv.string,
58 vol.Optional(CONF_ICON): cv.icon,
59 vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
60 vol.Optional(CONF_PATTERN): cv.string,
61 vol.Optional(CONF_MODE, default=MODE_TEXT): vol.In([MODE_TEXT, MODE_PASSWORD]),
66 """Configure validation helper for input box (voluptuous)."""
67 minimum: int = config[CONF_MIN]
68 maximum: int = config[CONF_MAX]
71 f
"Max len ({minimum}) is not greater than min len ({maximum})"
73 state: str |
None = config.get(CONF_INITIAL)
74 if state
is not None and (len(state) < minimum
or len(state) > maximum):
76 f
"Initial value {state} length not in range {minimum}-{maximum}"
81 CONFIG_SCHEMA = vol.Schema(
83 DOMAIN: cv.schema_with_slug_keys(
85 lambda value: value
or {},
87 vol.Optional(CONF_NAME): cv.string,
88 vol.Optional(CONF_MIN, default=CONF_MIN_VALUE): vol.Coerce(int),
89 vol.Optional(CONF_MAX, default=CONF_MAX_VALUE): vol.Coerce(int),
90 vol.Optional(CONF_INITIAL): cv.string,
91 vol.Optional(CONF_ICON): cv.icon,
92 vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
93 vol.Optional(CONF_PATTERN): cv.string,
94 vol.Optional(CONF_MODE, default=MODE_TEXT): vol.In(
95 [MODE_TEXT, MODE_PASSWORD]
102 extra=vol.ALLOW_EXTRA,
104 RELOAD_SERVICE_SCHEMA = vol.Schema({})
107 async
def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
108 """Set up an input text."""
109 component = EntityComponent[InputText](_LOGGER, DOMAIN, hass)
111 id_manager = collection.IDManager()
113 yaml_collection = collection.YamlCollection(
114 logging.getLogger(f
"{__name__}.yaml_collection"), id_manager
116 collection.sync_entity_lifecycle(
117 hass, DOMAIN, DOMAIN, component, yaml_collection, InputText
121 Store(hass, STORAGE_VERSION, STORAGE_KEY),
124 collection.sync_entity_lifecycle(
125 hass, DOMAIN, DOMAIN, component, storage_collection, InputText
128 await yaml_collection.async_load(
129 [{CONF_ID: id_, **(conf
or {})}
for id_, conf
in config.get(DOMAIN, {}).items()]
131 await storage_collection.async_load()
133 collection.DictStorageCollectionWebsocket(
134 storage_collection, DOMAIN, DOMAIN, STORAGE_FIELDS, STORAGE_FIELDS
137 async
def reload_service_handler(service_call: ServiceCall) ->
None:
138 """Reload yaml entities."""
139 conf = await component.async_prepare_reload(skip_reset=
True)
142 await yaml_collection.async_load(
143 [{CONF_ID: id_, **(cfg
or {})}
for id_, cfg
in conf.get(DOMAIN, {}).items()]
150 reload_service_handler,
151 schema=RELOAD_SERVICE_SCHEMA,
154 component.async_register_entity_service(
155 SERVICE_SET_VALUE, {vol.Required(ATTR_VALUE): cv.string},
"async_set_value"
162 """Input storage based collection."""
164 CREATE_UPDATE_SCHEMA = vol.Schema(vol.All(STORAGE_FIELDS, _cv_input_text))
167 """Validate the config is valid."""
172 """Suggest an ID based on the config."""
173 return info[CONF_NAME]
176 self, item: dict[str, Any], update_data: dict[str, Any]
178 """Return a new updated data object."""
180 return {CONF_ID: item[CONF_ID]} | update_data
184 """Represent a text box."""
186 _unrecorded_attributes = frozenset(
187 {ATTR_EDITABLE, ATTR_MAX, ATTR_MIN, ATTR_MODE, ATTR_PATTERN}
190 _attr_should_poll =
False
191 _current_value: str |
None
195 """Initialize a text input."""
201 """Return entity instance initialized from storage."""
202 input_text: Self = cls(config)
203 input_text.editable =
True
208 """Return entity instance initialized from yaml."""
209 input_text: Self = cls(config)
210 input_text.entity_id = f
"{DOMAIN}.{config[CONF_ID]}"
211 input_text.editable =
False
216 """Return the name of the text input entity."""
221 """Return the icon to be used for this entity."""
226 """Return max len of the text."""
227 return self.
_config_config[CONF_MAX]
231 """Return min len of the text."""
232 return self.
_config_config[CONF_MIN]
236 """Return the state of the component."""
241 """Return the unit the value is expressed in."""
242 return self.
_config_config.
get(CONF_UNIT_OF_MEASUREMENT)
246 """Return unique id for the entity."""
247 return self.
_config_config[CONF_ID]
251 """Return the state attributes."""
253 ATTR_EDITABLE: self.editable,
256 ATTR_PATTERN: self.
_config_config.
get(CONF_PATTERN),
257 ATTR_MODE: self.
_config_config[CONF_MODE],
261 """Run when entity about to be added to hass."""
267 value = state.state
if state
else None
270 if value
is not None and self.
_minimum_minimum <= len(value) <= self.
_maximum_maximum:
274 """Select new value."""
275 if len(value) < self.
_minimum_minimum
or len(value) > self.
_maximum_maximum:
277 "Invalid value: %s (length range %s - %s)",
287 """Handle when the config is updated."""
dict[str, Any] _process_create_data(self, dict[str, Any] data)
str _get_suggested_id(self, dict[str, Any] info)
dict[str, Any] _update_data(self, dict[str, Any] item, dict[str, Any] update_data)
None async_set_value(self, str value)
None async_added_to_hass(self)
Self from_yaml(cls, ConfigType config)
Self from_storage(cls, ConfigType config)
str|None unit_of_measurement(self)
None __init__(self, ConfigType config)
dict[str, Any] extra_state_attributes(self)
None async_update_config(self, ConfigType config)
None async_write_ha_state(self)
State|None async_get_last_state(self)
web.Response get(self, web.Request request, str config_key)
bool async_setup(HomeAssistant hass, ConfigType config)
dict[str, Any] _cv_input_text(dict[str, Any] config)
None async_register_admin_service(HomeAssistant hass, str domain, str service, Callable[[ServiceCall], Awaitable[None]|None] service_func, VolSchemaType schema=vol.Schema({}, extra=vol.PREVENT_EXTRA))