Skip to content

Commit

Permalink
ok + testu ok (#729)
Browse files Browse the repository at this point in the history
Co-authored-by: Jean-Marc Collin <jean-marc.collin-extern@renault.com>
  • Loading branch information
jmcollin78 and Jean-Marc Collin authored Dec 21, 2024
1 parent ee42a23 commit 083a3a4
Show file tree
Hide file tree
Showing 10 changed files with 266 additions and 14 deletions.
17 changes: 17 additions & 0 deletions custom_components/versatile_thermostat/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,21 @@ async def validate_input(self, data: dict, step_id) -> None:
if not self.check_valve_regulation_nb_entities(data, step_id):
raise ValveRegulationNbEntitiesIncorrect()

# Check that the min_opening_degrees is correctly set
raw_list = data.get(CONF_MIN_OPENING_DEGREES, None)
if raw_list:
try:
# Validation : Convertir la liste saisie
int_list = [int(x.strip()) for x in raw_list.split(",")]

# Optionnel : Vérifiez des conditions supplémentaires sur la liste
if any(x < 0 for x in int_list):
raise ValueError
except ValueError as exc:
raise ValveRegulationMinOpeningDegreesIncorrect(
CONF_MIN_OPENING_DEGREES
) from exc

def check_config_complete(self, infos) -> bool:
"""True if the config is now complete (ie all mandatory attributes are set)"""
is_central_config = (
Expand Down Expand Up @@ -399,6 +414,8 @@ async def generic_step(self, step_id, data_schema, user_input, next_step_functio
errors["base"] = "configuration_not_complete"
except ValveRegulationNbEntitiesIncorrect as err:
errors["base"] = "valve_regulation_nb_entities_incorrect"
except ValveRegulationMinOpeningDegreesIncorrect as err:
errors[str(err)] = "min_opening_degrees_format"
except Exception: # pylint: disable=broad-except
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
Expand Down
1 change: 1 addition & 0 deletions custom_components/versatile_thermostat/config_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@
PROPORTIONAL_FUNCTION_TPI,
]
),
vol.Optional(CONF_MIN_OPENING_DEGREES, default=""): str,
}
)

Expand Down
5 changes: 5 additions & 0 deletions custom_components/versatile_thermostat/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
CONF_OFFSET_CALIBRATION_LIST = "offset_calibration_entity_ids"
CONF_OPENING_DEGREE_LIST = "opening_degree_entity_ids"
CONF_CLOSING_DEGREE_LIST = "closing_degree_entity_ids"
CONF_MIN_OPENING_DEGREES = "min_opening_degrees"

