Compare commits

...

5 Commits

Author SHA1 Message Date
Jean-Marc Collin 7b657ffabf Issue 444 ha 2024.04.3 (#452)
* HA 2024.4.3 and release

* [#444] - fix initial temp values with standalone presets

---------

Co-authored-by: Jean-Marc Collin <jean-marc.collin-extern@renault.com>
2024-04-23 07:58:22 +02:00
Jean-Marc Collin acd22d1fc4 HA 2024.4.3 and release (#447)
Co-authored-by: Jean-Marc Collin <jean-marc.collin-extern@renault.com>
2024-04-16 08:54:59 +02:00
Jean-Marc Collin d6f33d5796 [#438] - manage total_energy none until restored or calculated (#446)
Co-authored-by: Jean-Marc Collin <jean-marc.collin-extern@renault.com>
2024-04-16 07:14:38 +02:00
Jean-Marc Collin c1ebb46ac6 [#358] - Block preset_mode change on central_mode status (#445)
Co-authored-by: Jean-Marc Collin <jean-marc.collin-extern@renault.com>
2024-04-15 08:06:07 +02:00
Jean-Marc Collin eee4a9c4e3 Beers ! 2024-04-08 05:33:56 +00:00
11 changed files with 101 additions and 23 deletions
+1 -1
View File
@@ -212,7 +212,7 @@ En conséquence toute la phase de paramètrage d'un VTherm a été profondemment
</details>
# Merci pour la bière [buymecoffee](https://www.buymeacoffee.com/jmcollin78)
Un grand merci à @salabur, @pvince83, @bergoglio, @EPicLURcher, @ecolorado66, @Kriss1670, @maia, @f.maymil, @moutte69, @Jerome, @Gunnar M, @Greg.o, @John Burgess, @abyssmal, @capinfo26, @Helge, @MattG @Mexx62, @Someone, @Lajull, @giopeco, @fredericselier, @philpagan, @studiogriffanti, @Edwin, @Sebbou, @Gerard R. pour les bières. Ca fait très plaisir et ça m'encourage à continuer !
Un grand merci à @salabur, @pvince83, @bergoglio, @EPicLURcher, @ecolorado66, @Kriss1670, @maia, @f.maymil, @moutte69, @Jerome, @Gunnar M, @Greg.o, @John Burgess, @abyssmal, @capinfo26, @Helge, @MattG @Mexx62, @Someone, @Lajull, @giopeco, @fredericselier, @philpagan, @studiogriffanti, @Edwin, @Sebbou, @Gerard R., @John Burgess, @Sylvoliv, @cdenfert pour les bières. Ca fait très plaisir et ça m'encourage à continuer !
# Quand l'utiliser et ne pas l'utiliser
+1 -1
View File
@@ -213,7 +213,7 @@ Consequently, the entire configuration phase of a VTherm has been profoundly mod
</details>
# Thanks for the beer [buymecoffee](https://www.buymeacoffee.com/jmcollin78)
Many thanks to @salabur, @pvince83, @bergoglio, @EPicLURcher, @ecolorado66, @Kriss1670, @maia, @f.maymil, @moutte69, @Jerome, @Gunnar M, @Greg.o, @John Burgess, @abyssmal, @capinfo26, @Helge, @MattG, @MattG, @Mexx62, @Someone, @Lajull, @giopeco, @fredericselier, @philpagan, @studiogriffanti, @Edwin, @Sebbou, @Gerard R. for the beers. It's very nice and encourages me to continue!
Many thanks to @salabur, @pvince83, @bergoglio, @EPicLURcher, @ecolorado66, @Kriss1670, @maia, @f.maymil, @moutte69, @Jerome, @Gunnar M, @Greg.o, @John Burgess, @abyssmal, @capinfo26, @Helge, @MattG, @MattG, @Mexx62, @Someone, @Lajull, @giopeco, @fredericselier, @philpagan, @studiogriffanti, @Edwin, @Sebbou, @Gerard R., @John Burgess, @Sylvoliv, @cdenfert for the beers. It's very nice and encourages me to continue!
# When to use / not use
This thermostat can control 3 types of equipment:
@@ -532,7 +532,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
self._overpowering_state = None
self._presence_state = None
self._total_energy = 0
self._total_energy = None
# Read the parameter from configuration.yaml if it exists
short_ema_params = DEFAULT_SHORT_EMA_PARAMS
@@ -860,8 +860,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
self._hvac_mode = HVACMode.OFF
old_total_energy = old_state.attributes.get(ATTR_TOTAL_ENERGY)
if old_total_energy:
self._total_energy = old_total_energy
self._total_energy = old_total_energy if old_total_energy else 0
self.restore_specific_previous_state(old_state)
else:
@@ -874,6 +873,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
_LOGGER.warning(
"No previously saved temperature, setting to %s", self._target_temp
)
self._total_energy = 0
self._saved_target_temp = self._target_temp
@@ -1063,7 +1063,10 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
@property
def total_energy(self) -> float | None:
"""Returns the total energy calculated for this thermostast"""
return round(self._total_energy, 2)
if self._total_energy is not None:
return round(self._total_energy, 2)
else:
return None
@property
def device_power(self) -> float | None:
@@ -1258,6 +1261,31 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
self, preset_mode: str, overwrite_saved_preset=True
):
"""Set new preset mode."""
# Wer accept a new preset when:
# 1. last_central_mode is not set,
# 2. or last_central_mode is AUTO,
# 3. or last_central_mode is CENTRAL_MODE_FROST_PROTECTION and preset_mode is PRESET_FROST_PROTECTION (to be abel to re-set the preset_mode)
accept = self._last_central_mode in [
None,
CENTRAL_MODE_AUTO,
CENTRAL_MODE_COOL_ONLY,
CENTRAL_MODE_HEAT_ONLY,
CENTRAL_MODE_STOPPED,
] or (
self._last_central_mode == CENTRAL_MODE_FROST_PROTECTION
and preset_mode == PRESET_FROST_PROTECTION
)
if not accept:
_LOGGER.info(
"%s - Impossible to change the preset to %s because central mode is %s",
self,
preset_mode,
self._last_central_mode,
)
return
await self._async_set_preset_mode_internal(
preset_mode, force=False, overwrite_saved_preset=overwrite_saved_preset
)
@@ -14,6 +14,6 @@
"quality_scale": "silver",
"requirements": [],
"ssdp": [],
"version": "6.2.0",
"version": "6.2.3",
"zeroconf": []
}
@@ -11,6 +11,9 @@ from homeassistant.components.number import (
NumberMode,
NumberDeviceClass,
DOMAIN as NUMBER_DOMAIN,
DEFAULT_MAX_VALUE,
DEFAULT_MIN_VALUE,
DEFAULT_STEP,
)
from homeassistant.components.climate import (
PRESET_BOOST,
@@ -53,6 +56,7 @@ from .const import (
CONF_USE_PRESENCE_FEATURE,
CONF_USE_CENTRAL_BOILER_FEATURE,
overrides,
CONF_USE_MAIN_CENTRAL_CONFIG,
)
PRESET_ICON_MAPPING = {
@@ -341,7 +345,10 @@ class CentralConfigTemperatureNumber(
async def async_set_native_value(self, value: float) -> None:
"""The value have change from the Number Entity in UI"""
float_value = float(value)
old_value = float(self._attr_native_value)
old_value = (
None if self._attr_native_value is None else float(self._attr_native_value)
)
if float_value == old_value:
return
@@ -395,9 +402,11 @@ class TemperatureNumber( # pylint: disable=abstract-method
self._attr_device_class = NumberDeviceClass.TEMPERATURE
self._attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS
self._attr_native_step = entry_infos.get(CONF_STEP_TEMPERATURE, 0.5)
self._attr_native_min_value = entry_infos.get(CONF_TEMP_MIN)
self._attr_native_max_value = entry_infos.get(CONF_TEMP_MAX)
self._has_central_main_attributes = entry_infos.get(
CONF_USE_MAIN_CENTRAL_CONFIG, False
)
self.init_min_max_step(entry_infos)
# Initialize the values if included into the entry_infos. This will do
# the temperature migration.
@@ -459,7 +468,9 @@ class TemperatureNumber( # pylint: disable=abstract-method
return
float_value = float(value)
old_value = float(self._attr_native_value)
old_value = (
None if self._attr_native_value is None else float(self._attr_native_value)
)
if float_value == old_value:
return
@@ -476,6 +487,10 @@ class TemperatureNumber( # pylint: disable=abstract-method
)
)
# We set the min, max and step from central config if relevant because it is possible that central config
# was not loaded at startup
self.init_min_max_step()
def __str__(self):
return f"VersatileThermostat-{self.name}"
@@ -485,3 +500,26 @@ class TemperatureNumber( # pylint: disable=abstract-method
if not self.my_climate:
return UnitOfTemperature.CELSIUS
return self.my_climate.temperature_unit
def init_min_max_step(self, entry_infos=None):
"""Initialize min, max and step value from config or from central config"""
if self._has_central_main_attributes:
vthermapi: VersatileThermostatAPI = VersatileThermostatAPI.get_vtherm_api()
central_config = vthermapi.find_central_configuration()
if central_config:
self._attr_native_step = central_config.data.get(CONF_STEP_TEMPERATURE)
self._attr_native_min_value = central_config.data.get(CONF_TEMP_MIN)
self._attr_native_max_value = central_config.data.get(CONF_TEMP_MAX)
return
if entry_infos:
self._attr_native_step = entry_infos.get(
CONF_STEP_TEMPERATURE, DEFAULT_STEP
)
self._attr_native_min_value = entry_infos.get(
CONF_TEMP_MIN, DEFAULT_MIN_VALUE
)
self._attr_native_max_value = entry_infos.get(
CONF_TEMP_MAX, DEFAULT_MAX_VALUE
)
@@ -125,15 +125,15 @@ class EnergySensor(VersatileThermostatBaseEntity, SensorEntity):
"""Called when my climate have change"""
_LOGGER.debug("%s - climate state change", self._attr_unique_id)
if math.isnan(self.my_climate.total_energy) or math.isinf(
self.my_climate.total_energy
):
energy = self.my_climate.total_energy
if energy is None:
return
if math.isnan(energy) or math.isinf(energy):
raise ValueError(f"Sensor has illegal state {self.my_climate.total_energy}")
old_state = self._attr_native_value
self._attr_native_value = round(
self.my_climate.total_energy, self.suggested_display_precision
)
self._attr_native_value = round(energy, self.suggested_display_precision)
if old_state != self._attr_native_value:
self.async_write_ha_state()
return
@@ -581,7 +581,11 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
):
added_energy = self._device_power * self._underlying_climate_delta_t
self._total_energy += added_energy
if self._total_energy is None:
self._total_energy = added_energy
else:
self._total_energy += added_energy
_LOGGER.debug(
"%s - added energy is %.3f . Total energy is now: %.3f",
self,
@@ -199,7 +199,11 @@ class ThermostatOverSwitch(BaseThermostat[UnderlyingSwitch]):
if not self.is_over_climate and self.mean_cycle_power is not None:
added_energy = self.mean_cycle_power * float(self._cycle_min) / 60.0
self._total_energy += added_energy
if self._total_energy is None:
self._total_energy = added_energy
else:
self._total_energy += added_energy
_LOGGER.debug(
"%s - added energy is %.3f . Total energy is now: %.3f",
self,
@@ -279,7 +279,11 @@ class ThermostatOverValve(BaseThermostat[UnderlyingValve]): # pylint: disable=a
if not self.is_over_climate and self.mean_cycle_power is not None:
added_energy = self.mean_cycle_power * float(self._cycle_min) / 60.0
self._total_energy += added_energy
if self._total_energy is None:
self._total_energy = added_energy
else:
self._total_energy += added_energy
_LOGGER.debug(
"%s - added energy is %.3f . Total energy is now: %.3f",
self,
+1 -1
View File
@@ -3,5 +3,5 @@
"content_in_root": false,
"render_readme": true,
"hide_default_branch": false,
"homeassistant": "2024.3.1"
"homeassistant": "2024.4.3"
}
+1 -1
View File
@@ -1 +1 @@
homeassistant==2024.3.1
homeassistant==2024.4.3