Hugh Saunders bb51837346
Generic Thermostat Add Target Min Max to UI config (#131168)
Currently you can configure the minium and maximum target temperatures
if you create a generic thermostat in YAML. If you create it via the
UI, there is no option to configure them, you just get the climate
domain defaults.

This commit adds minimum and maximum fields to the first stage of the
generic thermostat config flow, so that UI users can also set min and
max.

Min and max are important as usually users want to select target
temperatures within a relatively narrow band, while the defaults create
a wide band. The wide band makes it hard to be accurate enough with the
arc style temperatue selector on the thermostat card.
2024-12-03 22:23:04 +01:00

109 lines
3.2 KiB
Python

"""Config flow for Generic hygrostat."""
from __future__ import annotations
from collections.abc import Mapping
from typing import Any, cast
import voluptuous as vol
from homeassistant.components import fan, switch
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN, SensorDeviceClass
from homeassistant.const import CONF_NAME, DEGREE
from homeassistant.helpers import selector
from homeassistant.helpers.schema_config_entry_flow import (
SchemaConfigFlowHandler,
SchemaFlowFormStep,
)
from .const import (
CONF_AC_MODE,
CONF_COLD_TOLERANCE,
CONF_HEATER,
CONF_HOT_TOLERANCE,
CONF_MAX_TEMP,
CONF_MIN_DUR,
CONF_MIN_TEMP,
CONF_PRESETS,
CONF_SENSOR,
DEFAULT_TOLERANCE,
DOMAIN,
)
OPTIONS_SCHEMA = {
vol.Required(CONF_AC_MODE): selector.BooleanSelector(
selector.BooleanSelectorConfig(),
),
vol.Required(CONF_SENSOR): selector.EntitySelector(
selector.EntitySelectorConfig(
domain=SENSOR_DOMAIN, device_class=SensorDeviceClass.TEMPERATURE
)
),
vol.Required(CONF_HEATER): selector.EntitySelector(
selector.EntitySelectorConfig(domain=[fan.DOMAIN, switch.DOMAIN])
),
vol.Required(
CONF_COLD_TOLERANCE, default=DEFAULT_TOLERANCE
): selector.NumberSelector(
selector.NumberSelectorConfig(
mode=selector.NumberSelectorMode.BOX, unit_of_measurement=DEGREE, step=0.1
)
),
vol.Required(
CONF_HOT_TOLERANCE, default=DEFAULT_TOLERANCE
): selector.NumberSelector(
selector.NumberSelectorConfig(
mode=selector.NumberSelectorMode.BOX, unit_of_measurement=DEGREE, step=0.1
)
),
vol.Optional(CONF_MIN_DUR): selector.DurationSelector(
selector.DurationSelectorConfig(allow_negative=False)
),
vol.Optional(CONF_MIN_TEMP): selector.NumberSelector(
selector.NumberSelectorConfig(
mode=selector.NumberSelectorMode.BOX, unit_of_measurement=DEGREE, step=0.1
)
),
vol.Optional(CONF_MAX_TEMP): selector.NumberSelector(
selector.NumberSelectorConfig(
mode=selector.NumberSelectorMode.BOX, unit_of_measurement=DEGREE, step=0.1
)
),
}
PRESETS_SCHEMA = {
vol.Optional(v): selector.NumberSelector(
selector.NumberSelectorConfig(
mode=selector.NumberSelectorMode.BOX, unit_of_measurement=DEGREE, step=0.1
)
)
for v in CONF_PRESETS.values()
}
CONFIG_SCHEMA = {
vol.Required(CONF_NAME): selector.TextSelector(),
**OPTIONS_SCHEMA,
}
CONFIG_FLOW = {
"user": SchemaFlowFormStep(vol.Schema(CONFIG_SCHEMA), next_step="presets"),
"presets": SchemaFlowFormStep(vol.Schema(PRESETS_SCHEMA)),
}
OPTIONS_FLOW = {
"init": SchemaFlowFormStep(vol.Schema(OPTIONS_SCHEMA), next_step="presets"),
"presets": SchemaFlowFormStep(vol.Schema(PRESETS_SCHEMA)),
}
class ConfigFlowHandler(SchemaConfigFlowHandler, domain=DOMAIN):
"""Handle a config or options flow."""
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"])