All tests ok
This commit is contained in:
@@ -1111,3 +1111,9 @@ class SideEffects:
|
|||||||
def add_or_update_side_effect(self, key: str, new_value: Any):
|
def add_or_update_side_effect(self, key: str, new_value: Any):
|
||||||
"""Update the value of a side effect"""
|
"""Update the value of a side effect"""
|
||||||
self._current_side_effects[key] = new_value
|
self._current_side_effects[key] = new_value
|
||||||
|
|
||||||
|
|
||||||
|
async def do_central_power_refresh(hass):
|
||||||
|
"""Do a central power refresh"""
|
||||||
|
await VersatileThermostatAPI.get_vtherm_api().central_power_manager.refresh_state()
|
||||||
|
return hass.async_block_till_done()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# pylint: disable=wildcard-import, unused-wildcard-import, unused-argument, line-too-long
|
# 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
|
||||||
@@ -107,9 +107,16 @@ async def test_overpowering_binary_sensors(
|
|||||||
skip_hass_states_is_state,
|
skip_hass_states_is_state,
|
||||||
skip_turn_on_off_heater,
|
skip_turn_on_off_heater,
|
||||||
skip_send_event,
|
skip_send_event,
|
||||||
|
init_central_power_manager,
|
||||||
):
|
):
|
||||||
"""Test the overpowering binary sensors in thermostat type"""
|
"""Test the overpowering binary sensors in thermostat type"""
|
||||||
|
|
||||||
|
temps = {
|
||||||
|
"eco": 17,
|
||||||
|
"comfort": 18,
|
||||||
|
"boost": 19,
|
||||||
|
}
|
||||||
|
|
||||||
entry = MockConfigEntry(
|
entry = MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
title="TheOverSwitchMockName",
|
title="TheOverSwitchMockName",
|
||||||
@@ -122,9 +129,6 @@ async def test_overpowering_binary_sensors(
|
|||||||
CONF_CYCLE_MIN: 5,
|
CONF_CYCLE_MIN: 5,
|
||||||
CONF_TEMP_MIN: 15,
|
CONF_TEMP_MIN: 15,
|
||||||
CONF_TEMP_MAX: 30,
|
CONF_TEMP_MAX: 30,
|
||||||
"eco_temp": 17,
|
|
||||||
"comfort_temp": 18,
|
|
||||||
"boost_temp": 19,
|
|
||||||
CONF_USE_WINDOW_FEATURE: False,
|
CONF_USE_WINDOW_FEATURE: False,
|
||||||
CONF_USE_MOTION_FEATURE: False,
|
CONF_USE_MOTION_FEATURE: False,
|
||||||
CONF_USE_POWER_FEATURE: True,
|
CONF_USE_POWER_FEATURE: True,
|
||||||
@@ -136,15 +140,13 @@ async def test_overpowering_binary_sensors(
|
|||||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||||
CONF_SAFETY_DELAY_MIN: 5,
|
CONF_SAFETY_DELAY_MIN: 5,
|
||||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||||
CONF_POWER_SENSOR: "sensor.mock_power_sensor",
|
|
||||||
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
|
|
||||||
CONF_DEVICE_POWER: 100,
|
CONF_DEVICE_POWER: 100,
|
||||||
CONF_PRESET_POWER: 12,
|
CONF_PRESET_POWER: 12,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
entity: BaseThermostat = await create_thermostat(
|
entity: BaseThermostat = await create_thermostat(
|
||||||
hass, entry, "climate.theoverswitchmockname"
|
hass, entry, "climate.theoverswitchmockname", temps
|
||||||
)
|
)
|
||||||
assert entity
|
assert entity
|
||||||
|
|
||||||
@@ -153,7 +155,8 @@ async def test_overpowering_binary_sensors(
|
|||||||
)
|
)
|
||||||
assert overpowering_binary_sensor
|
assert overpowering_binary_sensor
|
||||||
|
|
||||||
now: datetime = datetime.now(tz=get_tz(hass))
|
now: datetime = NowClass.get_now(hass)
|
||||||
|
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||||
|
|
||||||
# Overpowering should be not set because poer have not been received
|
# Overpowering should be not set because poer have not been received
|
||||||
await entity.async_set_preset_mode(PRESET_COMFORT)
|
await entity.async_set_preset_mode(PRESET_COMFORT)
|
||||||
@@ -166,8 +169,20 @@ async def test_overpowering_binary_sensors(
|
|||||||
assert overpowering_binary_sensor.state is STATE_OFF
|
assert overpowering_binary_sensor.state is STATE_OFF
|
||||||
assert overpowering_binary_sensor.device_class == BinarySensorDeviceClass.POWER
|
assert overpowering_binary_sensor.device_class == BinarySensorDeviceClass.POWER
|
||||||
|
|
||||||
|
# Send power mesurement
|
||||||
|
side_effects = SideEffects(
|
||||||
|
{
|
||||||
|
"sensor.the_power_sensor": State("sensor.the_power_sensor", 100),
|
||||||
|
"sensor.the_max_power_sensor": State("sensor.the_max_power_sensor", 150),
|
||||||
|
},
|
||||||
|
State("unknown.entity_id", "unknown"),
|
||||||
|
)
|
||||||
|
# fmt:off
|
||||||
|
with patch("homeassistant.core.StateMachine.get", side_effect=side_effects.get_side_effects()):
|
||||||
|
# fmt: on
|
||||||
await send_power_change_event(entity, 100, now)
|
await send_power_change_event(entity, 100, now)
|
||||||
await send_max_power_change_event(entity, 150, now)
|
await send_max_power_change_event(entity, 150, now)
|
||||||
|
|
||||||
assert entity.power_manager.is_overpowering_detected is True
|
assert entity.power_manager.is_overpowering_detected is True
|
||||||
assert entity.power_manager.overpowering_state is STATE_ON
|
assert entity.power_manager.overpowering_state is STATE_ON
|
||||||
|
|
||||||
@@ -176,6 +191,12 @@ async def test_overpowering_binary_sensors(
|
|||||||
assert overpowering_binary_sensor.state == STATE_ON
|
assert overpowering_binary_sensor.state == STATE_ON
|
||||||
|
|
||||||
# set max power to a low value
|
# set max power to a low value
|
||||||
|
side_effects.add_or_update_side_effect("sensor.the_max_power_sensor", State("sensor.the_max_power_sensor", 201))
|
||||||
|
# fmt:off
|
||||||
|
with patch("homeassistant.core.StateMachine.get", side_effect=side_effects.get_side_effects()):
|
||||||
|
# fmt: on
|
||||||
|
now = now + timedelta(seconds=61)
|
||||||
|
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||||
await send_max_power_change_event(entity, 201, now)
|
await send_max_power_change_event(entity, 201, now)
|
||||||
assert entity.power_manager.is_overpowering_detected is False
|
assert entity.power_manager.is_overpowering_detected is False
|
||||||
assert entity.power_manager.overpowering_state is STATE_OFF
|
assert entity.power_manager.overpowering_state is STATE_OFF
|
||||||
|
|||||||
@@ -266,7 +266,9 @@ async def test_bug_272(
|
|||||||
|
|
||||||
@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_bug_407(hass: HomeAssistant, skip_hass_states_is_state):
|
async def test_bug_407(
|
||||||
|
hass: HomeAssistant, skip_hass_states_is_state, init_central_power_manager
|
||||||
|
):
|
||||||
"""Test the followin case in power management:
|
"""Test the followin case in power management:
|
||||||
1. a heater is active (heating). So the power consumption takes the heater power into account. We suppose the power consumption is near the threshold,
|
1. a heater is active (heating). So the power consumption takes the heater power into account. We suppose the power consumption is near the threshold,
|
||||||
2. the user switch preset let's say from Comfort to Boost,
|
2. the user switch preset let's say from Comfort to Boost,
|
||||||
@@ -275,6 +277,12 @@ async def test_bug_407(hass: HomeAssistant, skip_hass_states_is_state):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
temps = {
|
||||||
|
"eco": 17,
|
||||||
|
"comfort": 18,
|
||||||
|
"boost": 19,
|
||||||
|
}
|
||||||
|
|
||||||
entry = MockConfigEntry(
|
entry = MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
title="TheOverSwitchMockName",
|
title="TheOverSwitchMockName",
|
||||||
@@ -287,9 +295,6 @@ async def test_bug_407(hass: HomeAssistant, skip_hass_states_is_state):
|
|||||||
CONF_CYCLE_MIN: 5,
|
CONF_CYCLE_MIN: 5,
|
||||||
CONF_TEMP_MIN: 15,
|
CONF_TEMP_MIN: 15,
|
||||||
CONF_TEMP_MAX: 30,
|
CONF_TEMP_MAX: 30,
|
||||||
"eco_temp": 17,
|
|
||||||
"comfort_temp": 18,
|
|
||||||
"boost_temp": 19,
|
|
||||||
CONF_USE_WINDOW_FEATURE: False,
|
CONF_USE_WINDOW_FEATURE: False,
|
||||||
CONF_USE_MOTION_FEATURE: False,
|
CONF_USE_MOTION_FEATURE: False,
|
||||||
CONF_USE_POWER_FEATURE: True,
|
CONF_USE_POWER_FEATURE: True,
|
||||||
@@ -301,34 +306,43 @@ async def test_bug_407(hass: HomeAssistant, skip_hass_states_is_state):
|
|||||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||||
CONF_SAFETY_DELAY_MIN: 5,
|
CONF_SAFETY_DELAY_MIN: 5,
|
||||||
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
CONF_SAFETY_MIN_ON_PERCENT: 0.3,
|
||||||
CONF_POWER_SENSOR: "sensor.mock_power_sensor",
|
|
||||||
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
|
|
||||||
CONF_DEVICE_POWER: 100,
|
CONF_DEVICE_POWER: 100,
|
||||||
CONF_PRESET_POWER: 12,
|
CONF_PRESET_POWER: 12,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
entity: ThermostatOverSwitch = await create_thermostat(
|
entity: ThermostatOverSwitch = await create_thermostat(
|
||||||
hass, entry, "climate.theoverswitchmockname"
|
hass, entry, "climate.theoverswitchmockname", temps
|
||||||
)
|
)
|
||||||
assert entity
|
assert entity
|
||||||
|
|
||||||
tpi_algo = entity._prop_algorithm
|
tpi_algo = entity._prop_algorithm
|
||||||
assert tpi_algo
|
assert tpi_algo
|
||||||
|
|
||||||
tz = get_tz(hass) # pylint: disable=invalid-name
|
now: datetime = NowClass.get_now(hass)
|
||||||
now: datetime = datetime.now(tz=tz)
|
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||||
|
|
||||||
await send_temperature_change_event(entity, 16, now)
|
await send_temperature_change_event(entity, 16, now)
|
||||||
await send_ext_temperature_change_event(entity, 10, now)
|
await send_ext_temperature_change_event(entity, 10, now)
|
||||||
|
|
||||||
# 1. An already active heater will not switch to overpowering
|
# 1. An already active heater will not switch to overpowering
|
||||||
|
side_effects = SideEffects(
|
||||||
|
{
|
||||||
|
"sensor.the_power_sensor": State("sensor.the_power_sensor", 100),
|
||||||
|
"sensor.the_max_power_sensor": State("sensor.the_max_power_sensor", 110),
|
||||||
|
},
|
||||||
|
State("unknown.entity_id", "unknown"),
|
||||||
|
)
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.core.ServiceRegistry.async_call"
|
"homeassistant.core.ServiceRegistry.async_call"
|
||||||
) as mock_service_call, patch(
|
) as mock_service_call, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
new_callable=PropertyMock,
|
new_callable=PropertyMock,
|
||||||
return_value=True,
|
return_value=True,
|
||||||
|
), patch(
|
||||||
|
"homeassistant.core.StateMachine.get",
|
||||||
|
side_effect=side_effects.get_side_effects(),
|
||||||
):
|
):
|
||||||
await entity.async_set_hvac_mode(HVACMode.HEAT)
|
await entity.async_set_hvac_mode(HVACMode.HEAT)
|
||||||
await entity.async_set_preset_mode(PRESET_COMFORT)
|
await entity.async_set_preset_mode(PRESET_COMFORT)
|
||||||
@@ -337,14 +351,15 @@ async def test_bug_407(hass: HomeAssistant, skip_hass_states_is_state):
|
|||||||
assert entity.power_manager.overpowering_state is STATE_UNKNOWN
|
assert entity.power_manager.overpowering_state is STATE_UNKNOWN
|
||||||
assert entity.target_temperature == 18
|
assert entity.target_temperature == 18
|
||||||
# waits that the heater starts
|
# waits that the heater starts
|
||||||
await asyncio.sleep(0.1)
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert mock_service_call.call_count >= 1
|
assert mock_service_call.call_count >= 1
|
||||||
assert entity.is_device_active is True
|
assert entity.is_device_active is True
|
||||||
|
|
||||||
# Send power max mesurement
|
# Send power max mesurement
|
||||||
await send_max_power_change_event(entity, 110, datetime.now())
|
await send_max_power_change_event(entity, 110, now)
|
||||||
# Send power mesurement (theheater is already in the power measurement)
|
# Send power mesurement (theheater is already in the power measurement)
|
||||||
await send_power_change_event(entity, 100, datetime.now())
|
await send_power_change_event(entity, 100, now)
|
||||||
# No overpowering yet
|
# No overpowering yet
|
||||||
assert entity.power_manager.is_overpowering_detected is False
|
assert entity.power_manager.is_overpowering_detected is False
|
||||||
# All configuration is complete and power is < power_max
|
# All configuration is complete and power is < power_max
|
||||||
@@ -359,11 +374,22 @@ async def test_bug_407(hass: HomeAssistant, skip_hass_states_is_state):
|
|||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
new_callable=PropertyMock,
|
new_callable=PropertyMock,
|
||||||
return_value=True,
|
return_value=True,
|
||||||
|
), patch(
|
||||||
|
"homeassistant.core.StateMachine.get",
|
||||||
|
side_effect=side_effects.get_side_effects(),
|
||||||
):
|
):
|
||||||
|
now = now + timedelta(seconds=61)
|
||||||
|
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||||
|
|
||||||
# change preset to Boost
|
# change preset to Boost
|
||||||
await entity.async_set_preset_mode(PRESET_BOOST)
|
await entity.async_set_preset_mode(PRESET_BOOST)
|
||||||
# waits that the heater starts
|
# waits that the heater starts
|
||||||
await asyncio.sleep(0.1)
|
await asyncio.sleep(0.1)
|
||||||
|
# doesn't work for call_later
|
||||||
|
# await hass.async_block_till_done()
|
||||||
|
|
||||||
|
# simulate a refresh for central power (not necessary)
|
||||||
|
await do_central_power_refresh(hass)
|
||||||
|
|
||||||
assert entity.power_manager.is_overpowering_detected is False
|
assert entity.power_manager.is_overpowering_detected is False
|
||||||
assert entity.hvac_mode is HVACMode.HEAT
|
assert entity.hvac_mode is HVACMode.HEAT
|
||||||
@@ -379,12 +405,21 @@ async def test_bug_407(hass: HomeAssistant, skip_hass_states_is_state):
|
|||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||||
new_callable=PropertyMock,
|
new_callable=PropertyMock,
|
||||||
return_value=False,
|
return_value=False,
|
||||||
|
), patch(
|
||||||
|
"homeassistant.core.StateMachine.get",
|
||||||
|
side_effect=side_effects.get_side_effects(),
|
||||||
):
|
):
|
||||||
|
now = now + timedelta(seconds=61)
|
||||||
|
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||||
|
|
||||||
# change preset to Boost
|
# change preset to Boost
|
||||||
await entity.async_set_preset_mode(PRESET_COMFORT)
|
await entity.async_set_preset_mode(PRESET_COMFORT)
|
||||||
# waits that the heater starts
|
# waits that the heater starts
|
||||||
await asyncio.sleep(0.1)
|
await asyncio.sleep(0.1)
|
||||||
|
|
||||||
|
# simulate a refresh for central power (not necessary)
|
||||||
|
await do_central_power_refresh(hass)
|
||||||
|
|
||||||
assert entity.power_manager.is_overpowering_detected is True
|
assert entity.power_manager.is_overpowering_detected is True
|
||||||
assert entity.hvac_mode is HVACMode.HEAT
|
assert entity.hvac_mode is HVACMode.HEAT
|
||||||
assert entity.preset_mode is PRESET_POWER
|
assert entity.preset_mode is PRESET_POWER
|
||||||
|
|||||||
@@ -188,6 +188,18 @@ async def test_full_over_switch_wo_central_config(
|
|||||||
hass: HomeAssistant, skip_hass_states_is_state, init_vtherm_api
|
hass: HomeAssistant, skip_hass_states_is_state, init_vtherm_api
|
||||||
):
|
):
|
||||||
"""Tests that a VTherm without any central_configuration is working with its own attributes"""
|
"""Tests that a VTherm without any central_configuration is working with its own attributes"""
|
||||||
|
|
||||||
|
temps = {
|
||||||
|
"frost": 10,
|
||||||
|
"eco": 17,
|
||||||
|
"comfort": 18,
|
||||||
|
"boost": 21,
|
||||||
|
"frost_away": 13,
|
||||||
|
"eco_away": 13,
|
||||||
|
"comfort_away": 13,
|
||||||
|
"boost_away": 13,
|
||||||
|
}
|
||||||
|
|
||||||
# Add a Switch VTherm
|
# Add a Switch VTherm
|
||||||
entry = MockConfigEntry(
|
entry = MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
@@ -202,19 +214,11 @@ async def test_full_over_switch_wo_central_config(
|
|||||||
CONF_TEMP_MIN: 8,
|
CONF_TEMP_MIN: 8,
|
||||||
CONF_TEMP_MAX: 18,
|
CONF_TEMP_MAX: 18,
|
||||||
CONF_STEP_TEMPERATURE: 0.3,
|
CONF_STEP_TEMPERATURE: 0.3,
|
||||||
"frost_temp": 10,
|
|
||||||
"eco_temp": 17,
|
|
||||||
"comfort_temp": 18,
|
|
||||||
"boost_temp": 21,
|
|
||||||
"frost_away_temp": 13,
|
|
||||||
"eco_away_temp": 13,
|
|
||||||
"comfort_away_temp": 13,
|
|
||||||
"boost_away_temp": 13,
|
|
||||||
CONF_USE_WINDOW_FEATURE: True,
|
CONF_USE_WINDOW_FEATURE: True,
|
||||||
CONF_USE_MOTION_FEATURE: True,
|
CONF_USE_MOTION_FEATURE: True,
|
||||||
CONF_USE_POWER_FEATURE: True,
|
CONF_USE_POWER_FEATURE: True,
|
||||||
CONF_USE_PRESENCE_FEATURE: True,
|
CONF_USE_PRESENCE_FEATURE: True,
|
||||||
CONF_HEATER: "switch.mock_switch",
|
CONF_UNDERLYING_LIST: ["switch.mock_switch"],
|
||||||
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
|
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
|
||||||
CONF_INVERSE_SWITCH: False,
|
CONF_INVERSE_SWITCH: False,
|
||||||
CONF_TPI_COEF_INT: 0.3,
|
CONF_TPI_COEF_INT: 0.3,
|
||||||
@@ -233,8 +237,6 @@ async def test_full_over_switch_wo_central_config(
|
|||||||
CONF_MOTION_PRESET: "comfort",
|
CONF_MOTION_PRESET: "comfort",
|
||||||
CONF_NO_MOTION_PRESET: "eco",
|
CONF_NO_MOTION_PRESET: "eco",
|
||||||
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
|
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
|
||||||
CONF_POWER_SENSOR: "sensor.mock_power_sensor",
|
|
||||||
CONF_MAX_POWER_SENSOR: "sensor.mock_max_power_sensor",
|
|
||||||
CONF_PRESENCE_SENSOR: "binary_sensor.mock_presence_sensor",
|
CONF_PRESENCE_SENSOR: "binary_sensor.mock_presence_sensor",
|
||||||
CONF_USE_MAIN_CENTRAL_CONFIG: False,
|
CONF_USE_MAIN_CENTRAL_CONFIG: False,
|
||||||
CONF_USE_TPI_CENTRAL_CONFIG: False,
|
CONF_USE_TPI_CENTRAL_CONFIG: False,
|
||||||
@@ -249,7 +251,7 @@ async def test_full_over_switch_wo_central_config(
|
|||||||
|
|
||||||
with patch("homeassistant.core.ServiceRegistry.async_call"):
|
with patch("homeassistant.core.ServiceRegistry.async_call"):
|
||||||
entity: ThermostatOverSwitch = await create_thermostat(
|
entity: ThermostatOverSwitch = await create_thermostat(
|
||||||
hass, entry, "climate.theoverswitchmockname"
|
hass, entry, "climate.theoverswitchmockname", temps
|
||||||
)
|
)
|
||||||
assert entity
|
assert entity
|
||||||
assert entity.name == "TheOverSwitchMockName"
|
assert entity.name == "TheOverSwitchMockName"
|
||||||
@@ -300,10 +302,13 @@ async def test_full_over_switch_wo_central_config(
|
|||||||
assert entity.motion_manager.motion_preset == "comfort"
|
assert entity.motion_manager.motion_preset == "comfort"
|
||||||
assert entity.motion_manager.no_motion_preset == "eco"
|
assert entity.motion_manager.no_motion_preset == "eco"
|
||||||
|
|
||||||
assert entity.power_manager.power_sensor_entity_id == "sensor.mock_power_sensor"
|
|
||||||
assert (
|
assert (
|
||||||
entity.power_manager.max_power_sensor_entity_id
|
VersatileThermostatAPI.get_vtherm_api().central_power_manager.power_sensor_entity_id
|
||||||
== "sensor.mock_max_power_sensor"
|
is None
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
VersatileThermostatAPI.get_vtherm_api().central_power_manager.max_power_sensor_entity_id
|
||||||
|
is None
|
||||||
)
|
)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
@@ -317,7 +322,7 @@ async def test_full_over_switch_wo_central_config(
|
|||||||
@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_full_over_switch_with_central_config(
|
async def test_full_over_switch_with_central_config(
|
||||||
hass: HomeAssistant, skip_hass_states_is_state, init_central_config
|
hass: HomeAssistant, skip_hass_states_is_state, init_central_power_manager
|
||||||
):
|
):
|
||||||
"""Tests that a VTherm with central_configuration is working with the central_config attributes"""
|
"""Tests that a VTherm with central_configuration is working with the central_config attributes"""
|
||||||
# Add a Switch VTherm
|
# Add a Switch VTherm
|
||||||
@@ -334,15 +339,11 @@ async def test_full_over_switch_with_central_config(
|
|||||||
CONF_TEMP_MIN: 8,
|
CONF_TEMP_MIN: 8,
|
||||||
CONF_TEMP_MAX: 18,
|
CONF_TEMP_MAX: 18,
|
||||||
CONF_STEP_TEMPERATURE: 0.3,
|
CONF_STEP_TEMPERATURE: 0.3,
|
||||||
"frost_temp": 10,
|
|
||||||
"eco_temp": 17,
|
|
||||||
"comfort_temp": 18,
|
|
||||||
"boost_temp": 21,
|
|
||||||
CONF_USE_WINDOW_FEATURE: True,
|
CONF_USE_WINDOW_FEATURE: True,
|
||||||
CONF_USE_MOTION_FEATURE: True,
|
CONF_USE_MOTION_FEATURE: True,
|
||||||
CONF_USE_POWER_FEATURE: True,
|
CONF_USE_POWER_FEATURE: True,
|
||||||
CONF_USE_PRESENCE_FEATURE: True,
|
CONF_USE_PRESENCE_FEATURE: True,
|
||||||
CONF_HEATER: "switch.mock_switch",
|
CONF_UNDERLYING_LIST: ["switch.mock_switch"],
|
||||||
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
|
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
|
||||||
CONF_INVERSE_SWITCH: False,
|
CONF_INVERSE_SWITCH: False,
|
||||||
CONF_TPI_COEF_INT: 0.3,
|
CONF_TPI_COEF_INT: 0.3,
|
||||||
@@ -361,8 +362,6 @@ async def test_full_over_switch_with_central_config(
|
|||||||
CONF_MOTION_PRESET: "comfort",
|
CONF_MOTION_PRESET: "comfort",
|
||||||
CONF_NO_MOTION_PRESET: "eco",
|
CONF_NO_MOTION_PRESET: "eco",
|
||||||
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
|
CONF_MOTION_SENSOR: "binary_sensor.mock_motion_sensor",
|
||||||
CONF_POWER_SENSOR: "sensor.mock_power_sensor",
|
|
||||||
CONF_MAX_POWER_SENSOR: "sensor.mock_max_power_sensor",
|
|
||||||
CONF_PRESENCE_SENSOR: "binary_sensor.mock_presence_sensor",
|
CONF_PRESENCE_SENSOR: "binary_sensor.mock_presence_sensor",
|
||||||
CONF_USE_MAIN_CENTRAL_CONFIG: True,
|
CONF_USE_MAIN_CENTRAL_CONFIG: True,
|
||||||
CONF_USE_TPI_CENTRAL_CONFIG: True,
|
CONF_USE_TPI_CENTRAL_CONFIG: True,
|
||||||
@@ -426,10 +425,13 @@ async def test_full_over_switch_with_central_config(
|
|||||||
assert entity.motion_manager.motion_preset == "boost"
|
assert entity.motion_manager.motion_preset == "boost"
|
||||||
assert entity.motion_manager.no_motion_preset == "frost"
|
assert entity.motion_manager.no_motion_preset == "frost"
|
||||||
|
|
||||||
assert entity.power_manager.power_sensor_entity_id == "sensor.mock_power_sensor"
|
|
||||||
assert (
|
assert (
|
||||||
entity.power_manager.max_power_sensor_entity_id
|
VersatileThermostatAPI.get_vtherm_api().central_power_manager.power_sensor_entity_id
|
||||||
== "sensor.mock_max_power_sensor"
|
== "sensor.the_power_sensor"
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
VersatileThermostatAPI.get_vtherm_api().central_power_manager.max_power_sensor_entity_id
|
||||||
|
== "sensor.the_max_power_sensor"
|
||||||
)
|
)
|
||||||
|
|
||||||
assert (
|
assert (
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ async def test_central_power_manageer_find_vtherms(
|
|||||||
"is_overpowering_detected": False,
|
"is_overpowering_detected": False,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
{},
|
{"vtherm1": False},
|
||||||
),
|
),
|
||||||
# Simple trivial shedding
|
# Simple trivial shedding
|
||||||
(
|
(
|
||||||
|
|||||||
@@ -721,10 +721,14 @@ async def test_multiple_climates_underlying_changes_not_aligned(
|
|||||||
@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_multiple_switch_power_management(
|
async def test_multiple_switch_power_management(
|
||||||
hass: HomeAssistant, skip_hass_states_is_state
|
hass: HomeAssistant, skip_hass_states_is_state, init_central_power_manager
|
||||||
):
|
):
|
||||||
"""Test the Power management"""
|
"""Test the Power management"""
|
||||||
|
temps = {
|
||||||
|
"eco": 17,
|
||||||
|
"comfort": 18,
|
||||||
|
"boost": 19,
|
||||||
|
}
|
||||||
entry = MockConfigEntry(
|
entry = MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
title="TheOverSwitchMockName",
|
title="TheOverSwitchMockName",
|
||||||
@@ -737,17 +741,16 @@ async def test_multiple_switch_power_management(
|
|||||||
CONF_CYCLE_MIN: 8,
|
CONF_CYCLE_MIN: 8,
|
||||||
CONF_TEMP_MIN: 15,
|
CONF_TEMP_MIN: 15,
|
||||||
CONF_TEMP_MAX: 30,
|
CONF_TEMP_MAX: 30,
|
||||||
"eco_temp": 17,
|
|
||||||
"comfort_temp": 18,
|
|
||||||
"boost_temp": 19,
|
|
||||||
CONF_USE_WINDOW_FEATURE: False,
|
CONF_USE_WINDOW_FEATURE: False,
|
||||||
CONF_USE_MOTION_FEATURE: False,
|
CONF_USE_MOTION_FEATURE: False,
|
||||||
CONF_USE_POWER_FEATURE: True,
|
CONF_USE_POWER_FEATURE: True,
|
||||||
CONF_USE_PRESENCE_FEATURE: False,
|
CONF_USE_PRESENCE_FEATURE: False,
|
||||||
CONF_HEATER: "switch.mock_switch1",
|
CONF_UNDERLYING_LIST: [
|
||||||
CONF_HEATER_2: "switch.mock_switch2",
|
"switch.mock_switch1",
|
||||||
CONF_HEATER_3: "switch.mock_switch3",
|
"switch.mock_switch2",
|
||||||
CONF_HEATER_4: "switch.mock_switch4",
|
"switch.mock_switch3",
|
||||||
|
"switch.mock_switch4",
|
||||||
|
],
|
||||||
CONF_HEATER_KEEP_ALIVE: 0,
|
CONF_HEATER_KEEP_ALIVE: 0,
|
||||||
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
CONF_MINIMAL_ACTIVATION_DELAY: 30,
|
||||||
CONF_SAFETY_DELAY_MIN: 5,
|
CONF_SAFETY_DELAY_MIN: 5,
|
||||||
@@ -755,15 +758,13 @@ async def test_multiple_switch_power_management(
|
|||||||
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
|
CONF_PROP_FUNCTION: PROPORTIONAL_FUNCTION_TPI,
|
||||||
CONF_TPI_COEF_INT: 0.3,
|
CONF_TPI_COEF_INT: 0.3,
|
||||||
CONF_TPI_COEF_EXT: 0.01,
|
CONF_TPI_COEF_EXT: 0.01,
|
||||||
CONF_POWER_SENSOR: "sensor.mock_power_sensor",
|
|
||||||
CONF_MAX_POWER_SENSOR: "sensor.mock_power_max_sensor",
|
|
||||||
CONF_DEVICE_POWER: 100,
|
CONF_DEVICE_POWER: 100,
|
||||||
CONF_PRESET_POWER: 12,
|
CONF_PRESET_POWER: 12,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
entity: BaseThermostat = await create_thermostat(
|
entity: BaseThermostat = await create_thermostat(
|
||||||
hass, entry, "climate.theover4switchmockname"
|
hass, entry, "climate.theover4switchmockname", temps
|
||||||
)
|
)
|
||||||
assert entity
|
assert entity
|
||||||
assert entity.is_over_climate is False
|
assert entity.is_over_climate is False
|
||||||
@@ -772,6 +773,9 @@ async def test_multiple_switch_power_management(
|
|||||||
tpi_algo = entity._prop_algorithm
|
tpi_algo = entity._prop_algorithm
|
||||||
assert tpi_algo
|
assert tpi_algo
|
||||||
|
|
||||||
|
now: datetime = NowClass.get_now(hass)
|
||||||
|
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||||
|
|
||||||
await entity.async_set_hvac_mode(HVACMode.HEAT)
|
await entity.async_set_hvac_mode(HVACMode.HEAT)
|
||||||
await entity.async_set_preset_mode(PRESET_BOOST)
|
await entity.async_set_preset_mode(PRESET_BOOST)
|
||||||
assert entity.hvac_mode is HVACMode.HEAT
|
assert entity.hvac_mode is HVACMode.HEAT
|
||||||
@@ -780,8 +784,22 @@ async def test_multiple_switch_power_management(
|
|||||||
assert entity.target_temperature == 19
|
assert entity.target_temperature == 19
|
||||||
|
|
||||||
# 1. Send power mesurement
|
# 1. Send power mesurement
|
||||||
await send_power_change_event(entity, 50, datetime.now())
|
side_effects = SideEffects(
|
||||||
|
{
|
||||||
|
"sensor.the_power_sensor": State("sensor.the_power_sensor", 50),
|
||||||
|
"sensor.the_max_power_sensor": State("sensor.the_max_power_sensor", 300),
|
||||||
|
},
|
||||||
|
State("unknown.entity_id", "unknown"),
|
||||||
|
)
|
||||||
|
|
||||||
# Send power max mesurement
|
# Send power max mesurement
|
||||||
|
# fmt:off
|
||||||
|
with patch("homeassistant.core.StateMachine.get", side_effect=side_effects.get_side_effects()):
|
||||||
|
# fmt: on
|
||||||
|
now = now + timedelta(seconds=61)
|
||||||
|
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||||
|
|
||||||
|
await send_power_change_event(entity, 50, datetime.now())
|
||||||
await send_max_power_change_event(entity, 300, datetime.now())
|
await send_max_power_change_event(entity, 300, datetime.now())
|
||||||
assert entity.power_manager.is_overpowering_detected is False
|
assert entity.power_manager.is_overpowering_detected is False
|
||||||
# All configuration is complete and power is < power_max
|
# All configuration is complete and power is < power_max
|
||||||
@@ -789,6 +807,8 @@ async def test_multiple_switch_power_management(
|
|||||||
assert entity.power_manager.overpowering_state is STATE_OFF
|
assert entity.power_manager.overpowering_state is STATE_OFF
|
||||||
|
|
||||||
# 2. Send power max mesurement too low and HVACMode is on
|
# 2. Send power max mesurement too low and HVACMode is on
|
||||||
|
side_effects.add_or_update_side_effect("sensor.the_max_power_sensor", State("sensor.the_max_power_sensor", 74))
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
||||||
) as mock_send_event, patch(
|
) as mock_send_event, patch(
|
||||||
@@ -796,6 +816,9 @@ async def test_multiple_switch_power_management(
|
|||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
||||||
) as mock_heater_off:
|
) as mock_heater_off:
|
||||||
|
|
||||||
|
now = now + timedelta(seconds=61)
|
||||||
|
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||||
# 100 of the device / 4 -> 25, current power 50 so max is 75
|
# 100 of the device / 4 -> 25, current power 50 so max is 75
|
||||||
await send_max_power_change_event(entity, 74, datetime.now())
|
await send_max_power_change_event(entity, 74, datetime.now())
|
||||||
assert entity.power_manager.is_overpowering_detected is True
|
assert entity.power_manager.is_overpowering_detected is True
|
||||||
@@ -828,12 +851,17 @@ async def test_multiple_switch_power_management(
|
|||||||
with patch(
|
with patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
||||||
) as mock_send_event:
|
) as mock_send_event:
|
||||||
|
now = now + timedelta(seconds=61)
|
||||||
|
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||||
|
|
||||||
await entity.async_set_preset_mode(PRESET_ECO)
|
await entity.async_set_preset_mode(PRESET_ECO)
|
||||||
assert entity.preset_mode is PRESET_ECO
|
assert entity.preset_mode is PRESET_ECO
|
||||||
# No change
|
# No change
|
||||||
assert entity.power_manager.overpowering_state is STATE_ON
|
assert entity.power_manager.overpowering_state is STATE_ON
|
||||||
|
|
||||||
# 4. Send hugh power max mesurement to release overpowering
|
# 4. Send hugh power max mesurement to release overpowering
|
||||||
|
side_effects.add_or_update_side_effect("sensor.the_max_power_sensor", State("sensor.the_max_power_sensor", 150))
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
"custom_components.versatile_thermostat.base_thermostat.BaseThermostat.send_event"
|
||||||
) as mock_send_event, patch(
|
) as mock_send_event, patch(
|
||||||
@@ -841,6 +869,9 @@ async def test_multiple_switch_power_management(
|
|||||||
) as mock_heater_on, patch(
|
) as mock_heater_on, patch(
|
||||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.turn_off"
|
||||||
) as mock_heater_off:
|
) as mock_heater_off:
|
||||||
|
now = now + timedelta(seconds=61)
|
||||||
|
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||||
|
|
||||||
# 100 of the device / 4 -> 25, current power 50 so max is 75. With 150 no overheating
|
# 100 of the device / 4 -> 25, current power 50 so max is 75. With 150 no overheating
|
||||||
await send_max_power_change_event(entity, 150, datetime.now())
|
await send_max_power_change_event(entity, 150, datetime.now())
|
||||||
assert entity.power_manager.is_overpowering_detected is False
|
assert entity.power_manager.is_overpowering_detected is False
|
||||||
|
|||||||
Reference in New Issue
Block a user