Fix too much shedding in over_climate
This commit is contained in:
@@ -1609,14 +1609,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
return False
|
||||
|
||||
# Check overpowering condition
|
||||
await VersatileThermostatAPI.get_vtherm_api().central_power_manager.refresh_state()
|
||||
|
||||
# TODO remove this
|
||||
# overpowering is now centralized
|
||||
# overpowering = await self._power_manager.check_overpowering()
|
||||
# if overpowering == STATE_ON:
|
||||
# _LOGGER.debug("%s - End of cycle (overpowering)", self)
|
||||
# return True
|
||||
# Not usefull. Will be done at the next power refresh
|
||||
# await VersatileThermostatAPI.get_vtherm_api().central_power_manager.refresh_state()
|
||||
|
||||
safety: bool = await self._safety_manager.refresh_state()
|
||||
if safety and self.is_over_climate:
|
||||
@@ -1974,5 +1968,17 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
||||
|
||||
@property
|
||||
def power_percent(self) -> float | None:
|
||||
"""Get the current on_percent as a percentage value. valid only for Vtherm with a TPI algo"""
|
||||
"""Get the current on_percent value"""
|
||||
if self._prop_algorithm and self._prop_algorithm.on_percent is not None:
|
||||
return round(self._prop_algorithm.on_percent * 100, 0)
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def on_percent(self) -> float | None:
|
||||
"""Get the current on_percent value. valid only for Vtherm with a TPI algo"""
|
||||
return None
|
||||
if self._prop_algorithm and self._prop_algorithm.on_percent is not None:
|
||||
return self._prop_algorithm.on_percent
|
||||
else:
|
||||
return None
|
||||
|
||||
@@ -4,6 +4,7 @@ import logging
|
||||
from typing import Any
|
||||
from functools import cmp_to_key
|
||||
|
||||
from homeassistant.const import STATE_OFF
|
||||
from homeassistant.core import HomeAssistant, Event, callback
|
||||
from homeassistant.helpers.event import (
|
||||
async_track_state_change_event,
|
||||
@@ -163,54 +164,52 @@ class CentralFeaturePowerManager(BaseFeatureManager):
|
||||
total_power_gain = 0
|
||||
|
||||
for vtherm in vtherms_sorted:
|
||||
device_power = vtherm.power_manager.device_power
|
||||
if vtherm.is_device_active and not vtherm.power_manager.is_overpowering_detected:
|
||||
device_power = vtherm.power_manager.device_power
|
||||
total_power_gain += device_power
|
||||
_LOGGER.debug("vtherm %s should be in overpowering state", vtherm.name)
|
||||
_LOGGER.info("vtherm %s should be in overpowering state (device_power=%.2f)", vtherm.name, device_power)
|
||||
await vtherm.power_manager.set_overpowering(True, device_power)
|
||||
|
||||
_LOGGER.debug("after vtherm %s total_power_gain=%s, available_power=%s", vtherm.name, total_power_gain, available_power)
|
||||
if total_power_gain >= -available_power:
|
||||
_LOGGER.debug("We have found enough vtherm to set to overpowering")
|
||||
break
|
||||
# unshedding only
|
||||
else:
|
||||
# vtherms_sorted.reverse()
|
||||
vtherms_sorted.reverse()
|
||||
_LOGGER.debug("The available power is is > 0 (%s). Do a complete shedding/un-shedding calculation for list: %s", available_power, vtherms_sorted)
|
||||
|
||||
total_affected_power = 0
|
||||
force_overpowering = False
|
||||
total_power_added = 0
|
||||
|
||||
for vtherm in vtherms_sorted:
|
||||
device_power = vtherm.power_manager.device_power
|
||||
# We want to do always unshedding in order to initialize the state
|
||||
# so we cannot use is_overpowering_detected which test also UNKNOWN and UNAVAILABLE
|
||||
if vtherm.power_manager.overpowering_state == STATE_OFF:
|
||||
continue
|
||||
|
||||
power_consumption_max = device_power = vtherm.power_manager.device_power
|
||||
# calculate the power_consumption_max
|
||||
if vtherm.is_device_active:
|
||||
power_consumption_max = 0
|
||||
else:
|
||||
if vtherm.is_over_climate:
|
||||
power_consumption_max = device_power
|
||||
else:
|
||||
if vtherm.proportional_algorithm.on_percent > 0:
|
||||
power_consumption_max = max(
|
||||
device_power / vtherm.nb_underlying_entities,
|
||||
device_power * vtherm.proportional_algorithm.on_percent,
|
||||
)
|
||||
else:
|
||||
power_consumption_max = 0
|
||||
if vtherm.on_percent is not None:
|
||||
power_consumption_max = max(
|
||||
device_power / vtherm.nb_underlying_entities,
|
||||
device_power * vtherm.on_percent,
|
||||
)
|
||||
|
||||
_LOGGER.debug("vtherm %s power_consumption_max is %s (device_power=%s, overclimate=%s)", vtherm.name, power_consumption_max, device_power, vtherm.is_over_climate)
|
||||
if force_overpowering or (total_affected_power + power_consumption_max >= available_power):
|
||||
_LOGGER.debug("vtherm %s should be in overpowering state", vtherm.name)
|
||||
if not vtherm.power_manager.is_overpowering_detected:
|
||||
# To force all others vtherms to be in overpowering
|
||||
force_overpowering = True
|
||||
await vtherm.power_manager.set_overpowering(True, power_consumption_max)
|
||||
else:
|
||||
total_affected_power += power_consumption_max
|
||||
# Always set to false to init the state
|
||||
_LOGGER.debug("vtherm %s should not be in overpowering state", vtherm.name)
|
||||
await vtherm.power_manager.set_overpowering(False)
|
||||
# if total_power_added + power_consumption_max < available_power or not vtherm.power_manager.is_overpowering_detected:
|
||||
_LOGGER.info("vtherm %s should not be in overpowering state (power_consumption_max=%.2f)", vtherm.name, power_consumption_max)
|
||||
|
||||
_LOGGER.debug("after vtherm %s total_affected_power=%s, available_power=%s", vtherm.name, total_affected_power, available_power)
|
||||
# we count the unshedding only if the VTherm was in shedding
|
||||
if vtherm.power_manager.is_overpowering_detected:
|
||||
total_power_added += power_consumption_max
|
||||
|
||||
await vtherm.power_manager.set_overpowering(False)
|
||||
|
||||
if total_power_added >= available_power:
|
||||
_LOGGER.debug("We have found enough vtherm to set to non-overpowering")
|
||||
break
|
||||
|
||||
_LOGGER.debug("after vtherm %s total_power_added=%s, available_power=%s", vtherm.name, total_power_added, available_power)
|
||||
|
||||
def get_climate_components_entities(self) -> list:
|
||||
"""Get all VTherms entitites"""
|
||||
|
||||
@@ -263,15 +263,6 @@ class ThermostatOverClimateValve(ThermostatOverClimate):
|
||||
"""True if the Thermostat is regulated by valve"""
|
||||
return True
|
||||
|
||||
@overrides
|
||||
@property
|
||||
def power_percent(self) -> float | None:
|
||||
"""Get the current on_percent value"""
|
||||
if self._prop_algorithm:
|
||||
return round(self._prop_algorithm.on_percent * 100, 0)
|
||||
else:
|
||||
return None
|
||||
|
||||
# @property
|
||||
# def hvac_modes(self) -> list[HVACMode]:
|
||||
# """Get the hvac_modes"""
|
||||
|
||||
@@ -61,15 +61,6 @@ class ThermostatOverSwitch(BaseThermostat[UnderlyingSwitch]):
|
||||
"""True if the switch is inversed (for pilot wire and diode)"""
|
||||
return self._is_inversed is True
|
||||
|
||||
@overrides
|
||||
@property
|
||||
def power_percent(self) -> float | None:
|
||||
"""Get the current on_percent value"""
|
||||
if self._prop_algorithm:
|
||||
return round(self._prop_algorithm.on_percent * 100, 0)
|
||||
else:
|
||||
return None
|
||||
|
||||
@overrides
|
||||
def post_init(self, config_entry: ConfigData):
|
||||
"""Initialize the Thermostat"""
|
||||
|
||||
Reference in New Issue
Block a user