[Feature Request] - Pwoer shedding should prevent all VTherm to start at the same time (#845)
Fixes #844 Co-authored-by: Jean-Marc Collin <jean-marc.collin-extern@renault.com>
This commit is contained in:
@@ -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):
|
||||||
|
|||||||
@@ -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