Issue_766-enhance_power_management (#778)
* First implem + tests (not finished) * With tests of calculate_shedding ok * Commit for rebase * All tests ok for central_feature_power_manager * All tests not ok * All tests ok * integrattion tests - Do startup works * enhance the overpowering algo if current_power > max_power * Change shedding calculation delay to 20 sec (vs 60 sec) * Integration tests ok * Fix overpowering is set even if other heater have on_percent = 0 * Fix too much shedding in over_climate * Add logs * Add temporal filter for calculate_shedding Add restore overpowering state at startup * Fix restore overpowering_state * Removes poweer_entity_id from vtherm non central config * Release * Add Sonoff TRVZB in creation.md * Add comment on Sonoff TRVZB Closing degree --------- Co-authored-by: Jean-Marc Collin <jean-marc.collin-extern@renault.com>
This commit is contained in:
@@ -266,7 +266,9 @@ async def test_bug_272(
|
||||
|
||||
@pytest.mark.parametrize("expected_lingering_tasks", [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:
|
||||
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,
|
||||
@@ -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(
|
||||
domain=DOMAIN,
|
||||
title="TheOverSwitchMockName",
|
||||
@@ -287,9 +295,6 @@ async def test_bug_407(hass: HomeAssistant, skip_hass_states_is_state):
|
||||
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: False,
|
||||
CONF_USE_MOTION_FEATURE: False,
|
||||
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_SAFETY_DELAY_MIN: 5,
|
||||
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_PRESET_POWER: 12,
|
||||
},
|
||||
)
|
||||
|
||||
entity: ThermostatOverSwitch = await create_thermostat(
|
||||
hass, entry, "climate.theoverswitchmockname"
|
||||
hass, entry, "climate.theoverswitchmockname", temps
|
||||
)
|
||||
assert entity
|
||||
|
||||
tpi_algo = entity._prop_algorithm
|
||||
assert tpi_algo
|
||||
|
||||
tz = get_tz(hass) # pylint: disable=invalid-name
|
||||
now: datetime = datetime.now(tz=tz)
|
||||
now: datetime = NowClass.get_now(hass)
|
||||
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||
|
||||
await send_temperature_change_event(entity, 16, now)
|
||||
await send_ext_temperature_change_event(entity, 10, now)
|
||||
|
||||
# 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(
|
||||
"homeassistant.core.ServiceRegistry.async_call"
|
||||
) as mock_service_call, patch(
|
||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||
new_callable=PropertyMock,
|
||||
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_preset_mode(PRESET_COMFORT)
|
||||
@@ -337,16 +351,17 @@ async def test_bug_407(hass: HomeAssistant, skip_hass_states_is_state):
|
||||
assert entity.power_manager.overpowering_state is STATE_UNKNOWN
|
||||
assert entity.target_temperature == 18
|
||||
# waits that the heater starts
|
||||
await asyncio.sleep(0.1)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_service_call.call_count >= 1
|
||||
assert entity.is_device_active is True
|
||||
|
||||
# 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)
|
||||
await send_power_change_event(entity, 100, datetime.now())
|
||||
await send_power_change_event(entity, 100, now)
|
||||
# No overpowering yet
|
||||
assert await entity.power_manager.check_overpowering() is False
|
||||
assert entity.power_manager.is_overpowering_detected is False
|
||||
# All configuration is complete and power is < power_max
|
||||
assert entity.preset_mode is PRESET_COMFORT
|
||||
assert entity.power_manager.overpowering_state is STATE_OFF
|
||||
@@ -359,36 +374,57 @@ async def test_bug_407(hass: HomeAssistant, skip_hass_states_is_state):
|
||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||
new_callable=PropertyMock,
|
||||
return_value=True,
|
||||
), patch(
|
||||
"homeassistant.core.StateMachine.get",
|
||||
side_effect=side_effects.get_side_effects(),
|
||||
):
|
||||
now = now + timedelta(seconds=30)
|
||||
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||
|
||||
# change preset to Boost
|
||||
await entity.async_set_preset_mode(PRESET_BOOST)
|
||||
# waits that the heater starts
|
||||
await asyncio.sleep(0.1)
|
||||
# doesn't work for call_later
|
||||
# await hass.async_block_till_done()
|
||||
|
||||
assert await entity.power_manager.check_overpowering() is False
|
||||
# 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.hvac_mode is HVACMode.HEAT
|
||||
assert entity.preset_mode is PRESET_BOOST
|
||||
assert entity.power_manager.overpowering_state is STATE_OFF
|
||||
assert entity.target_temperature == 19
|
||||
assert mock_service_call.call_count >= 1
|
||||
|
||||
# 3. if heater is stopped (is_device_active==False), then overpowering should be started
|
||||
# 3. if heater is stopped (is_device_active==False) and power is over max, then overpowering should be started
|
||||
side_effects.add_or_update_side_effect("sensor.the_power_sensor", State("sensor.the_power_sensor", 150))
|
||||
with patch(
|
||||
"homeassistant.core.ServiceRegistry.async_call"
|
||||
) as mock_service_call, patch(
|
||||
"custom_components.versatile_thermostat.underlyings.UnderlyingSwitch.is_device_active",
|
||||
new_callable=PropertyMock,
|
||||
return_value=False,
|
||||
), patch(
|
||||
"homeassistant.core.StateMachine.get",
|
||||
side_effect=side_effects.get_side_effects(),
|
||||
):
|
||||
now = now + timedelta(seconds=30)
|
||||
VersatileThermostatAPI.get_vtherm_api()._set_now(now)
|
||||
|
||||
# change preset to Boost
|
||||
await entity.async_set_preset_mode(PRESET_COMFORT)
|
||||
# waits that the heater starts
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
assert await entity.power_manager.check_overpowering() is True
|
||||
# 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.hvac_mode is HVACMode.HEAT
|
||||
assert entity.preset_mode is PRESET_POWER
|
||||
assert entity.power_manager.overpowering_state is STATE_ON
|
||||
assert entity.preset_mode is PRESET_COMFORT
|
||||
assert entity.power_manager.overpowering_state is STATE_OFF
|
||||
|
||||
|
||||
@pytest.mark.parametrize("expected_lingering_tasks", [True])
|
||||
@@ -445,8 +481,6 @@ async def test_bug_500_3(hass: HomeAssistant, init_vtherm_api) -> None:
|
||||
CONF_USE_WINDOW_CENTRAL_CONFIG: False,
|
||||
CONF_WINDOW_SENSOR: "sensor.theWindowSensor",
|
||||
CONF_USE_POWER_CENTRAL_CONFIG: False,
|
||||
CONF_POWER_SENSOR: "sensor.thePowerSensor",
|
||||
CONF_MAX_POWER_SENSOR: "sensor.theMaxPowerSensor",
|
||||
CONF_USE_PRESENCE_CENTRAL_CONFIG: False,
|
||||
CONF_PRESENCE_SENSOR: "sensor.thePresenceSensor",
|
||||
CONF_USE_MOTION_FEATURE: True, # motion sensor need to be checked AND a motion sensor set
|
||||
@@ -456,7 +490,7 @@ async def test_bug_500_3(hass: HomeAssistant, init_vtherm_api) -> None:
|
||||
flow = VersatileThermostatBaseConfigFlow(config)
|
||||
|
||||
assert flow._infos[CONF_USE_WINDOW_FEATURE] is True
|
||||
assert flow._infos[CONF_USE_POWER_FEATURE] is True
|
||||
assert flow._infos[CONF_USE_POWER_FEATURE] is False
|
||||
assert flow._infos[CONF_USE_PRESENCE_FEATURE] is True
|
||||
assert flow._infos[CONF_USE_MOTION_FEATURE] is True
|
||||
|
||||
|
||||
Reference in New Issue
Block a user