Window bypass - add testu and color theme for sensor
This commit is contained in:
@@ -219,3 +219,4 @@ frontend:
|
|||||||
state-binary_sensor-window-on-color: "rgb(156, 39, 176)"
|
state-binary_sensor-window-on-color: "rgb(156, 39, 176)"
|
||||||
state-binary_sensor-motion-on-color: "rgb(156, 39, 176)"
|
state-binary_sensor-motion-on-color: "rgb(156, 39, 176)"
|
||||||
state-binary_sensor-presence-on-color: "lightgreen"
|
state-binary_sensor-presence-on-color: "lightgreen"
|
||||||
|
state-binary_sensor-running-on-color: "orange"
|
||||||
|
|||||||
@@ -518,6 +518,7 @@ frontend:
|
|||||||
state-binary_sensor-window-on-color: "rgb(156, 39, 176)"
|
state-binary_sensor-window-on-color: "rgb(156, 39, 176)"
|
||||||
state-binary_sensor-motion-on-color: "rgb(156, 39, 176)"
|
state-binary_sensor-motion-on-color: "rgb(156, 39, 176)"
|
||||||
state-binary_sensor-presence-on-color: "lightgreen"
|
state-binary_sensor-presence-on-color: "lightgreen"
|
||||||
|
state-binary_sensor-running-on-color: "orange"
|
||||||
```
|
```
|
||||||
et choisissez le thème ```versatile_thermostat_theme``` dans la configuration du panel. Vous obtiendrez quelque-chose qui va ressembler à ça :
|
et choisissez le thème ```versatile_thermostat_theme``` dans la configuration du panel. Vous obtiendrez quelque-chose qui va ressembler à ça :
|
||||||
|
|
||||||
|
|||||||
@@ -505,6 +505,7 @@ frontend:
|
|||||||
state-binary_sensor-window-on-color: "rgb(156, 39, 176)"
|
state-binary_sensor-window-on-color: "rgb(156, 39, 176)"
|
||||||
state-binary_sensor-motion-on-color: "rgb(156, 39, 176)"
|
state-binary_sensor-motion-on-color: "rgb(156, 39, 176)"
|
||||||
state-binary_sensor-presence-on-color: "lightgreen"
|
state-binary_sensor-presence-on-color: "lightgreen"
|
||||||
|
state-binary_sensor-running-on-color: "orange"
|
||||||
```
|
```
|
||||||
and choose the ```versatile_thermostat_theme``` theme in the panel configuration. You will get something that will look like this:
|
and choose the ```versatile_thermostat_theme``` theme in the panel configuration. You will get something that will look like this:
|
||||||
|
|
||||||
|
|||||||
@@ -1324,8 +1324,7 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
|||||||
#PR - Adding Window ByPass
|
#PR - Adding Window ByPass
|
||||||
_LOGGER.debug("%s - Window ByPass is : %s", self, self._window_bypass_state)
|
_LOGGER.debug("%s - Window ByPass is : %s", self, self._window_bypass_state)
|
||||||
if self._window_bypass_state:
|
if self._window_bypass_state:
|
||||||
_LOGGER.info("Window ByPass is activated. Ignore window event")
|
_LOGGER.info("%s - Window ByPass is activated. Ignore window event", self)
|
||||||
self.update_custom_attributes()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if self._window_state == STATE_OFF:
|
if self._window_state == STATE_OFF:
|
||||||
@@ -1706,6 +1705,11 @@ class BaseThermostat(ClimateEntity, RestoreEntity):
|
|||||||
self,
|
self,
|
||||||
slope if slope is not None else 0.0,
|
slope if slope is not None else 0.0,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if self.window_bypass_state:
|
||||||
|
_LOGGER.info("%s - Window auto event is ignored because bypass is ON", self)
|
||||||
|
return
|
||||||
|
|
||||||
if (
|
if (
|
||||||
self._window_auto_algo.is_window_open_detected()
|
self._window_auto_algo.is_window_open_detected()
|
||||||
and self._window_auto_state is False
|
and self._window_auto_state is False
|
||||||
|
|||||||
@@ -326,7 +326,7 @@
|
|||||||
"thermostat_type": {
|
"thermostat_type": {
|
||||||
"options": {
|
"options": {
|
||||||
"thermostat_over_switch": "Termostat nad spínačom",
|
"thermostat_over_switch": "Termostat nad spínačom",
|
||||||
"thermostat_over_climate": "Termostat nad iným termostatom"
|
"thermostat_over_climate": "Termostat nad iným termostatom",
|
||||||
"thermostat_over_valve": "Thermostat over a valve"
|
"thermostat_over_valve": "Thermostat over a valve"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
# pylint: disable=unused-argument, line-too-long
|
||||||
""" Test the OpenWindow algorithm """
|
""" Test the OpenWindow algorithm """
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from .commons import * # pylint: disable=wildcard-import, unused-wildcard-import
|
|
||||||
from custom_components.versatile_thermostat.open_window_algorithm import WindowOpenDetectionAlgorithm
|
from custom_components.versatile_thermostat.open_window_algorithm import WindowOpenDetectionAlgorithm
|
||||||
|
|
||||||
|
from .commons import * # pylint: disable=wildcard-import, unused-wildcard-import
|
||||||
|
|
||||||
|
|
||||||
async def test_open_window_algo(
|
async def test_open_window_algo(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
|
# pylint: disable=unused-argument, line-too-long, protected-access
|
||||||
""" Test the Window management """
|
""" Test the Window management """
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import logging
|
||||||
from unittest.mock import patch, call, PropertyMock
|
from unittest.mock import patch, call, PropertyMock
|
||||||
from .commons import * # pylint: disable=wildcard-import, unused-wildcard-import
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
import logging
|
from custom_components.versatile_thermostat.base_thermostat import BaseThermostat
|
||||||
|
from .commons import * # pylint: disable=wildcard-import, unused-wildcard-import
|
||||||
|
|
||||||
logging.getLogger().setLevel(logging.DEBUG)
|
logging.getLogger().setLevel(logging.DEBUG)
|
||||||
|
|
||||||
@@ -47,7 +49,7 @@ async def test_window_management_time_not_enough(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
entity: VersatileThermostat = await create_thermostat(
|
entity: BaseThermostat = await create_thermostat(
|
||||||
hass, entry, "climate.theoverswitchmockname"
|
hass, entry, "climate.theoverswitchmockname"
|
||||||
)
|
)
|
||||||
assert entity
|
assert entity
|
||||||
@@ -135,7 +137,7 @@ async def test_window_management_time_enough(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
entity: VersatileThermostat = await create_thermostat(
|
entity: BaseThermostat = await create_thermostat(
|
||||||
hass, entry, "climate.theoverswitchmockname"
|
hass, entry, "climate.theoverswitchmockname"
|
||||||
)
|
)
|
||||||
assert entity
|
assert entity
|
||||||
@@ -274,7 +276,7 @@ async def test_window_auto_fast(hass: HomeAssistant, skip_hass_states_is_state):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
entity: VersatileThermostat = await create_thermostat(
|
entity: BaseThermostat = await create_thermostat(
|
||||||
hass, entry, "climate.theoverswitchmockname"
|
hass, entry, "climate.theoverswitchmockname"
|
||||||
)
|
)
|
||||||
assert entity
|
assert entity
|
||||||
@@ -424,7 +426,7 @@ async def test_window_auto_fast(hass: HomeAssistant, skip_hass_states_is_state):
|
|||||||
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
||||||
@pytest.mark.parametrize("expected_lingering_timers", [True])
|
@pytest.mark.parametrize("expected_lingering_timers", [True])
|
||||||
async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_state):
|
async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_state):
|
||||||
"""Test the Power management"""
|
"""Test the Window auto management"""
|
||||||
|
|
||||||
entry = MockConfigEntry(
|
entry = MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
@@ -458,7 +460,7 @@ async def test_window_auto_auto_stop(hass: HomeAssistant, skip_hass_states_is_st
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
entity: VersatileThermostat = await create_thermostat(
|
entity: BaseThermostat = await create_thermostat(
|
||||||
hass, entry, "climate.theoverswitchmockname"
|
hass, entry, "climate.theoverswitchmockname"
|
||||||
)
|
)
|
||||||
assert entity
|
assert entity
|
||||||
@@ -603,7 +605,7 @@ async def test_window_auto_no_on_percent(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
entity: VersatileThermostat = await create_thermostat(
|
entity: BaseThermostat = await create_thermostat(
|
||||||
hass, entry, "climate.theoverswitchmockname"
|
hass, entry, "climate.theoverswitchmockname"
|
||||||
)
|
)
|
||||||
assert entity
|
assert entity
|
||||||
@@ -711,7 +713,7 @@ async def test_window_bypass(
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
entity: VersatileThermostat = await create_thermostat(
|
entity: BaseThermostat = await create_thermostat(
|
||||||
hass, entry, "climate.theoverswitchmockname"
|
hass, entry, "climate.theoverswitchmockname"
|
||||||
)
|
)
|
||||||
assert entity
|
assert entity
|
||||||
@@ -746,8 +748,11 @@ async def test_window_bypass(
|
|||||||
assert mock_heater_off.call_count == 0
|
assert mock_heater_off.call_count == 0
|
||||||
assert mock_send_event.call_count == 0
|
assert mock_send_event.call_count == 0
|
||||||
|
|
||||||
#Set Window ByPass to true
|
# Set Window ByPass to true
|
||||||
entity._window_bypass_state = True
|
await entity.service_set_window_bypass_state(True)
|
||||||
|
assert entity.window_bypass_state is True
|
||||||
|
|
||||||
|
# entity._window_bypass_state = True
|
||||||
|
|
||||||
# Open the window, condition of time is satisfied, check the thermostat and heater turns off
|
# Open the window, condition of time is satisfied, check the thermostat and heater turns off
|
||||||
with patch(
|
with patch(
|
||||||
@@ -804,3 +809,244 @@ async def test_window_bypass(
|
|||||||
|
|
||||||
# Clean the entity
|
# Clean the entity
|
||||||
entity.remove_thermostat()
|
entity.remove_thermostat()
|
||||||
|
|
||||||
|
#PR - Adding Window bypass for window auto algorithm
|
||||||
|
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
||||||
|
@pytest.mark.parametrize("expected_lingering_timers", [True])
|
||||||
|
async def test_window_auto_bypass(hass: HomeAssistant, skip_hass_states_is_state):
|
||||||
|
"""Test the Window auto management"""
|
||||||
|
|
||||||
|
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,
|
||||||
|
"eco_temp": 17,
|
||||||
|
"comfort_temp": 18,
|
||||||
|
"boost_temp": 21,
|
||||||
|
CONF_USE_WINDOW_FEATURE: True,
|
||||||
|
CONF_USE_MOTION_FEATURE: False,
|
||||||
|
CONF_USE_POWER_FEATURE: False,
|
||||||
|
CONF_USE_PRESENCE_FEATURE: False,
|
||||||
|
CONF_HEATER: "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_SECURITY_DELAY_MIN: 5,
|
||||||
|
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||||
|
CONF_WINDOW_AUTO_OPEN_THRESHOLD: 0.1,
|
||||||
|
CONF_WINDOW_AUTO_CLOSE_THRESHOLD: 0.1,
|
||||||
|
CONF_WINDOW_AUTO_MAX_DURATION: 0, # Should be 0 for test
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
entity: BaseThermostat = await create_thermostat(
|
||||||
|
hass, entry, "climate.theoverswitchmockname"
|
||||||
|
)
|
||||||
|
assert entity
|
||||||
|
|
||||||
|
tz = get_tz(hass) # pylint: disable=invalid-name
|
||||||
|
now = datetime.now(tz)
|
||||||
|
|
||||||
|
tpi_algo = entity._prop_algorithm
|
||||||
|
assert tpi_algo
|
||||||
|
|
||||||
|
await entity.async_set_hvac_mode(HVACMode.HEAT)
|
||||||
|
await entity.async_set_preset_mode(PRESET_BOOST)
|
||||||
|
assert entity.hvac_mode is HVACMode.HEAT
|
||||||
|
assert entity.preset_mode is PRESET_BOOST
|
||||||
|
assert entity.overpowering_state is None
|
||||||
|
assert entity.target_temperature == 21
|
||||||
|
|
||||||
|
assert entity.window_state is None
|
||||||
|
|
||||||
|
# Make the temperature down
|
||||||
|
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_off"
|
||||||
|
) as mock_heater_off, patch(
|
||||||
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
return_value=True,
|
||||||
|
):
|
||||||
|
event_timestamp = now - timedelta(minutes=4)
|
||||||
|
await send_temperature_change_event(entity, 19, event_timestamp)
|
||||||
|
|
||||||
|
# The heater turns on
|
||||||
|
assert mock_heater_on.call_count == 1
|
||||||
|
assert entity.last_temperature_slope is None
|
||||||
|
assert entity._window_auto_algo.is_window_open_detected() is False
|
||||||
|
assert entity._window_auto_algo.is_window_close_detected() is False
|
||||||
|
assert entity.hvac_mode is HVACMode.HEAT
|
||||||
|
|
||||||
|
# send one degre down in one minute with window bypass on
|
||||||
|
await entity.service_set_window_bypass_state(True)
|
||||||
|
assert entity.window_bypass_state is True
|
||||||
|
# entity._window_bypass_state = True
|
||||||
|
|
||||||
|
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_off"
|
||||||
|
) as mock_heater_off, patch(
|
||||||
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
return_value=True,
|
||||||
|
):
|
||||||
|
event_timestamp = now - timedelta(minutes=3)
|
||||||
|
await send_temperature_change_event(entity, 18, event_timestamp, sleep=False)
|
||||||
|
|
||||||
|
# No change should have been done
|
||||||
|
assert mock_send_event.call_count == 0
|
||||||
|
|
||||||
|
assert mock_heater_on.call_count == 0
|
||||||
|
assert mock_heater_off.call_count == 0
|
||||||
|
assert entity.last_temperature_slope == -1
|
||||||
|
assert entity._window_auto_algo.is_window_open_detected() is True
|
||||||
|
assert entity._window_auto_algo.is_window_close_detected() is False
|
||||||
|
assert entity.window_auto_state == STATE_OFF
|
||||||
|
assert entity.hvac_mode is HVACMode.HEAT
|
||||||
|
|
||||||
|
# Clean the entity
|
||||||
|
entity.remove_thermostat()
|
||||||
|
|
||||||
|
#PR - Adding Window bypass AFTER detection have been done should reactivate the heater
|
||||||
|
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
||||||
|
@pytest.mark.parametrize("expected_lingering_timers", [True])
|
||||||
|
async def test_window_bypass_reactivate(hass: HomeAssistant, skip_hass_states_is_state):
|
||||||
|
"""Test the Window management when window is open and then bypass is set to on"""
|
||||||
|
|
||||||
|
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,
|
||||||
|
"eco_temp": 17,
|
||||||
|
"comfort_temp": 18,
|
||||||
|
"boost_temp": 19,
|
||||||
|
CONF_USE_WINDOW_FEATURE: True,
|
||||||
|
CONF_USE_MOTION_FEATURE: False,
|
||||||
|
CONF_USE_POWER_FEATURE: False,
|
||||||
|
CONF_USE_PRESENCE_FEATURE: False,
|
||||||
|
CONF_HEATER: "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_SECURITY_DELAY_MIN: 5,
|
||||||
|
CONF_SECURITY_MIN_ON_PERCENT: 0.3,
|
||||||
|
CONF_WINDOW_SENSOR: "binary_sensor.mock_window_sensor",
|
||||||
|
CONF_WINDOW_DELAY: 0, # important to not been obliged to wait
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
entity: BaseThermostat = await create_thermostat(
|
||||||
|
hass, entry, "climate.theoverswitchmockname"
|
||||||
|
)
|
||||||
|
assert entity
|
||||||
|
|
||||||
|
tpi_algo = entity._prop_algorithm
|
||||||
|
assert tpi_algo
|
||||||
|
|
||||||
|
await entity.async_set_hvac_mode(HVACMode.HEAT)
|
||||||
|
await entity.async_set_preset_mode(PRESET_BOOST)
|
||||||
|
assert entity.hvac_mode is HVACMode.HEAT
|
||||||
|
assert entity.preset_mode is PRESET_BOOST
|
||||||
|
assert entity.overpowering_state is None
|
||||||
|
assert entity.target_temperature == 19
|
||||||
|
|
||||||
|
assert entity.window_state is None
|
||||||
|
|
||||||
|
# change temperature to force turning on the heater
|
||||||
|
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_off"
|
||||||
|
) as mock_heater_off, patch(
|
||||||
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
return_value=False,
|
||||||
|
):
|
||||||
|
await send_temperature_change_event(entity, 15, datetime.now())
|
||||||
|
|
||||||
|
# Heater shoud turn-on
|
||||||
|
assert mock_heater_on.call_count >= 1
|
||||||
|
assert mock_heater_off.call_count == 0
|
||||||
|
assert mock_send_event.call_count == 0
|
||||||
|
|
||||||
|
# Open the window, condition of time is satisfied, check the thermostat and heater turns off
|
||||||
|
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_off"
|
||||||
|
) as mock_heater_off, patch(
|
||||||
|
"homeassistant.helpers.condition.state", return_value=True
|
||||||
|
) as mock_condition, patch(
|
||||||
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
return_value=True,
|
||||||
|
):
|
||||||
|
await send_window_change_event(entity, True, False, datetime.now())
|
||||||
|
|
||||||
|
assert mock_send_event.call_count == 1
|
||||||
|
mock_send_event.assert_has_calls(
|
||||||
|
[call.send_event(EventType.HVAC_MODE_EVENT, {"hvac_mode": HVACMode.OFF})]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Heater should not be on
|
||||||
|
assert mock_heater_on.call_count == 0
|
||||||
|
# One call in set_hvac_mode turn_off and one call in the control_heating for security
|
||||||
|
assert mock_heater_off.call_count == 2
|
||||||
|
assert mock_condition.call_count == 1
|
||||||
|
assert entity.hvac_mode is HVACMode.OFF
|
||||||
|
assert entity.window_state == STATE_ON
|
||||||
|
|
||||||
|
# Call the set bypass service to set bypass ON
|
||||||
|
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_off"
|
||||||
|
) as mock_heater_off, patch(
|
||||||
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
|
return_value=False,
|
||||||
|
):
|
||||||
|
await entity.service_set_window_bypass_state(True)
|
||||||
|
|
||||||
|
assert entity.window_state == STATE_ON
|
||||||
|
assert entity.preset_mode is PRESET_BOOST
|
||||||
|
assert entity.hvac_mode is HVACMode.HEAT
|
||||||
|
# assert mock_heater_on.call_count == 1
|
||||||
|
assert mock_send_event.call_count == 1
|
||||||
|
mock_send_event.assert_has_calls(
|
||||||
|
[
|
||||||
|
call.send_event(
|
||||||
|
EventType.HVAC_MODE_EVENT, {"hvac_mode": HVACMode.HEAT}
|
||||||
|
),
|
||||||
|
],
|
||||||
|
any_order=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Clean the entity
|
||||||
|
entity.remove_thermostat()
|
||||||
Reference in New Issue
Block a user