Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ebc2d8b6ac | ||
|
|
cf4cc32b13 | ||
|
|
2523fc74c2 | ||
|
|
87de91c2c5 | ||
|
|
a3b6f66f1b | ||
|
|
8cf09e5254 | ||
|
|
0b67226666 | ||
|
|
812bb19e10 | ||
|
|
be3012af71 | ||
|
|
05fe2055e2 | ||
|
|
8743872c09 |
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
@@ -1050,7 +1050,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
|||||||
self._hvac_mode in [HVACMode.COOL, HVACMode.HEAT, HVACMode.HEAT_COOL]
|
self._hvac_mode in [HVACMode.COOL, HVACMode.HEAT, HVACMode.HEAT_COOL]
|
||||||
and self.preset_mode != PRESET_NONE
|
and self.preset_mode != PRESET_NONE
|
||||||
):
|
):
|
||||||
if self.preset_mode != PRESET_FROST_PROTECTION:
|
if self.preset_mode != PRESET_FROST_PROTECTION or self._hvac_mode in [HVACMode.HEAT, HVACMode.HEAT_COOL]:
|
||||||
await self.async_set_preset_mode_internal(self.preset_mode, True)
|
await self.async_set_preset_mode_internal(self.preset_mode, True)
|
||||||
else:
|
else:
|
||||||
await self.async_set_preset_mode_internal(PRESET_ECO, True, False)
|
await self.async_set_preset_mode_internal(PRESET_ECO, True, False)
|
||||||
@@ -1244,12 +1244,12 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
|||||||
|
|
||||||
async def async_set_humidity(self, humidity: int):
|
async def async_set_humidity(self, humidity: int):
|
||||||
"""Set new target humidity."""
|
"""Set new target humidity."""
|
||||||
_LOGGER.info("%s - Set fan mode: %s", self, humidity)
|
_LOGGER.info("%s - Set humidity: %s", self, humidity)
|
||||||
return
|
return
|
||||||
|
|
||||||
async def async_set_swing_mode(self, swing_mode: str):
|
async def async_set_swing_mode(self, swing_mode: str):
|
||||||
"""Set new target swing operation."""
|
"""Set new target swing operation."""
|
||||||
_LOGGER.info("%s - Set fan mode: %s", self, swing_mode)
|
_LOGGER.info("%s - Set swing mode: %s", self, swing_mode)
|
||||||
return
|
return
|
||||||
|
|
||||||
async def async_set_temperature(self, **kwargs):
|
async def async_set_temperature(self, **kwargs):
|
||||||
@@ -1528,8 +1528,8 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
|||||||
is_window_detected = self._window_manager.is_window_detected
|
is_window_detected = self._window_manager.is_window_detected
|
||||||
if new_central_mode == CENTRAL_MODE_AUTO:
|
if new_central_mode == CENTRAL_MODE_AUTO:
|
||||||
if not is_window_detected and not first_init:
|
if not is_window_detected and not first_init:
|
||||||
await self.restore_hvac_mode()
|
await self.restore_preset_mode(force=False)
|
||||||
await self.restore_preset_mode()
|
await self.restore_hvac_mode(need_control_heating=True)
|
||||||
elif is_window_detected and self.hvac_mode == HVACMode.OFF:
|
elif is_window_detected and self.hvac_mode == HVACMode.OFF:
|
||||||
# do not restore but mark the reason of off with window detection
|
# do not restore but mark the reason of off with window detection
|
||||||
self.set_hvac_off_reason(HVAC_OFF_REASON_WINDOW_DETECTION)
|
self.set_hvac_off_reason(HVAC_OFF_REASON_WINDOW_DETECTION)
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ class CentralFeaturePowerManager(BaseFeatureManager):
|
|||||||
self._current_max_power: float = None
|
self._current_max_power: float = None
|
||||||
self._power_temp: float = None
|
self._power_temp: float = None
|
||||||
self._cancel_calculate_shedding_call = None
|
self._cancel_calculate_shedding_call = None
|
||||||
|
self._started_vtherm_total_power: float = None
|
||||||
# Not used now
|
# Not used now
|
||||||
self._last_shedding_date = None
|
self._last_shedding_date = None
|
||||||
|
|
||||||
@@ -71,6 +72,7 @@ class CentralFeaturePowerManager(BaseFeatureManager):
|
|||||||
and self._power_temp
|
and self._power_temp
|
||||||
):
|
):
|
||||||
self._is_configured = True
|
self._is_configured = True
|
||||||
|
self._started_vtherm_total_power = 0
|
||||||
else:
|
else:
|
||||||
_LOGGER.info("Power management is not fully configured and will be deactivated")
|
_LOGGER.info("Power management is not fully configured and will be deactivated")
|
||||||
|
|
||||||
@@ -102,6 +104,8 @@ class CentralFeaturePowerManager(BaseFeatureManager):
|
|||||||
"""Handle power changes."""
|
"""Handle power changes."""
|
||||||
_LOGGER.debug("Receive new Power event")
|
_LOGGER.debug("Receive new Power event")
|
||||||
_LOGGER.debug(event)
|
_LOGGER.debug(event)
|
||||||
|
|
||||||
|
self._started_vtherm_total_power = 0
|
||||||
await self.refresh_state()
|
await self.refresh_state()
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
@@ -275,6 +279,12 @@ class CentralFeaturePowerManager(BaseFeatureManager):
|
|||||||
vtherms.sort(key=cmp_to_key(cmp_temps))
|
vtherms.sort(key=cmp_to_key(cmp_temps))
|
||||||
return vtherms
|
return vtherms
|
||||||
|
|
||||||
|
def add_started_vtherm_total_power(self, started_power: float):
|
||||||
|
"""Add the power into the _started_vtherm_total_power which holds all VTherm started after
|
||||||
|
the last power measurement"""
|
||||||
|
self._started_vtherm_total_power += started_power
|
||||||
|
_LOGGER.debug("%s - started_vtherm_total_power is now %s", self, self._started_vtherm_total_power)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_configured(self) -> bool:
|
def is_configured(self) -> bool:
|
||||||
"""True if the FeatureManager is fully configured"""
|
"""True if the FeatureManager is fully configured"""
|
||||||
@@ -305,5 +315,10 @@ class CentralFeaturePowerManager(BaseFeatureManager):
|
|||||||
"""Return the max power sensor entity id"""
|
"""Return the max power sensor entity id"""
|
||||||
return self._max_power_sensor_entity_id
|
return self._max_power_sensor_entity_id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def started_vtherm_total_power(self) -> float | None:
|
||||||
|
"""Return the started_vtherm_total_power"""
|
||||||
|
return self._started_vtherm_total_power
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "CentralPowerManager"
|
return "CentralPowerManager"
|
||||||
|
|||||||
@@ -104,7 +104,8 @@ class FeaturePowerManager(BaseFeatureManager):
|
|||||||
|
|
||||||
async def check_power_available(self) -> bool:
|
async def check_power_available(self) -> bool:
|
||||||
"""Check if the Vtherm can be started considering overpowering.
|
"""Check if the Vtherm can be started considering overpowering.
|
||||||
Returns True if no overpowering conditions are found
|
Returns True if no overpowering conditions are found.
|
||||||
|
If True the vtherm power is written into the temporay vtherm started
|
||||||
"""
|
"""
|
||||||
|
|
||||||
vtherm_api = VersatileThermostatAPI.get_vtherm_api()
|
vtherm_api = VersatileThermostatAPI.get_vtherm_api()
|
||||||
@@ -116,6 +117,7 @@ class FeaturePowerManager(BaseFeatureManager):
|
|||||||
|
|
||||||
current_power = vtherm_api.central_power_manager.current_power
|
current_power = vtherm_api.central_power_manager.current_power
|
||||||
current_max_power = vtherm_api.central_power_manager.current_max_power
|
current_max_power = vtherm_api.central_power_manager.current_max_power
|
||||||
|
started_vtherm_total_power = vtherm_api.central_power_manager.started_vtherm_total_power
|
||||||
if (
|
if (
|
||||||
current_power is None
|
current_power is None
|
||||||
or current_max_power is None
|
or current_max_power is None
|
||||||
@@ -146,7 +148,7 @@ class FeaturePowerManager(BaseFeatureManager):
|
|||||||
self._device_power * self._vtherm.proportional_algorithm.on_percent,
|
self._device_power * self._vtherm.proportional_algorithm.on_percent,
|
||||||
)
|
)
|
||||||
|
|
||||||
ret = (current_power + power_consumption_max) < current_max_power
|
ret = (current_power + started_vtherm_total_power + power_consumption_max) < current_max_power
|
||||||
if not ret:
|
if not ret:
|
||||||
_LOGGER.info(
|
_LOGGER.info(
|
||||||
"%s - there is not enough power available power=%.3f, max_power=%.3f heater power=%.3f",
|
"%s - there is not enough power available power=%.3f, max_power=%.3f heater power=%.3f",
|
||||||
@@ -155,6 +157,10 @@ class FeaturePowerManager(BaseFeatureManager):
|
|||||||
current_max_power,
|
current_max_power,
|
||||||
self._device_power,
|
self._device_power,
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
# Adds the current_power_max to the started vtherm total power
|
||||||
|
vtherm_api.central_power_manager.add_started_vtherm_total_power(power_consumption_max)
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
async def set_overpowering(self, overpowering: bool, power_consumption_max=0):
|
async def set_overpowering(self, overpowering: bool, power_consumption_max=0):
|
||||||
|
|||||||
@@ -14,6 +14,6 @@
|
|||||||
"quality_scale": "silver",
|
"quality_scale": "silver",
|
||||||
"requirements": [],
|
"requirements": [],
|
||||||
"ssdp": [],
|
"ssdp": [],
|
||||||
"version": "7.1.4",
|
"version": "7.1.6",
|
||||||
"zeroconf": []
|
"zeroconf": []
|
||||||
}
|
}
|
||||||
@@ -1104,7 +1104,7 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
|
|||||||
@overrides
|
@overrides
|
||||||
async def async_set_humidity(self, humidity: int):
|
async def async_set_humidity(self, humidity: int):
|
||||||
"""Set new target humidity."""
|
"""Set new target humidity."""
|
||||||
_LOGGER.info("%s - Set fan mode: %s", self, humidity)
|
_LOGGER.info("%s - Set humidity: %s", self, humidity)
|
||||||
if humidity is None:
|
if humidity is None:
|
||||||
return
|
return
|
||||||
for under in self._underlyings:
|
for under in self._underlyings:
|
||||||
@@ -1115,7 +1115,7 @@ class ThermostatOverClimate(BaseThermostat[UnderlyingClimate]):
|
|||||||
@overrides
|
@overrides
|
||||||
async def async_set_swing_mode(self, swing_mode):
|
async def async_set_swing_mode(self, swing_mode):
|
||||||
"""Set new target swing operation."""
|
"""Set new target swing operation."""
|
||||||
_LOGGER.info("%s - Set fan mode: %s", self, swing_mode)
|
_LOGGER.info("%s - Set swing mode: %s", self, swing_mode)
|
||||||
if swing_mode is None:
|
if swing_mode is None:
|
||||||
return
|
return
|
||||||
for under in self._underlyings:
|
for under in self._underlyings:
|
||||||
|
|||||||
@@ -155,7 +155,7 @@
|
|||||||
},
|
},
|
||||||
"data_description": {
|
"data_description": {
|
||||||
"motion_sensor_entity_id": "Id d'entité du détecteur de mouvement",
|
"motion_sensor_entity_id": "Id d'entité du détecteur de mouvement",
|
||||||
"motion_delay": "Délai avant activation lorsqu'un mouvement est détecté (secondss)",
|
"motion_delay": "Délai avant activation lorsqu'un mouvement est détecté (secondes)",
|
||||||
"motion_off_delai": "Délai avant désactivation lorsqu'aucun mouvement n'est détecté (secondes)",
|
"motion_off_delai": "Délai avant désactivation lorsqu'aucun mouvement n'est détecté (secondes)",
|
||||||
"motion_preset": "Preset à utiliser si mouvement détecté",
|
"motion_preset": "Preset à utiliser si mouvement détecté",
|
||||||
"no_motion_preset": "Preset à utiliser si pas de mouvement détecté",
|
"no_motion_preset": "Preset à utiliser si pas de mouvement détecté",
|
||||||
@@ -200,7 +200,7 @@
|
|||||||
"use_advanced_central_config": "Utiliser la configuration centrale avancée"
|
"use_advanced_central_config": "Utiliser la configuration centrale avancée"
|
||||||
},
|
},
|
||||||
"data_description": {
|
"data_description": {
|
||||||
"minimal_activation_delay": "Délai en seondes en-dessous duquel l'équipement ne sera pas activé",
|
"minimal_activation_delay": "Délai en secondes en-dessous duquel l'équipement ne sera pas activé",
|
||||||
"safety_delay_min": "Délai maximal autorisé en minutes entre 2 mesures de températures. Au-dessus de ce délai, le thermostat se mettra en position de sécurité",
|
"safety_delay_min": "Délai maximal autorisé en minutes entre 2 mesures de températures. Au-dessus de ce délai, le thermostat se mettra en position de sécurité",
|
||||||
"safety_min_on_percent": "Seuil minimal de pourcentage de chauffage en-dessous duquel le préréglage sécurité ne sera jamais activé",
|
"safety_min_on_percent": "Seuil minimal de pourcentage de chauffage en-dessous duquel le préréglage sécurité ne sera jamais activé",
|
||||||
"safety_default_on_percent": "Valeur par défaut pour le pourcentage de chauffage en mode sécurité. Mettre 0 pour éteindre le radiateur en mode sécurité",
|
"safety_default_on_percent": "Valeur par défaut pour le pourcentage de chauffage en mode sécurité. Mettre 0 pour éteindre le radiateur en mode sécurité",
|
||||||
|
|||||||
@@ -611,7 +611,7 @@ class UnderlyingClimate(UnderlyingEntity):
|
|||||||
|
|
||||||
async def set_humidity(self, humidity: int):
|
async def set_humidity(self, humidity: int):
|
||||||
"""Set new target humidity."""
|
"""Set new target humidity."""
|
||||||
_LOGGER.info("%s - Set fan mode: %s", self, humidity)
|
_LOGGER.info("%s - Set humidity: %s", self, humidity)
|
||||||
if not self.is_initialized:
|
if not self.is_initialized:
|
||||||
return
|
return
|
||||||
data = {
|
data = {
|
||||||
@@ -627,7 +627,7 @@ class UnderlyingClimate(UnderlyingEntity):
|
|||||||
|
|
||||||
async def set_swing_mode(self, swing_mode):
|
async def set_swing_mode(self, swing_mode):
|
||||||
"""Set new target swing operation."""
|
"""Set new target swing operation."""
|
||||||
_LOGGER.info("%s - Set fan mode: %s", self, swing_mode)
|
_LOGGER.info("%s - Set swing mode: %s", self, swing_mode)
|
||||||
if not self.is_initialized:
|
if not self.is_initialized:
|
||||||
return
|
return
|
||||||
data = {
|
data = {
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ Of course, your underlying equipment must have ventilation, and it must be contr
|
|||||||
|
|
||||||
### Compensating for the Internal Temperature of the Underlying Equipment
|
### Compensating for the Internal Temperature of the Underlying Equipment
|
||||||
|
|
||||||
|
Warning: This option must not be used with direct valve control regulation if a calibration entity has been provided.
|
||||||
|
|
||||||
Sometimes, the internal thermometer of the underlying equipment (TRV, air conditioner, etc.) is inaccurate to the point that self-regulation is insufficient. This happens when the internal thermometer is placed too close to the heat source. The internal temperature rises much faster than the room temperature, leading to regulation failures.
|
Sometimes, the internal thermometer of the underlying equipment (TRV, air conditioner, etc.) is inaccurate to the point that self-regulation is insufficient. This happens when the internal thermometer is placed too close to the heat source. The internal temperature rises much faster than the room temperature, leading to regulation failures.
|
||||||
Example:
|
Example:
|
||||||
1. Room temperature is 18°, setpoint is 20°.
|
1. Room temperature is 18°, setpoint is 20°.
|
||||||
@@ -99,4 +101,4 @@ When this entity is 'On', all temperature or state changes made directly on the
|
|||||||
Be careful, if you use this feature, your equipment is now controlled in two ways: _VTherm_ and directly by you. The commands might be contradictory, which could lead to confusion about the equipment's state. _VTherm_ is equipped with a delay mechanism that prevents loops: the user gives a setpoint, which is captured by _VTherm_ and changes the setpoint, ... This delay may cause the change made directly on the equipment to be ignored if these changes are too close together in time.
|
Be careful, if you use this feature, your equipment is now controlled in two ways: _VTherm_ and directly by you. The commands might be contradictory, which could lead to confusion about the equipment's state. _VTherm_ is equipped with a delay mechanism that prevents loops: the user gives a setpoint, which is captured by _VTherm_ and changes the setpoint, ... This delay may cause the change made directly on the equipment to be ignored if these changes are too close together in time.
|
||||||
|
|
||||||
Some equipment (like Daikin, for example) changes state by itself. If the checkbox is checked, it may turn off the _VTherm_ when that's not what you intended.
|
Some equipment (like Daikin, for example) changes state by itself. If the checkbox is checked, it may turn off the _VTherm_ when that's not what you intended.
|
||||||
That's why it's better not to use it. It generates a lot of confusion and many support requests.
|
That's why it's better not to use it. It generates a lot of confusion and many support requests.
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ This allows you to configure the valve control entities:
|
|||||||
You need to provide:
|
You need to provide:
|
||||||
1. As many valve opening control entities as there are underlying devices, and in the same order. These parameters are mandatory.
|
1. As many valve opening control entities as there are underlying devices, and in the same order. These parameters are mandatory.
|
||||||
2. As many temperature calibration entities as there are underlying devices, and in the same order. These parameters are optional; they must either all be provided or none.
|
2. As many temperature calibration entities as there are underlying devices, and in the same order. These parameters are optional; they must either all be provided or none.
|
||||||
3. As many valve closure control entities as there are underlying devices, and in the same order. These parameters are optional; they must either all be provided or none.
|
3. As many valve closure control entities as there are underlying devices, and in the same order. These parameters are optional; they must either all be provided or none. For Sonoff TRVZB, you should not configure this entity. See the note below.
|
||||||
4. A list of minimum opening values for the valve when it needs to be opened. This field is a list of integers. If the valve needs to be opened, it will be opened at a minimum of this opening value. This allows enough water to pass through when it needs to be opened.
|
4. A list of minimum opening values for the valve when it needs to be opened. This field is a list of integers. If the valve needs to be opened, it will be opened at a minimum of this opening value, else it will be set to 0 (to ensure the valve is closed). This allows enough water to pass through when it needs to be opened.
|
||||||
|
|
||||||
The opening rate calculation algorithm is based on the _TPI_ algorithm described [here](algorithms.md). This is the same algorithm used for _VTherms_ `over_switch` and `over_valve`.
|
The opening rate calculation algorithm is based on the _TPI_ algorithm described [here](algorithms.md). This is the same algorithm used for _VTherms_ `over_switch` and `over_valve`.
|
||||||
|
|
||||||
@@ -152,4 +152,4 @@ To apply the changes, you must either **restart Home Assistant completely** or j
|
|||||||
|
|
||||||
## Summary of the Auto-Regulation Algorithm
|
## Summary of the Auto-Regulation Algorithm
|
||||||
|
|
||||||
A summary of the auto-regulation algorithm is described [here](algorithms.md#the-auto-regulation-algorithm-without-valve-control)
|
A summary of the auto-regulation algorithm is described [here](algorithms.md#the-auto-regulation-algorithm-without-valve-control)
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ Une fois l'écart de température redevenu faible, la ventilation se mettra dans
|
|||||||
|
|
||||||
### Compenser la température interne du sous-jacent
|
### Compenser la température interne du sous-jacent
|
||||||
|
|
||||||
|
Attention : cette option ne doit pas être utilisée avec une régulation par contrôle direct de la vanne si une entité de calibrage a été fournie.
|
||||||
|
|
||||||
Quelque fois, il arrive que le thermomètre interne du sous-jacent (TRV, climatisation, ...) soit tellement faux que l' auto-régulation ne suffise pas à réguler.
|
Quelque fois, il arrive que le thermomètre interne du sous-jacent (TRV, climatisation, ...) soit tellement faux que l' auto-régulation ne suffise pas à réguler.
|
||||||
Cela arrive lorsque le thermomètre interne est trop près de la source de chaleur. La température interne monte alors beaucoup plus vite que la température de la pièce, ce qui génère des défauts dans la régulation.
|
Cela arrive lorsque le thermomètre interne est trop près de la source de chaleur. La température interne monte alors beaucoup plus vite que la température de la pièce, ce qui génère des défauts dans la régulation.
|
||||||
Exemple :
|
Exemple :
|
||||||
@@ -103,4 +105,4 @@ Lorsque cette entité est 'On', tous les changements de température ou d'état
|
|||||||
Attention, si vous utilisez cette fonction, votre équipement est maintenant contrôlé par 2 moyens : _VTherm_ et par vous même directement. Les ordres peuvent être contradictoires et cela peut induire une incompréhension sur l'état de l'équipement. _VTherm_ est équipé d'un mécanisme de temporisation qui évite les boucles : l'utilisateur donne une consigne qui est captée par _VTherm_ qui change la consigne, ... Cette temporisation peut faire que le changement fait directement sur l'équipement est ignoré si ces changements sont trop rapprochés dans le temps.
|
Attention, si vous utilisez cette fonction, votre équipement est maintenant contrôlé par 2 moyens : _VTherm_ et par vous même directement. Les ordres peuvent être contradictoires et cela peut induire une incompréhension sur l'état de l'équipement. _VTherm_ est équipé d'un mécanisme de temporisation qui évite les boucles : l'utilisateur donne une consigne qui est captée par _VTherm_ qui change la consigne, ... Cette temporisation peut faire que le changement fait directement sur l'équipement est ignoré si ces changements sont trop rapprochés dans le temps.
|
||||||
|
|
||||||
Certains équipements (Daikin par exemple), changent d'état tout seul. Si la case est cochée, cela peut éteindre le _VTherm_ alors que ce n'est pas ce que vous souhaitiez.
|
Certains équipements (Daikin par exemple), changent d'état tout seul. Si la case est cochée, cela peut éteindre le _VTherm_ alors que ce n'est pas ce que vous souhaitiez.
|
||||||
C'est pour ça qu'il est préférable de ne pas l'utiliser. Cela génère beaucoup d'incompréhensions et de nombreuses demandes de support.
|
C'est pour ça qu'il est préférable de ne pas l'utiliser. Cela génère beaucoup d'incompréhensions et de nombreuses demandes de support.
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ Elle permet de configurer les entités de contrôle de la vanne :
|
|||||||
Vous devez donner :
|
Vous devez donner :
|
||||||
1. autant d'entités de contrôle d'ouverture de la vanne qu'il y a de sous-jacents et dans le même odre. Ces paramètres sont obligatoires,
|
1. autant d'entités de contrôle d'ouverture de la vanne qu'il y a de sous-jacents et dans le même odre. Ces paramètres sont obligatoires,
|
||||||
2. autant d'entités de calibrage du décalage de température qu'il y a de sous-jacents et dans le même ordre. Ces paramètres sont facultatifs ; ils doivent être tous founis ou aucun,
|
2. autant d'entités de calibrage du décalage de température qu'il y a de sous-jacents et dans le même ordre. Ces paramètres sont facultatifs ; ils doivent être tous founis ou aucun,
|
||||||
3. autant d'entités de de contrôile du taux de fermture qu'il y a de sous-jacents et dans le même ordre. Ces paramètres sont facultatifs ; ils doivent être tous founis ou aucun,
|
3. autant d'entités de de contrôile du taux de fermture qu'il y a de sous-jacents et dans le même ordre. Ces paramètres sont facultatifs ; ils doivent être tous founis ou aucun. Pour les Sonoff TRVZB, ils ne doivent pas être fournis,
|
||||||
4. une liste de valeurs minimales d'ouverture de la vanne lorsqu'elle doit être ouverte. Ce champ est une liste d'entier. Si la vanne doit être ouverte, elle le sera au minimum avec cette valeur d'ouverture. Cela permet de laisser passer suffisamment d'eau lorsqu'elle doit être ouverte.
|
4. une liste de valeurs minimales d'ouverture de la vanne lorsqu'elle doit être ouverte. Ce champ est une liste d'entier. Si la vanne doit être ouverte, elle le sera au minimum avec cette valeur d'ouverture, sinon elle sera totalement close (0). Cela permet de laisser passer suffisamment d'eau lorsqu'elle doit être ouverte mais garde la fermeeture complète si il n'y a pas besoin de chauffer.
|
||||||
|
|
||||||
L'algorithme de calcul du taux d'ouverture est basé sur le _TPI_ qui est décrit [ici](algorithms.md). C'est le même algorithme qui est utilisé pour les _VTherm_ `over_switch` et `over_valve`.
|
L'algorithme de calcul du taux d'ouverture est basé sur le _TPI_ qui est décrit [ici](algorithms.md). C'est le même algorithme qui est utilisé pour les _VTherm_ `over_switch` et `over_valve`.
|
||||||
|
|
||||||
@@ -152,4 +152,4 @@ Pour que les modifications soient prises en compte, il faut soit **relancer tota
|
|||||||
|
|
||||||
## Synthèse de l'algorithme d'auto-régulation
|
## Synthèse de l'algorithme d'auto-régulation
|
||||||
|
|
||||||
Une synthèse de l'algorithme d'auto-régulation est décrite [ici](algorithms.md#lalgorithme-dauto-régulation-sans-contrôle-de-la-vanne)
|
Une synthèse de l'algorithme d'auto-régulation est décrite [ici](algorithms.md#lalgorithme-dauto-régulation-sans-contrôle-de-la-vanne)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# pylint: disable=wildcard-import, unused-wildcard-import, unused-argument, line-too-long, protected-access
|
# pylint: disable=wildcard-import, unused-wildcard-import, unused-argument, line-too-long, protected-access
|
||||||
|
|
||||||
""" Test the normal start of a Thermostat """
|
""" Test the normal start of a Thermostat """
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch, PropertyMock
|
||||||
from datetime import timedelta, datetime
|
from datetime import timedelta, datetime
|
||||||
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
@@ -179,7 +179,7 @@ async def test_overpowering_binary_sensors(
|
|||||||
)
|
)
|
||||||
# fmt:off
|
# fmt:off
|
||||||
with patch("homeassistant.core.StateMachine.get", side_effect=side_effects.get_side_effects()), \
|
with patch("homeassistant.core.StateMachine.get", side_effect=side_effects.get_side_effects()), \
|
||||||
patch("custom_components.versatile_thermostat.thermostat_switch.ThermostatOverSwitch.is_device_active", return_value="True"):
|
patch("custom_components.versatile_thermostat.thermostat_switch.ThermostatOverSwitch.is_device_active", new_callable=PropertyMock, return_value=True):
|
||||||
# fmt: on
|
# fmt: on
|
||||||
await send_power_change_event(entity, 150, now)
|
await send_power_change_event(entity, 150, now)
|
||||||
await send_max_power_change_event(entity, 100, now)
|
await send_max_power_change_event(entity, 100, now)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
# pylint: disable=protected-access, unused-argument, line-too-long
|
# pylint: disable=protected-access, unused-argument, line-too-long
|
||||||
""" Test the Central Power management """
|
""" Test the Central Power management """
|
||||||
|
import asyncio
|
||||||
from unittest.mock import patch, AsyncMock, MagicMock, PropertyMock
|
from unittest.mock import patch, AsyncMock, MagicMock, PropertyMock
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import logging
|
import logging
|
||||||
@@ -10,6 +11,14 @@ from custom_components.versatile_thermostat.feature_power_manager import (
|
|||||||
from custom_components.versatile_thermostat.central_feature_power_manager import (
|
from custom_components.versatile_thermostat.central_feature_power_manager import (
|
||||||
CentralFeaturePowerManager,
|
CentralFeaturePowerManager,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from custom_components.versatile_thermostat.thermostat_switch import (
|
||||||
|
ThermostatOverSwitch,
|
||||||
|
)
|
||||||
|
from custom_components.versatile_thermostat.thermostat_climate import (
|
||||||
|
ThermostatOverClimate,
|
||||||
|
)
|
||||||
|
|
||||||
from .commons import * # pylint: disable=wildcard-import, unused-wildcard-import
|
from .commons import * # pylint: disable=wildcard-import, unused-wildcard-import
|
||||||
|
|
||||||
logging.getLogger().setLevel(logging.DEBUG)
|
logging.getLogger().setLevel(logging.DEBUG)
|
||||||
@@ -700,3 +709,150 @@ async def test_central_power_manager_max_power_event(
|
|||||||
|
|
||||||
assert central_power_manager.current_max_power == expected_power
|
assert central_power_manager.current_max_power == expected_power
|
||||||
assert mock_calculate_shedding.call_count == nb_call
|
assert mock_calculate_shedding.call_count == nb_call
|
||||||
|
|
||||||
|
|
||||||
|
async def test_central_power_manager_start_vtherm_power(hass: HomeAssistant, skip_hass_states_is_state, init_central_power_manager):
|
||||||
|
"""Tests the central power start VTherm power. The objective is to starts VTherm until the power max is exceeded"""
|
||||||
|
|
||||||
|
temps = {
|
||||||
|
"eco": 17,
|
||||||
|
"comfort": 18,
|
||||||
|
"boost": 19,
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
title="TheOverSwitchMockName",
|
||||||
|
unique_id="uniqueId",
|
||||||
|
data={
|
||||||
|
CONF_NAME: "TheOverSwitchMockName",
|
||||||
|
CONF_THERMOSTAT_TYPE: CONF_THERMOSTAT_SWITCH,
|
||||||
|
CONF_TEMP_SENSOR: "sensor.mock_temp_sensor",
|
||||||
|
CONF_EXTERNAL_TEMP_SENSOR: "sensor.mock_ext_temp_sensor",
|
||||||
|
CONF_CYCLE_MIN: 5,
|
||||||
|
CONF_TEMP_MIN: 15,
|
||||||
|
CONF_TEMP_MAX: 30,
|
||||||
|
CONF_USE_WINDOW_FEATURE: False,
|
||||||
|
CONF_USE_MOTION_FEATURE: False,
|
||||||
|
CONF_USE_POWER_FEATURE: True,
|
||||||
|
CONF_USE_PRESENCE_FEATURE: False,
|
||||||
|
CONF_UNDERLYING_LIST: ["switch.mock_switch"],
|
||||||
|
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
|
||||||
|
CONF_TPI_COEF_INT: 0.3,
|
||||||
|
CONF_TPI_COEF_EXT: 0.01,
|
||||||
|
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||||
|
CONF_SAFETY_DELAY_MIN: 5,
|
||||||
|
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||||
|
CONF_DEVICE_POWER: 1000,
|
||||||
|
CONF_PRESET_POWER: 12,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
entity: ThermostatOverSwitch = await create_thermostat(hass, entry, "climate.theoverswitchmockname", temps)
|
||||||
|
assert entity
|
||||||
|
|
||||||
|
now: datetime = NowClass.get_now(hass)
|
||||||
|
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||||
|
|
||||||
|
central_power_manager = VersatileThermostatAPI.get_vtherm_api().central_power_manager
|
||||||
|
assert central_power_manager
|
||||||
|
|
||||||
|
side_effects = SideEffects(
|
||||||
|
{
|
||||||
|
"sensor.the_power_sensor": State("sensor.the_power_sensor", 1000),
|
||||||
|
"sensor.the_max_power_sensor": State("sensor.the_max_power_sensor", 2100),
|
||||||
|
},
|
||||||
|
State("unknown.entity_id", "unknown"),
|
||||||
|
)
|
||||||
|
|
||||||
|
# 1. Make the heater heats
|
||||||
|
# fmt: off
|
||||||
|
with patch("homeassistant.core.StateMachine.get", side_effect=side_effects.get_side_effects()), \
|
||||||
|
patch("custom_components.versatile_thermostat.thermostat_switch.ThermostatOverSwitch.is_device_active", new_callable=PropertyMock, return_value=False):
|
||||||
|
# fmt: on
|
||||||
|
# make the heater heats
|
||||||
|
await send_power_change_event(entity, 1000, now)
|
||||||
|
await send_max_power_change_event(entity, 2100, now)
|
||||||
|
|
||||||
|
await send_temperature_change_event(entity, 15, now)
|
||||||
|
await send_ext_temperature_change_event(entity, 1, now)
|
||||||
|
|
||||||
|
await entity.async_set_preset_mode(PRESET_BOOST)
|
||||||
|
assert entity.preset_mode is PRESET_BOOST
|
||||||
|
assert entity.power_manager.overpowering_state is STATE_UNKNOWN
|
||||||
|
assert entity.target_temperature == 19
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
await entity.async_set_hvac_mode(HVACMode.HEAT)
|
||||||
|
assert entity.hvac_mode is HVACMode.HEAT
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
await asyncio.sleep(0.1)
|
||||||
|
|
||||||
|
# the power of Vtherm should have been added
|
||||||
|
assert central_power_manager.started_vtherm_total_power == 1000
|
||||||
|
|
||||||
|
# 2. Check that another heater cannot heat
|
||||||
|
entry2 = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
title="TheOverClimateMockName2",
|
||||||
|
unique_id="uniqueId2",
|
||||||
|
data={
|
||||||
|
CONF_NAME: "TheOverClimateMockName2",
|
||||||
|
CONF_THERMOSTAT_TYPE: CONF_THERMOSTAT_CLIMATE,
|
||||||
|
CONF_TEMP_SENSOR: "sensor.mock_temp_sensor",
|
||||||
|
CONF_EXTERNAL_TEMP_SENSOR: "sensor.mock_ext_temp_sensor",
|
||||||
|
CONF_CYCLE_MIN: 5,
|
||||||
|
CONF_TEMP_MIN: 15,
|
||||||
|
CONF_TEMP_MAX: 30,
|
||||||
|
CONF_USE_WINDOW_FEATURE: False,
|
||||||
|
CONF_USE_MOTION_FEATURE: False,
|
||||||
|
CONF_USE_POWER_FEATURE: True,
|
||||||
|
CONF_USE_PRESENCE_FEATURE: False,
|
||||||
|
CONF_UNDERLYING_LIST: ["switch.mock_climate"],
|
||||||
|
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||||
|
CONF_SAFETY_DELAY_MIN: 5,
|
||||||
|
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||||
|
CONF_DEVICE_POWER: 150,
|
||||||
|
CONF_PRESET_POWER: 12,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
entity2: ThermostatOverClimate = await create_thermostat(hass, entry2, "climate.theoverclimatemockname2", temps)
|
||||||
|
assert entity2
|
||||||
|
|
||||||
|
fake_underlying_climate = MockClimate(
|
||||||
|
hass=hass,
|
||||||
|
unique_id="mockUniqueId",
|
||||||
|
name="MockClimateName",
|
||||||
|
)
|
||||||
|
|
||||||
|
# fmt: off
|
||||||
|
with patch("homeassistant.core.StateMachine.get", side_effect=side_effects.get_side_effects()), \
|
||||||
|
patch("custom_components.versatile_thermostat.thermostat_switch.ThermostatOverSwitch.is_device_active", new_callable=PropertyMock, return_value=False), \
|
||||||
|
patch("custom_components.versatile_thermostat.underlyings.UnderlyingClimate.find_underlying_climate",return_value=fake_underlying_climate):
|
||||||
|
# fmt: on
|
||||||
|
# make the heater heats
|
||||||
|
await entity2.async_set_preset_mode(PRESET_COMFORT)
|
||||||
|
assert entity2.preset_mode is PRESET_COMFORT
|
||||||
|
assert entity2.power_manager.overpowering_state is STATE_UNKNOWN
|
||||||
|
assert entity2.target_temperature == 18
|
||||||
|
await entity2.async_set_hvac_mode(HVACMode.HEAT)
|
||||||
|
assert entity2.hvac_mode is HVACMode.HEAT
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
await asyncio.sleep(0.1)
|
||||||
|
|
||||||
|
# the power of Vtherm should have not been added (cause it has not started) and the entity2 should be shedding
|
||||||
|
assert central_power_manager.started_vtherm_total_power == 1000
|
||||||
|
|
||||||
|
|
||||||
|
assert entity2.power_manager.overpowering_state is STATE_ON
|
||||||
|
|
||||||
|
# 3. sends a new power sensor event
|
||||||
|
await send_max_power_change_event(entity, 2150, now)
|
||||||
|
# No change
|
||||||
|
assert central_power_manager.started_vtherm_total_power == 1000
|
||||||
|
|
||||||
|
await send_power_change_event(entity, 1010, now)
|
||||||
|
assert central_power_manager.started_vtherm_total_power == 0
|
||||||
|
|||||||
@@ -347,22 +347,17 @@ async def test_motion_management_time_not_enough(
|
|||||||
assert entity.presence_state == STATE_ON
|
assert entity.presence_state == STATE_ON
|
||||||
|
|
||||||
# 2. starts detecting motion with time not enough
|
# 2. starts detecting motion with time not enough
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=False,
|
return_value=False,
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.helpers.condition.state", return_value=False
|
"homeassistant.helpers.condition.state", return_value=False
|
||||||
) as mock_condition, patch(
|
) as mock_condition, patch(
|
||||||
"homeassistant.core.StateMachine.get",
|
"homeassistant.core.StateMachine.get",
|
||||||
return_value=State(
|
return_value=State(entity_id="binary_sensor.mock_motion_sensor", state=STATE_OFF),
|
||||||
entity_id="binary_sensor.mock_motion_sensor", state=STATE_OFF
|
|
||||||
),
|
|
||||||
):
|
):
|
||||||
event_timestamp = now - timedelta(minutes=4)
|
event_timestamp = now - timedelta(minutes=4)
|
||||||
try_condition = await send_motion_change_event(
|
try_condition = await send_motion_change_event(
|
||||||
@@ -387,14 +382,11 @@ async def test_motion_management_time_not_enough(
|
|||||||
assert mock_send_event.call_count == 0
|
assert mock_send_event.call_count == 0
|
||||||
|
|
||||||
# starts detecting motion with time enough this time
|
# starts detecting motion with time enough this time
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=False,
|
return_value=False,
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.helpers.condition.state", return_value=True
|
"homeassistant.helpers.condition.state", return_value=True
|
||||||
@@ -415,22 +407,17 @@ async def test_motion_management_time_not_enough(
|
|||||||
assert entity.presence_state == STATE_ON
|
assert entity.presence_state == STATE_ON
|
||||||
|
|
||||||
# stop detecting motion with off delay too low
|
# stop detecting motion with off delay too low
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=True,
|
return_value=True,
|
||||||
) as mock_device_active, patch(
|
) as mock_device_active, patch(
|
||||||
"homeassistant.helpers.condition.state", return_value=False
|
"homeassistant.helpers.condition.state", return_value=False
|
||||||
) as mock_condition, patch(
|
) as mock_condition, patch(
|
||||||
"homeassistant.core.StateMachine.get",
|
"homeassistant.core.StateMachine.get",
|
||||||
return_value=State(
|
return_value=State(entity_id="binary_sensor.mock_motion_sensor", state=STATE_OFF),
|
||||||
entity_id="binary_sensor.mock_motion_sensor", state=STATE_OFF
|
|
||||||
),
|
|
||||||
):
|
):
|
||||||
event_timestamp = now - timedelta(minutes=2)
|
event_timestamp = now - timedelta(minutes=2)
|
||||||
try_condition = await send_motion_change_event(
|
try_condition = await send_motion_change_event(
|
||||||
@@ -454,14 +441,11 @@ async def test_motion_management_time_not_enough(
|
|||||||
assert mock_send_event.call_count == 0
|
assert mock_send_event.call_count == 0
|
||||||
|
|
||||||
# stop detecting motion with off delay enough long
|
# stop detecting motion with off delay enough long
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=True,
|
return_value=True,
|
||||||
) as mock_device_active, patch(
|
) as mock_device_active, patch(
|
||||||
"homeassistant.helpers.condition.state", return_value=True
|
"homeassistant.helpers.condition.state", return_value=True
|
||||||
@@ -562,14 +546,11 @@ async def test_motion_management_time_enough_and_presence(
|
|||||||
assert entity.presence_state == "on"
|
assert entity.presence_state == "on"
|
||||||
|
|
||||||
# starts detecting motion
|
# starts detecting motion
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=False,
|
return_value=False,
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.helpers.condition.state", return_value=True
|
"homeassistant.helpers.condition.state", return_value=True
|
||||||
@@ -590,14 +571,11 @@ async def test_motion_management_time_enough_and_presence(
|
|||||||
assert mock_send_event.call_count == 0
|
assert mock_send_event.call_count == 0
|
||||||
|
|
||||||
# stop detecting motion with confirmation of stop
|
# stop detecting motion with confirmation of stop
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=True,
|
return_value=True,
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.helpers.condition.state", return_value=True
|
"homeassistant.helpers.condition.state", return_value=True
|
||||||
@@ -693,14 +671,11 @@ async def test_motion_management_time_enough_and_not_presence(
|
|||||||
assert entity.presence_state == STATE_OFF
|
assert entity.presence_state == STATE_OFF
|
||||||
|
|
||||||
# starts detecting motion
|
# starts detecting motion
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=False,
|
return_value=False,
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.helpers.condition.state", return_value=True
|
"homeassistant.helpers.condition.state", return_value=True
|
||||||
@@ -722,14 +697,11 @@ async def test_motion_management_time_enough_and_not_presence(
|
|||||||
assert mock_send_event.call_count == 0
|
assert mock_send_event.call_count == 0
|
||||||
|
|
||||||
# stop detecting motion with confirmation of stop
|
# stop detecting motion with confirmation of stop
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=True,
|
return_value=True,
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.helpers.condition.state", return_value=True
|
"homeassistant.helpers.condition.state", return_value=True
|
||||||
@@ -826,14 +798,11 @@ async def test_motion_management_with_stop_during_condition(
|
|||||||
assert entity.presence_state == STATE_OFF
|
assert entity.presence_state == STATE_OFF
|
||||||
|
|
||||||
# starts detecting motion
|
# starts detecting motion
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=True,
|
return_value=True,
|
||||||
), patch(
|
), patch(
|
||||||
"homeassistant.helpers.condition.state", return_value=True
|
"homeassistant.helpers.condition.state", return_value=True
|
||||||
@@ -959,12 +928,11 @@ async def test_motion_management_with_stop_during_condition_last_state_on(
|
|||||||
# 1. starts detecting motion but the sensor is off
|
# 1. starts detecting motion but the sensor is off
|
||||||
with patch(
|
with patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=True,
|
return_value=True,
|
||||||
), patch("homeassistant.helpers.condition.state", return_value=False), patch(
|
), patch("homeassistant.helpers.condition.state", return_value=False), patch(
|
||||||
"homeassistant.core.StateMachine.get",
|
"homeassistant.core.StateMachine.get",
|
||||||
return_value=State(
|
return_value=State(entity_id="binary_sensor.mock_motion_sensor", state=STATE_OFF),
|
||||||
entity_id="binary_sensor.mock_motion_sensor", state=STATE_OFF
|
|
||||||
),
|
|
||||||
):
|
):
|
||||||
event_timestamp = now - timedelta(minutes=5)
|
event_timestamp = now - timedelta(minutes=5)
|
||||||
try_condition1 = await send_motion_change_event(
|
try_condition1 = await send_motion_change_event(
|
||||||
@@ -982,12 +950,11 @@ async def test_motion_management_with_stop_during_condition_last_state_on(
|
|||||||
# 2. starts detecting motion but the sensor is on
|
# 2. starts detecting motion but the sensor is on
|
||||||
with patch(
|
with patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=True,
|
return_value=True,
|
||||||
), patch("homeassistant.helpers.condition.state", return_value=False), patch(
|
), patch("homeassistant.helpers.condition.state", return_value=False), patch(
|
||||||
"homeassistant.core.StateMachine.get",
|
"homeassistant.core.StateMachine.get",
|
||||||
return_value=State(
|
return_value=State(entity_id="binary_sensor.mock_motion_sensor", state=STATE_ON),
|
||||||
entity_id="binary_sensor.mock_motion_sensor", state=STATE_ON
|
|
||||||
),
|
|
||||||
):
|
):
|
||||||
event_timestamp = now - timedelta(minutes=5)
|
event_timestamp = now - timedelta(minutes=5)
|
||||||
try_condition1 = await send_motion_change_event(
|
try_condition1 = await send_motion_change_event(
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
""" Test the Multiple switch management """
|
""" Test the Multiple switch management """
|
||||||
import asyncio
|
import asyncio
|
||||||
from unittest.mock import patch, call, ANY
|
from unittest.mock import patch, call, ANY, PropertyMock
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@@ -84,14 +84,11 @@ async def test_one_switch_cycle(
|
|||||||
assert mock_is_state.call_count == 1
|
assert mock_is_state.call_count == 1
|
||||||
|
|
||||||
# Set temperature to a low level
|
# Set temperature to a low level
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=False,
|
return_value=False,
|
||||||
) as mock_device_active, patch(
|
) as mock_device_active, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.call_later",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.call_later",
|
||||||
@@ -107,7 +104,8 @@ async def test_one_switch_cycle(
|
|||||||
# assert mock_heater_on.call_count == 1
|
# assert mock_heater_on.call_count == 1
|
||||||
assert mock_heater_on.call_count == 0
|
assert mock_heater_on.call_count == 0
|
||||||
# There is no check if active
|
# There is no check if active
|
||||||
assert mock_device_active.call_count == 0
|
# don't work with PropertyMock
|
||||||
|
# assert mock_device_active.call_count == 0
|
||||||
|
|
||||||
# 4 calls dispatched along the cycle
|
# 4 calls dispatched along the cycle
|
||||||
assert mock_call_later.call_count == 1
|
assert mock_call_later.call_count == 1
|
||||||
@@ -119,14 +117,11 @@ async def test_one_switch_cycle(
|
|||||||
|
|
||||||
# Set a temperature at middle level
|
# Set a temperature at middle level
|
||||||
event_timestamp = now - timedelta(minutes=4)
|
event_timestamp = now - timedelta(minutes=4)
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=False,
|
return_value=False,
|
||||||
) as mock_device_active:
|
) as mock_device_active:
|
||||||
await send_temperature_change_event(entity, 18, event_timestamp)
|
await send_temperature_change_event(entity, 18, event_timestamp)
|
||||||
@@ -141,14 +136,11 @@ async def test_one_switch_cycle(
|
|||||||
|
|
||||||
# Set another temperature at middle level
|
# Set another temperature at middle level
|
||||||
event_timestamp = now - timedelta(minutes=3)
|
event_timestamp = now - timedelta(minutes=3)
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=True,
|
return_value=True,
|
||||||
) as mock_device_active:
|
) as mock_device_active:
|
||||||
await send_temperature_change_event(entity, 18.1, event_timestamp)
|
await send_temperature_change_event(entity, 18.1, event_timestamp)
|
||||||
@@ -176,14 +168,11 @@ async def test_one_switch_cycle(
|
|||||||
|
|
||||||
# Simulate the end of heater on cycle
|
# Simulate the end of heater on cycle
|
||||||
event_timestamp = now - timedelta(minutes=3)
|
event_timestamp = now - timedelta(minutes=3)
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=True,
|
return_value=True,
|
||||||
) as mock_device_active:
|
) as mock_device_active:
|
||||||
await entity.underlying_entity(
|
await entity.underlying_entity(
|
||||||
@@ -201,14 +190,11 @@ async def test_one_switch_cycle(
|
|||||||
|
|
||||||
# Simulate the start of heater on cycle
|
# Simulate the start of heater on cycle
|
||||||
event_timestamp = now - timedelta(minutes=3)
|
event_timestamp = now - timedelta(minutes=3)
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=True,
|
return_value=True,
|
||||||
) as mock_device_active:
|
) as mock_device_active:
|
||||||
await entity.underlying_entity(
|
await entity.underlying_entity(
|
||||||
@@ -306,14 +292,11 @@ async def test_multiple_switchs(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Set temperature to a low level
|
# Set temperature to a low level
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=False,
|
return_value=False,
|
||||||
) as mock_device_active, patch(
|
) as mock_device_active, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.call_later",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.call_later",
|
||||||
@@ -329,7 +312,8 @@ async def test_multiple_switchs(
|
|||||||
# assert mock_heater_on.call_count == 1
|
# assert mock_heater_on.call_count == 1
|
||||||
assert mock_heater_on.call_count == 0
|
assert mock_heater_on.call_count == 0
|
||||||
# There is no check if active
|
# There is no check if active
|
||||||
assert mock_device_active.call_count == 0
|
# don't work with PropertyMock
|
||||||
|
# assert mock_device_active.call_count == 0
|
||||||
|
|
||||||
# 4 calls dispatched along the cycle
|
# 4 calls dispatched along the cycle
|
||||||
assert mock_call_later.call_count == 4
|
assert mock_call_later.call_count == 4
|
||||||
@@ -344,14 +328,11 @@ async def test_multiple_switchs(
|
|||||||
|
|
||||||
# Set a temperature at middle level
|
# Set a temperature at middle level
|
||||||
event_timestamp = now - timedelta(minutes=4)
|
event_timestamp = now - timedelta(minutes=4)
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=False,
|
return_value=False,
|
||||||
) as mock_device_active:
|
) as mock_device_active:
|
||||||
await send_temperature_change_event(entity, 18, event_timestamp)
|
await send_temperature_change_event(entity, 18, event_timestamp)
|
||||||
@@ -818,7 +799,7 @@ async def test_multiple_switch_power_management(
|
|||||||
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, \
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, \
|
||||||
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on") as mock_heater_on, \
|
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on") as mock_heater_on, \
|
||||||
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, \
|
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, \
|
||||||
patch("custom_components.versatile_thermostat.thermostat_switch.ThermostatOverSwitch.is_device_active", return_value="True"):
|
patch("custom_components.versatile_thermostat.thermostat_switch.ThermostatOverSwitch.is_device_active", new_callable=PropertyMock, return_value=True):
|
||||||
#fmt: on
|
#fmt: on
|
||||||
now = now + timedelta(seconds=30)
|
now = now + timedelta(seconds=30)
|
||||||
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||||
|
|||||||
@@ -523,7 +523,7 @@ async def test_power_management_hvac_on(
|
|||||||
patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, \
|
patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, \
|
||||||
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on") as mock_heater_on, \
|
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on") as mock_heater_on, \
|
||||||
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, \
|
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, \
|
||||||
patch("custom_components.versatile_thermostat.thermostat_switch.ThermostatOverSwitch.is_device_active", return_value="True"):
|
patch("custom_components.versatile_thermostat.thermostat_switch.ThermostatOverSwitch.is_device_active", new_callable=PropertyMock, return_value=True):
|
||||||
# fmt: on
|
# fmt: on
|
||||||
now = now + timedelta(seconds=30)
|
now = now + timedelta(seconds=30)
|
||||||
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||||
@@ -913,12 +913,15 @@ async def test_power_management_turn_off_while_shedding(hass: HomeAssistant, ski
|
|||||||
|
|
||||||
# 1. Set VTherm to overpowering
|
# 1. Set VTherm to overpowering
|
||||||
# Send power max mesurement too low and HVACMode is on and device is active
|
# Send power max mesurement too low and HVACMode is on and device is active
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
# fmt:off
|
# fmt:off
|
||||||
with patch("homeassistant.core.StateMachine.get", side_effect=side_effects.get_side_effects()), \
|
with patch("homeassistant.core.StateMachine.get", side_effect=side_effects.get_side_effects()), \
|
||||||
patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"), \
|
patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"), \
|
||||||
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on") as mock_heater_on, \
|
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on") as mock_heater_on, \
|
||||||
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, \
|
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, \
|
||||||
patch("custom_components.versatile_thermostat.thermostat_switch.ThermostatOverSwitch.is_device_active", return_value="True"):
|
patch("custom_components.versatile_thermostat.thermostat_switch.ThermostatOverSwitch.is_device_active", new_callable=PropertyMock, return_value=True):
|
||||||
# fmt: on
|
# fmt: on
|
||||||
now = now + timedelta(seconds=30)
|
now = now + timedelta(seconds=30)
|
||||||
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||||
@@ -939,7 +942,7 @@ async def test_power_management_turn_off_while_shedding(hass: HomeAssistant, ski
|
|||||||
patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, \
|
patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, \
|
||||||
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on") as mock_heater_on, \
|
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on") as mock_heater_on, \
|
||||||
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, \
|
patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, \
|
||||||
patch("custom_components.versatile_thermostat.thermostat_switch.ThermostatOverSwitch.is_device_active", return_value="True"):
|
patch("custom_components.versatile_thermostat.thermostat_switch.ThermostatOverSwitch.is_device_active", new_callable=PropertyMock, return_value=True):
|
||||||
# fmt: on
|
# fmt: on
|
||||||
now = now + timedelta(seconds=30)
|
now = now + timedelta(seconds=30)
|
||||||
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||||
|
|||||||
@@ -2039,16 +2039,13 @@ async def test_bug_66(
|
|||||||
assert entity.window_state is STATE_UNKNOWN
|
assert entity.window_state is STATE_UNKNOWN
|
||||||
|
|
||||||
# Open the window and let the thermostat shut down
|
# Open the window and let the thermostat shut down
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"homeassistant.helpers.condition.state", return_value=True
|
"homeassistant.helpers.condition.state", return_value=True
|
||||||
) as mock_condition, patch(
|
) as mock_condition, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=True,
|
return_value=True,
|
||||||
):
|
):
|
||||||
await send_temperature_change_event(entity, 15, now)
|
await send_temperature_change_event(entity, 15, now)
|
||||||
@@ -2067,16 +2064,13 @@ async def test_bug_66(
|
|||||||
assert entity.window_state == STATE_ON
|
assert entity.window_state == STATE_ON
|
||||||
|
|
||||||
# Close the window but too shortly
|
# Close the window but too shortly
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"homeassistant.helpers.condition.state", return_value=False
|
"homeassistant.helpers.condition.state", return_value=False
|
||||||
) as mock_condition, patch(
|
) as mock_condition, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=False,
|
return_value=False,
|
||||||
):
|
):
|
||||||
event_timestamp = now + timedelta(minutes=1)
|
event_timestamp = now + timedelta(minutes=1)
|
||||||
@@ -2090,16 +2084,13 @@ async def test_bug_66(
|
|||||||
assert entity.window_state == STATE_ON
|
assert entity.window_state == STATE_ON
|
||||||
|
|
||||||
# Reopen immediatly with sufficient time
|
# Reopen immediatly with sufficient time
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"homeassistant.helpers.condition.state", return_value=True
|
"homeassistant.helpers.condition.state", return_value=True
|
||||||
) as mock_condition, patch(
|
) as mock_condition, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=False,
|
return_value=False,
|
||||||
):
|
):
|
||||||
try_window_condition = await send_window_change_event(
|
try_window_condition = await send_window_change_event(
|
||||||
@@ -2113,16 +2104,13 @@ async def test_bug_66(
|
|||||||
assert entity.hvac_mode == HVACMode.OFF
|
assert entity.hvac_mode == HVACMode.OFF
|
||||||
|
|
||||||
# Close the window but with sufficient time this time
|
# Close the window but with sufficient time this time
|
||||||
with patch(
|
with patch("custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event") as mock_send_event, patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
|
||||||
) as mock_send_event, patch(
|
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_on"
|
||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch("custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off") as mock_heater_off, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
|
||||||
) as mock_heater_off, patch(
|
|
||||||
"homeassistant.helpers.condition.state", return_value=True
|
"homeassistant.helpers.condition.state", return_value=True
|
||||||
) as mock_condition, patch(
|
) as mock_condition, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
new_callable=PropertyMock,
|
||||||
return_value=False,
|
return_value=False,
|
||||||
):
|
):
|
||||||
event_timestamp = now + timedelta(minutes=2)
|
event_timestamp = now + timedelta(minutes=2)
|
||||||
|
|||||||
Reference in New Issue
Block a user