Use scheduled current preset (if set), when setting HVAC mode in AVM Fritz!Smarthome (#126044)

* Use temperature of current preset when set fritz HVAC mode to HEAT

If the HVAC mode of the Fritzbox thermostats changes from `HVACMode.OFF`
to `HVAMode.HEAT`, the current preset (COMFORT / ECO) should be
observed. Depending on the status of the current preset, the set
temperature of comfort / eco is set as the new temperature.

* fixup do not use value_scheduled_preset

Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com>

* Add current_preset value to test_set_hvac_mode

The current_preset parameter allows the mock to be set to an active
preset. When setting HVACMode.HEAT, the respective temperature of the
ECO/COMFORT preset should be set.

* fixup Use the updated value_scheduled_preset function

To distinguish which temperature should be used when setting the
`HVAMode.HEAT`, `value_schedules_preset` is now used again, which has
been updated since the first commit. If no schedule is active, the
comfort_temperature is used. Otherwise, the respective temperature of
the current preset.

Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com>

---------

Co-authored-by: Michael <35783820+mib1185@users.noreply.github.com>
This commit is contained in:
Sven Sager 2024-09-30 16:29:39 +02:00 committed by GitHub
parent c92169cb20
commit 74931071de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 32 additions and 6 deletions

View File

@ -33,6 +33,7 @@ from .const import (
from .coordinator import FritzboxConfigEntry, FritzboxDataUpdateCoordinator
from .entity import FritzBoxDeviceEntity
from .model import ClimateExtraAttributes
from .sensor import value_scheduled_preset
HVAC_MODES = [HVACMode.HEAT, HVACMode.OFF]
PRESET_HOLIDAY = "holiday"
@ -177,7 +178,11 @@ class FritzboxThermostat(FritzBoxDeviceEntity, ClimateEntity):
if hvac_mode == HVACMode.OFF:
await self.async_set_temperature(temperature=OFF_REPORT_SET_TEMPERATURE)
else:
await self.async_set_temperature(temperature=self.data.comfort_temperature)
if value_scheduled_preset(self.data) == PRESET_ECO:
target_temp = self.data.eco_temperature
else:
target_temp = self.data.comfort_temperature
await self.async_set_temperature(temperature=target_temp)
@property
def preset_mode(self) -> str | None:

View File

@ -313,12 +313,24 @@ async def test_set_temperature(
@pytest.mark.parametrize(
("service_data", "target_temperature", "expected_call_args"),
("service_data", "target_temperature", "current_preset", "expected_call_args"),
[
({ATTR_HVAC_MODE: HVACMode.OFF}, 22, [call(0)]),
({ATTR_HVAC_MODE: HVACMode.HEAT}, 0.0, [call(22)]),
({ATTR_HVAC_MODE: HVACMode.HEAT}, 18, []),
({ATTR_HVAC_MODE: HVACMode.HEAT}, 22, []),
# mode off always sets target temperature to 0
({ATTR_HVAC_MODE: HVACMode.OFF}, 22, PRESET_COMFORT, [call(0)]),
({ATTR_HVAC_MODE: HVACMode.OFF}, 16, PRESET_ECO, [call(0)]),
({ATTR_HVAC_MODE: HVACMode.OFF}, 16, None, [call(0)]),
# mode heat sets target temperature based on current scheduled preset,
# when not already in mode heat
({ATTR_HVAC_MODE: HVACMode.HEAT}, 0.0, PRESET_COMFORT, [call(22)]),
({ATTR_HVAC_MODE: HVACMode.HEAT}, 0.0, PRESET_ECO, [call(16)]),
({ATTR_HVAC_MODE: HVACMode.HEAT}, 0.0, None, [call(22)]),
# mode heat does not set target temperature, when already in mode heat
({ATTR_HVAC_MODE: HVACMode.HEAT}, 16, PRESET_COMFORT, []),
({ATTR_HVAC_MODE: HVACMode.HEAT}, 16, PRESET_ECO, []),
({ATTR_HVAC_MODE: HVACMode.HEAT}, 16, None, []),
({ATTR_HVAC_MODE: HVACMode.HEAT}, 22, PRESET_COMFORT, []),
({ATTR_HVAC_MODE: HVACMode.HEAT}, 22, PRESET_ECO, []),
({ATTR_HVAC_MODE: HVACMode.HEAT}, 22, None, []),
],
)
async def test_set_hvac_mode(
@ -326,11 +338,20 @@ async def test_set_hvac_mode(
fritz: Mock,
service_data: dict,
target_temperature: float,
current_preset: str,
expected_call_args: list[_Call],
) -> None:
"""Test setting hvac mode."""
device = FritzDeviceClimateMock()
device.target_temperature = target_temperature
if current_preset is PRESET_COMFORT:
device.nextchange_temperature = device.eco_temperature
elif current_preset is PRESET_ECO:
device.nextchange_temperature = device.comfort_temperature
else:
device.nextchange_endperiod = 0
assert await setup_config_entry(
hass, MOCK_CONFIG[FB_DOMAIN][CONF_DEVICES][0], ENTITY_ID, device, fritz
)