# Deprecated
CONF_HEATER = "heater_entity_id"
Expand Down Expand Up @@ -552,6 +553,10 @@ class ValveRegulationNbEntitiesIncorrect(HomeAssistantError):
The number of specific entities is incorrect."""


class ValveRegulationMinOpeningDegreesIncorrect(HomeAssistantError):
"""Error to indicate that the minimal opening degrees is not a list of int separated by coma"""


class overrides: # pylint: disable=invalid-name
"""An annotation to inform overrides"""

Expand Down
15 changes: 10 additions & 5 deletions custom_components/versatile_thermostat/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,15 @@
"offset_calibration_entity_ids": "Offset calibration entities",
"opening_degree_entity_ids": "Opening degree entities",
"closing_degree_entity_ids": "Closing degree entities",
"proportional_function": "Algorithm"
"proportional_function": "Algorithm",
"min_opening_degrees": "Min opening degrees"
},
"data_description": {
"offset_calibration_entity_ids": "The list of the 'offset calibration' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"opening_degree_entity_ids": "The list of the 'opening degree' entities. There should be one per underlying climate entities",
"closing_degree_entity_ids": "The list of the 'closing degree' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"proportional_function": "Algorithm to use (TPI is the only one for now)"
"proportional_function": "Algorithm to use (TPI is the only one for now)",
"min_opening_degrees": "A comma seperated list of minimal opening degrees. Default to 0. Example: 20, 25, 30"
}
}
},
Expand Down Expand Up @@ -468,13 +470,15 @@
"offset_calibration_entity_ids": "Offset calibration entities",
"opening_degree_entity_ids": "Opening degree entities",
"closing_degree_entity_ids": "Closing degree entities",
"proportional_function": "Algorithm"
"proportional_function": "Algorithm",
"min_opening_degrees": "Min opening degrees"
},
"data_description": {
"offset_calibration_entity_ids": "The list of the 'offset calibration' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"opening_degree_entity_ids": "The list of the 'opening degree' entities. There should be one per underlying climate entities",
"closing_degree_entity_ids": "The list of the 'closing degree' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"proportional_function": "Algorithm to use (TPI is the only one for now)"
"proportional_function": "Algorithm to use (TPI is the only one for now)",
"min_opening_degrees": "A comma seperated list of minimal opening degrees. Default to 0. Example: 20, 25, 30"
}
}
},
Expand All @@ -484,7 +488,8 @@
"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.",
"service_configuration_format": "The format of the service configuration is wrong",
"valve_regulation_nb_entities_incorrect": "The number of valve entities for valve regulation should be equal to the number of underlyings"
"valve_regulation_nb_entities_incorrect": "The number of valve entities for valve regulation should be equal to the number of underlyings",
"min_opening_degrees_format": "A comma separated list of positive integer is expected. Example: 20, 25, 30"
},
"abort": {
"already_configured": "Device is already configured"
Expand Down
19 changes: 19 additions & 0 deletions custom_components/versatile_thermostat/thermostat_climate_valve.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class ThermostatOverClimateValve(ThermostatOverClimate):
"tpi_coef_int",
"tpi_coef_ext",
"power_percent",
"min_opening_degrees",
}
)
)
Expand All @@ -51,6 +52,7 @@ def __init__(
self._last_calculation_timestamp: datetime | None = None
self._auto_regulation_dpercent: float | None = None
self._auto_regulation_period_min: int | None = None
self._min_opening_degress: list[int] = []

super().__init__(hass, unique_id, name, entry_infos)

Expand Down Expand Up @@ -86,6 +88,14 @@ def post_init(self, config_entry: ConfigData):
offset_list = config_entry.get(CONF_OFFSET_CALIBRATION_LIST, [])
opening_list = config_entry.get(CONF_OPENING_DEGREE_LIST)
closing_list = config_entry.get(CONF_CLOSING_DEGREE_LIST, [])

self._min_opening_degrees = config_entry.get(CONF_MIN_OPENING_DEGREES, None)
min_opening_degrees_list = []
if self._min_opening_degrees:
min_opening_degrees_list = [
int(x.strip()) for x in self._min_opening_degrees.split(",")
]

for idx, _ in enumerate(config_entry.get(CONF_UNDERLYING_LIST)):
offset = offset_list[idx] if idx < len(offset_list) else None
# number of opening should equal number of underlying
Expand All @@ -98,6 +108,11 @@ def post_init(self, config_entry: ConfigData):
opening_degree_entity_id=opening,
closing_degree_entity_id=closing,
climate_underlying=self._underlyings[idx],
min_opening_degree=(
min_opening_degrees_list[idx]
if idx < len(min_opening_degrees_list)
else 0
),
)
self._underlyings_valve_regulation.append(under)

Expand Down Expand Up @@ -130,6 +145,10 @@ def update_custom_attributes(self):
self._attr_extra_state_attributes["tpi_coef_int"] = self._tpi_coef_int
self._attr_extra_state_attributes["tpi_coef_ext"] = self._tpi_coef_ext

self._attr_extra_state_attributes["min_opening_degrees"] = (
self._min_opening_degrees
)

self._attr_extra_state_attributes["valve_open_percent"] = (
self.valve_open_percent
)
Expand Down
12 changes: 8 additions & 4 deletions custom_components/versatile_thermostat/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,15 @@
"offset_calibration_entity_ids": "Offset calibration entities",
"opening_degree_entity_ids": "Opening degree entities",
"closing_degree_entity_ids": "Closing degree entities",
"proportional_function": "Algorithm"
"proportional_function": "Algorithm",
"min_opening_degrees": "Min opening degrees"
},
"data_description": {
"offset_calibration_entity_ids": "The list of the 'offset calibration' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"opening_degree_entity_ids": "The list of the 'opening degree' entities. There should be one per underlying climate entities",
"closing_degree_entity_ids": "The list of the 'closing degree' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"proportional_function": "Algorithm to use (TPI is the only one for now)"
"proportional_function": "Algorithm to use (TPI is the only one for now)",
"min_opening_degrees": "A comma seperated list of minimal opening degrees. Default to 0. Example: 20, 25, 30"
}
}
},
Expand Down Expand Up @@ -468,13 +470,15 @@
"offset_calibration_entity_ids": "Offset calibration entities",
"opening_degree_entity_ids": "Opening degree entities",
"closing_degree_entity_ids": "Closing degree entities",
"proportional_function": "Algorithm"
"proportional_function": "Algorithm",
"min_opening_degrees": "Min opening degrees"
},
"data_description": {
"offset_calibration_entity_ids": "The list of the 'offset calibration' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"opening_degree_entity_ids": "The list of the 'opening degree' entities. There should be one per underlying climate entities",
"closing_degree_entity_ids": "The list of the 'closing degree' entities. Set it if your TRV have the entity for better regulation. There should be one per underlying climate entities",
"proportional_function": "Algorithm to use (TPI is the only one for now)"
"proportional_function": "Algorithm to use (TPI is the only one for now)",
"min_opening_degrees": "A comma seperated list of minimal opening degrees. Default to 0. Example: 20, 25, 30"
}
}
},
Expand Down
15 changes: 10 additions & 5 deletions custom_components/versatile_thermostat/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,15 @@
"offset_calibration_entity_ids": "Entités de 'calibrage du décalage''",
"opening_degree_entity_ids": "Entités 'ouverture de vanne'",
"closing_degree_entity_ids": "Entités 'fermeture de la vanne'",
"proportional_function": "Algorithme"
"proportional_function": "Algorithme",
"min_opening_degrees": "Ouvertures minimales"
},
"data_description": {
"offset_calibration_entity_ids": "La liste des entités 'calibrage du décalage' (offset calibration). Configurez le si votre TRV possède cette fonction pour une meilleure régulation. Il doit y en avoir une par entité climate sous-jacente",
"opening_degree_entity_ids": "La liste des entités 'ouverture de vanne'. Il doit y en avoir une par entité climate sous-jacente",
"closing_degree_entity_ids": "La liste des entités 'fermeture de la vanne'. Configurez le si votre TRV possède cette fonction pour une meilleure régulation. Il doit y en avoir une par entité climate sous-jacente",
"proportional_function": "Algorithme à utiliser (seulement TPI est disponible)"
"proportional_function": "Algorithme à utiliser (seulement TPI est disponible)",
"min_opening_degrees": "Une liste séparée par des virgules de minimum d'ouverture. Valeur par défaut : 0. Exemple : 20, 25, 30"
}
}
},
Expand Down Expand Up @@ -462,13 +464,15 @@
"offset_calibration_entity_ids": "Entités de 'calibrage du décalage''",
"opening_degree_entity_ids": "Entités 'ouverture de vanne'",
"closing_degree_entity_ids": "Entités 'fermeture de la vanne'",
"proportional_function": "Algorithme"
"proportional_function": "Algorithme",
"min_opening_degrees": "Ouvertures minimales"
},
"data_description": {
"offset_calibration_entity_ids": "La liste des entités 'calibrage du décalage' (offset calibration). Configurez le si votre TRV possède cette fonction pour une meilleure régulation. Il doit y en avoir une par entité climate sous-jacente",
"opening_degree_entity_ids": "La liste des entités 'ouverture de vanne'. Il doit y en avoir une par entité climate sous-jacente",
"closing_degree_entity_ids": "La liste des entités 'fermeture de la vanne'. Configurez le si votre TRV possède cette fonction pour une meilleure régulation. Il doit y en avoir une par entité climate sous-jacente",
"proportional_function": "Algorithme à utiliser (seulement TPI est disponible)"
"proportional_function": "Algorithme à utiliser (seulement TPI est disponible)",
"min_opening_degrees": "Une liste séparée par des virgules de minimum d'ouverture. Valeur par défaut : 0. Exemple : 20, 25, 30"
}
}
},
Expand All @@ -478,7 +482,8 @@
"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.",
"service_configuration_format": "Mauvais format de la configuration du service",
"valve_regulation_nb_entities_incorrect": "Le nombre d'entités pour la régulation par vanne doit être égal au nombre d'entité sous-jacentes"
"valve_regulation_nb_entities_incorrect": "Le nombre d'entités pour la régulation par vanne doit être égal au nombre d'entité sous-jacentes",
"min_opening_degrees_format": "Une liste d'entiers positifs séparés par des ',' est attendu. Exemple : 20, 25, 30"
},
"abort": {
"already_configured": "Le device est déjà configuré"
Expand Down
10 changes: 10 additions & 0 deletions custom_components/versatile_thermostat/underlyings.py
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,7 @@ def __init__(
opening_degree_entity_id: str,
closing_degree_entity_id: str,
climate_underlying: UnderlyingClimate,
min_opening_degree: int = 0,
) -> None:
"""Initialize the underlying TRV with valve regulation"""
super().__init__(
Expand All @@ -1045,6 +1046,7 @@ def __init__(
self._max_opening_degree: float = None
self._min_offset_calibration: float = None
self._max_offset_calibration: float = None
self._min_opening_degree: int = min_opening_degree

async def send_percent_open(self):
"""Send the percent open to the underlying valve"""
Expand Down Expand Up @@ -1079,6 +1081,9 @@ async def send_percent_open(self):
return

# Send opening_degree
if 0 < self._percent_open < self._min_opening_degree:
self._percent_open = self._min_opening_degree

await super().send_percent_open()

# Send closing_degree if set
Expand Down Expand Up @@ -1138,6 +1143,11 @@ def closing_degree_entity_id(self) -> str:
"""The offset_calibration_entity_id"""
return self._closing_degree_entity_id

@property
def min_opening_degree(self) -> int:
"""The minimum opening degree"""
return self._min_opening_degree

@property
def have_closing_degree_entity(self) -> bool:
"""Return True if the underlying have a closing_degree entity"""
Expand Down
3 changes: 3 additions & 0 deletions tests/test_config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -1581,6 +1581,7 @@ async def test_user_config_flow_over_climate_valve(
CONF_OFFSET_CALIBRATION_LIST: ["number.offset_calibration1"],
CONF_OPENING_DEGREE_LIST: ["number.opening_degree1"],
CONF_CLOSING_DEGREE_LIST: ["number.closing_degree1"],
CONF_MIN_OPENING_DEGREES: "10, 20,0",
},
)
assert result["type"] == FlowResultType.FORM
Expand Down Expand Up @@ -1619,6 +1620,7 @@ async def test_user_config_flow_over_climate_valve(
"number.opening_degree2",
],
CONF_CLOSING_DEGREE_LIST: [],
CONF_MIN_OPENING_DEGREES: "10, 20,0",
},
)
assert result["type"] == FlowResultType.MENU
Expand Down Expand Up @@ -1715,6 +1717,7 @@ async def test_user_config_flow_over_climate_valve(
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
CONF_TPI_COEF_INT: 0.3,
CONF_TPI_COEF_EXT: 0.1,
CONF_MIN_OPENING_DEGREES: "10, 20,0",
}
assert result["result"]
assert result["result"].domain == DOMAIN
Expand Down
Loading

0 comments on commit 083a3a4

Please sign in to comment.