Fix configuration
This commit is contained in:
@@ -162,7 +162,26 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
if COMES_FROM in self._infos:
|
if COMES_FROM in self._infos:
|
||||||
del self._infos[COMES_FROM]
|
del self._infos[COMES_FROM]
|
||||||
|
|
||||||
async def validate_input(self, data: dict) -> None:
|
def check_sonoff_trvzb_nb_entities(self, data: dict) -> bool:
|
||||||
|
"""Check the number of entities for Sonoff TRVZB"""
|
||||||
|
ret = True
|
||||||
|
if (
|
||||||
|
self._infos.get(CONF_SONOFF_TRZB_MODE)
|
||||||
|
and data.get(CONF_OFFSET_CALIBRATION_LIST) is not None
|
||||||
|
):
|
||||||
|
nb_unders = len(self._infos.get(CONF_UNDERLYING_LIST))
|
||||||
|
nb_offset = len(data.get(CONF_OFFSET_CALIBRATION_LIST))
|
||||||
|
nb_opening = len(data.get(CONF_OPENING_DEGREE_LIST))
|
||||||
|
nb_closing = len(data.get(CONF_CLOSING_DEGREE_LIST))
|
||||||
|
if (
|
||||||
|
nb_unders != nb_offset
|
||||||
|
or nb_unders != nb_opening
|
||||||
|
or nb_unders != nb_closing
|
||||||
|
):
|
||||||
|
ret = False
|
||||||
|
return ret
|
||||||
|
|
||||||
|
async def validate_input(self, data: dict, step_id) -> None:
|
||||||
"""Validate the user input allows us to connect.
|
"""Validate the user input allows us to connect.
|
||||||
|
|
||||||
Data has the keys from STEP_*_DATA_SCHEMA with values provided by the user.
|
Data has the keys from STEP_*_DATA_SCHEMA with values provided by the user.
|
||||||
@@ -178,6 +197,9 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
CONF_POWER_SENSOR,
|
CONF_POWER_SENSOR,
|
||||||
CONF_MAX_POWER_SENSOR,
|
CONF_MAX_POWER_SENSOR,
|
||||||
CONF_PRESENCE_SENSOR,
|
CONF_PRESENCE_SENSOR,
|
||||||
|
CONF_OFFSET_CALIBRATION_LIST,
|
||||||
|
CONF_OPENING_DEGREE_LIST,
|
||||||
|
CONF_CLOSING_DEGREE_LIST,
|
||||||
]:
|
]:
|
||||||
d = data.get(conf, None) # pylint: disable=invalid-name
|
d = data.get(conf, None) # pylint: disable=invalid-name
|
||||||
if not isinstance(d, list):
|
if not isinstance(d, list):
|
||||||
@@ -235,6 +257,11 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
except ServiceConfigurationError as err:
|
except ServiceConfigurationError as err:
|
||||||
raise ServiceConfigurationError(conf) from err
|
raise ServiceConfigurationError(conf) from err
|
||||||
|
|
||||||
|
# Check that the number of offet_calibration and opening_degree and closing_degree are equals
|
||||||
|
# to the number of underlying entities
|
||||||
|
if not self.check_sonoff_trvzb_nb_entities(data):
|
||||||
|
raise SonoffTRVZBNbEntitiesIncorrect()
|
||||||
|
|
||||||
def check_config_complete(self, infos) -> bool:
|
def check_config_complete(self, infos) -> bool:
|
||||||
"""True if the config is now complete (ie all mandatory attributes are set)"""
|
"""True if the config is now complete (ie all mandatory attributes are set)"""
|
||||||
is_central_config = (
|
is_central_config = (
|
||||||
@@ -330,6 +357,9 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
if not self.check_sonoff_trvzb_nb_entities(infos):
|
||||||
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def merge_user_input(self, data_schema: vol.Schema, user_input: dict):
|
def merge_user_input(self, data_schema: vol.Schema, user_input: dict):
|
||||||
@@ -359,7 +389,7 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
if user_input is not None:
|
if user_input is not None:
|
||||||
defaults.update(user_input or {})
|
defaults.update(user_input or {})
|
||||||
try:
|
try:
|
||||||
await self.validate_input(user_input)
|
await self.validate_input(user_input, step_id)
|
||||||
except UnknownEntity as err:
|
except UnknownEntity as err:
|
||||||
errors[str(err)] = "unknown_entity"
|
errors[str(err)] = "unknown_entity"
|
||||||
except WindowOpenDetectionMethod as err:
|
except WindowOpenDetectionMethod as err:
|
||||||
@@ -370,6 +400,8 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
errors[str(err)] = "service_configuration_format"
|
errors[str(err)] = "service_configuration_format"
|
||||||
except ConfigurationNotCompleteError as err:
|
except ConfigurationNotCompleteError as err:
|
||||||
errors["base"] = "configuration_not_complete"
|
errors["base"] = "configuration_not_complete"
|
||||||
|
except SonoffTRVZBNbEntitiesIncorrect as err:
|
||||||
|
errors["base"] = "sonoff_trvzb_nb_entities_incorrect"
|
||||||
except Exception: # pylint: disable=broad-except
|
except Exception: # pylint: disable=broad-except
|
||||||
_LOGGER.exception("Unexpected exception")
|
_LOGGER.exception("Unexpected exception")
|
||||||
errors["base"] = "unknown"
|
errors["base"] = "unknown"
|
||||||
@@ -528,6 +560,24 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
"""Handle the Type flow steps"""
|
"""Handle the Type flow steps"""
|
||||||
_LOGGER.debug("Into ConfigFlow.async_step_type user_input=%s", user_input)
|
_LOGGER.debug("Into ConfigFlow.async_step_type user_input=%s", user_input)
|
||||||
|
|
||||||
|
if (
|
||||||
|
self._infos[CONF_THERMOSTAT_TYPE] == CONF_THERMOSTAT_CLIMATE
|
||||||
|
and user_input is not None
|
||||||
|
and not user_input.get(CONF_SONOFF_TRZB_MODE)
|
||||||
|
):
|
||||||
|
# Remove TPI info
|
||||||
|
for key in [
|
||||||
|
PROPORTIONAL_FUNCTION_TPI,
|
||||||
|
CONF_PROP_FUNCTION,
|
||||||
|
CONF_TPI_COEF_INT,
|
||||||
|
CONF_TPI_COEF_EXT,
|
||||||
|
CONF_OFFSET_CALIBRATION_LIST,
|
||||||
|
CONF_OPENING_DEGREE_LIST,
|
||||||
|
CONF_CLOSING_DEGREE_LIST,
|
||||||
|
]:
|
||||||
|
if self._infos.get(key):
|
||||||
|
del self._infos[key]
|
||||||
|
|
||||||
if self._infos[CONF_THERMOSTAT_TYPE] == CONF_THERMOSTAT_SWITCH:
|
if self._infos[CONF_THERMOSTAT_TYPE] == CONF_THERMOSTAT_SWITCH:
|
||||||
return await self.generic_step(
|
return await self.generic_step(
|
||||||
"type", STEP_THERMOSTAT_SWITCH, user_input, self.async_step_menu
|
"type", STEP_THERMOSTAT_SWITCH, user_input, self.async_step_menu
|
||||||
|
|||||||
@@ -511,6 +511,11 @@ class ConfigurationNotCompleteError(HomeAssistantError):
|
|||||||
"""Error the configuration is not complete"""
|
"""Error the configuration is not complete"""
|
||||||
|
|
||||||
|
|
||||||
|
class SonoffTRVZBNbEntitiesIncorrect(HomeAssistantError):
|
||||||
|
"""Error to indicate there is an error in the configuration of the Sonoff TRVZB.
|
||||||
|
The number of specific entities is incorrect."""
|
||||||
|
|
||||||
|
|
||||||
class overrides: # pylint: disable=invalid-name
|
class overrides: # pylint: disable=invalid-name
|
||||||
"""An annotation to inform overrides"""
|
"""An annotation to inform overrides"""
|
||||||
|
|
||||||
|
|||||||
@@ -487,7 +487,8 @@
|
|||||||
"unknown_entity": "Unknown entity id",
|
"unknown_entity": "Unknown entity id",
|
||||||
"window_open_detection_method": "Only one window open detection method should be used. Use either window sensor or automatic detection through temperature threshold but not both",
|
"window_open_detection_method": "Only one window open detection method should be used. Use either window sensor or automatic detection through temperature threshold but not both",
|
||||||
"no_central_config": "You cannot check 'use central configuration' because no central configuration was found. You need to create a Versatile Thermostat of type 'Central Configuration' to use it.",
|
"no_central_config": "You cannot check 'use central configuration' because no central configuration was found. You need to create a Versatile Thermostat of type 'Central Configuration' to use it.",
|
||||||
"service_configuration_format": "The format of the service configuration is wrong"
|
"service_configuration_format": "The format of the service configuration is wrong",
|
||||||
|
"sonoff_trvzb_nb_entities_incorrect": "The number of specific entities for Sonoff TRVZB should be equal to the number of underlyings"
|
||||||
},
|
},
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "Device is already configured"
|
"already_configured": "Device is already configured"
|
||||||
|
|||||||
@@ -966,7 +966,7 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
|
|||||||
if not continu:
|
if not continu:
|
||||||
return ret
|
return ret
|
||||||
else:
|
else:
|
||||||
_LOGGER.debug("%s - auto start/stop is disabled")
|
_LOGGER.debug("%s - auto start/stop is disabled", self)
|
||||||
|
|
||||||
# Continue the normal async_control_heating
|
# Continue the normal async_control_heating
|
||||||
|
|
||||||
|
|||||||
@@ -487,7 +487,8 @@
|
|||||||
"unknown_entity": "Unknown entity id",
|
"unknown_entity": "Unknown entity id",
|
||||||
"window_open_detection_method": "Only one window open detection method should be used. Use either window sensor or automatic detection through temperature threshold but not both",
|
"window_open_detection_method": "Only one window open detection method should be used. Use either window sensor or automatic detection through temperature threshold but not both",
|
||||||
"no_central_config": "You cannot check 'use central configuration' because no central configuration was found. You need to create a Versatile Thermostat of type 'Central Configuration' to use it.",
|
"no_central_config": "You cannot check 'use central configuration' because no central configuration was found. You need to create a Versatile Thermostat of type 'Central Configuration' to use it.",
|
||||||
"service_configuration_format": "The format of the service configuration is wrong"
|
"service_configuration_format": "The format of the service configuration is wrong",
|
||||||
|
"sonoff_trvzb_nb_entities_incorrect": "The number of specific entities for Sonoff TRVZB should be equal to the number of underlyings"
|
||||||
},
|
},
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "Device is already configured"
|
"already_configured": "Device is already configured"
|
||||||
|
|||||||
@@ -481,7 +481,8 @@
|
|||||||
"unknown_entity": "entity id inconnu",
|
"unknown_entity": "entity id inconnu",
|
||||||
"window_open_detection_method": "Une seule méthode de détection des ouvertures ouvertes doit être utilisée. Utilisez le détecteur d'ouverture ou les seuils de température mais pas les deux.",
|
"window_open_detection_method": "Une seule méthode de détection des ouvertures ouvertes doit être utilisée. Utilisez le détecteur d'ouverture ou les seuils de température mais pas les deux.",
|
||||||
"no_central_config": "Vous ne pouvez pas cocher 'Utiliser la configuration centrale' car aucune configuration centrale n'a été trouvée. Vous devez créer un Versatile Thermostat de type 'Central Configuration' pour pouvoir l'utiliser.",
|
"no_central_config": "Vous ne pouvez pas cocher 'Utiliser la configuration centrale' car aucune configuration centrale n'a été trouvée. Vous devez créer un Versatile Thermostat de type 'Central Configuration' pour pouvoir l'utiliser.",
|
||||||
"service_configuration_format": "Mauvais format de la configuration du service"
|
"service_configuration_format": "Mauvais format de la configuration du service",
|
||||||
|
"sonoff_trvzb_nb_entities_incorrect": "Le nombre d'entités spécifiques au Sonoff TRVZB doit être égal au nombre d'entité sous-jacentes"
|
||||||
},
|
},
|
||||||
"abort": {
|
"abort": {
|
||||||
"already_configured": "Le device est déjà configuré"
|
"already_configured": "Le device est déjà configuré"
|
||||||
|
|||||||
Reference in New Issue
Block a user