Use integration fallback configuration for tado water heater fallback (#111014)
* 103619 tado water heater fallback * extracted a method to remove code duplication * test cases and suggested changes * tests * util method for connector * Update homeassistant/components/tado/climate.py Co-authored-by: Andriy Kushnir <me@orhideous.name> * missing import after applies suggestion * early return * simplify if statements * simplify pr * pr requested changes * better docstring --------- Co-authored-by: Andriy Kushnir <me@orhideous.name>
This commit is contained in:
parent
ad6e6a1810
commit
b684801cae
4 changed files with 98 additions and 25 deletions
|
@ -36,8 +36,6 @@ from .const import (
|
||||||
CONST_MODE_OFF,
|
CONST_MODE_OFF,
|
||||||
CONST_MODE_SMART_SCHEDULE,
|
CONST_MODE_SMART_SCHEDULE,
|
||||||
CONST_OVERLAY_MANUAL,
|
CONST_OVERLAY_MANUAL,
|
||||||
CONST_OVERLAY_TADO_DEFAULT,
|
|
||||||
CONST_OVERLAY_TADO_MODE,
|
|
||||||
CONST_OVERLAY_TADO_OPTIONS,
|
CONST_OVERLAY_TADO_OPTIONS,
|
||||||
CONST_OVERLAY_TIMER,
|
CONST_OVERLAY_TIMER,
|
||||||
DATA,
|
DATA,
|
||||||
|
@ -67,6 +65,7 @@ from .const import (
|
||||||
TYPE_HEATING,
|
TYPE_HEATING,
|
||||||
)
|
)
|
||||||
from .entity import TadoZoneEntity
|
from .entity import TadoZoneEntity
|
||||||
|
from .helper import decide_overlay_mode
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -598,23 +597,12 @@ class TadoClimate(TadoZoneEntity, ClimateEntity):
|
||||||
self._tado.reset_zone_overlay(self.zone_id)
|
self._tado.reset_zone_overlay(self.zone_id)
|
||||||
return
|
return
|
||||||
|
|
||||||
# If user gave duration then overlay mode needs to be timer
|
overlay_mode = decide_overlay_mode(
|
||||||
if duration:
|
tado=self._tado,
|
||||||
overlay_mode = CONST_OVERLAY_TIMER
|
duration=duration,
|
||||||
# If no duration or timer set to fallback setting
|
overlay_mode=overlay_mode,
|
||||||
if overlay_mode is None:
|
zone_id=self.zone_id,
|
||||||
overlay_mode = (
|
)
|
||||||
self._tado.fallback
|
|
||||||
if self._tado.fallback is not None
|
|
||||||
else CONST_OVERLAY_TADO_MODE
|
|
||||||
)
|
|
||||||
# If default is Tado default then look it up
|
|
||||||
if overlay_mode == CONST_OVERLAY_TADO_DEFAULT:
|
|
||||||
overlay_mode = (
|
|
||||||
self._tado_zone_data.default_overlay_termination_type
|
|
||||||
if self._tado_zone_data.default_overlay_termination_type is not None
|
|
||||||
else CONST_OVERLAY_TADO_MODE
|
|
||||||
)
|
|
||||||
# If we ended up with a timer but no duration, set a default duration
|
# If we ended up with a timer but no duration, set a default duration
|
||||||
if overlay_mode == CONST_OVERLAY_TIMER and duration is None:
|
if overlay_mode == CONST_OVERLAY_TIMER and duration is None:
|
||||||
duration = (
|
duration = (
|
||||||
|
|
31
homeassistant/components/tado/helper.py
Normal file
31
homeassistant/components/tado/helper.py
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
"""Helper methods for Tado."""
|
||||||
|
|
||||||
|
from . import TadoConnector
|
||||||
|
from .const import (
|
||||||
|
CONST_OVERLAY_TADO_DEFAULT,
|
||||||
|
CONST_OVERLAY_TADO_MODE,
|
||||||
|
CONST_OVERLAY_TIMER,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def decide_overlay_mode(
|
||||||
|
tado: TadoConnector,
|
||||||
|
duration: int | None,
|
||||||
|
zone_id: int,
|
||||||
|
overlay_mode: str | None = None,
|
||||||
|
) -> str:
|
||||||
|
"""Return correct overlay mode based on the action and defaults."""
|
||||||
|
# If user gave duration then overlay mode needs to be timer
|
||||||
|
if duration:
|
||||||
|
return CONST_OVERLAY_TIMER
|
||||||
|
# If no duration or timer set to fallback setting
|
||||||
|
if overlay_mode is None:
|
||||||
|
overlay_mode = tado.fallback or CONST_OVERLAY_TADO_MODE
|
||||||
|
# If default is Tado default then look it up
|
||||||
|
if overlay_mode == CONST_OVERLAY_TADO_DEFAULT:
|
||||||
|
overlay_mode = (
|
||||||
|
tado.data["zone"][zone_id].default_overlay_termination_type
|
||||||
|
or CONST_OVERLAY_TADO_MODE
|
||||||
|
)
|
||||||
|
|
||||||
|
return overlay_mode
|
|
@ -32,6 +32,7 @@ from .const import (
|
||||||
TYPE_HOT_WATER,
|
TYPE_HOT_WATER,
|
||||||
)
|
)
|
||||||
from .entity import TadoZoneEntity
|
from .entity import TadoZoneEntity
|
||||||
|
from .helper import decide_overlay_mode
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -277,12 +278,11 @@ class TadoWaterHeater(TadoZoneEntity, WaterHeaterEntity):
|
||||||
self._tado.set_zone_off(self.zone_id, CONST_OVERLAY_MANUAL, TYPE_HOT_WATER)
|
self._tado.set_zone_off(self.zone_id, CONST_OVERLAY_MANUAL, TYPE_HOT_WATER)
|
||||||
return
|
return
|
||||||
|
|
||||||
overlay_mode = CONST_OVERLAY_MANUAL
|
overlay_mode = decide_overlay_mode(
|
||||||
if duration:
|
tado=self._tado,
|
||||||
overlay_mode = CONST_OVERLAY_TIMER
|
duration=duration,
|
||||||
elif self._tado.fallback:
|
zone_id=self.zone_id,
|
||||||
# Fallback to Smart Schedule at next Schedule switch if we have fallback enabled
|
)
|
||||||
overlay_mode = CONST_OVERLAY_TADO_MODE
|
|
||||||
|
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Switching to %s for zone %s (%d) with temperature %s",
|
"Switching to %s for zone %s (%d) with temperature %s",
|
||||||
|
|
54
tests/components/tado/test_helper.py
Normal file
54
tests/components/tado/test_helper.py
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
"""Helper method tests."""
|
||||||
|
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from homeassistant.components.tado import TadoConnector
|
||||||
|
from homeassistant.components.tado.const import (
|
||||||
|
CONST_OVERLAY_MANUAL,
|
||||||
|
CONST_OVERLAY_TADO_DEFAULT,
|
||||||
|
CONST_OVERLAY_TADO_MODE,
|
||||||
|
CONST_OVERLAY_TIMER,
|
||||||
|
)
|
||||||
|
from homeassistant.components.tado.helper import decide_overlay_mode
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
|
||||||
|
def dummy_tado_connector(hass: HomeAssistant, fallback) -> TadoConnector:
|
||||||
|
"""Return dummy tado connector."""
|
||||||
|
return TadoConnector(hass, username="dummy", password="dummy", fallback=fallback)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_overlay_mode_duration_set(hass: HomeAssistant) -> None:
|
||||||
|
"""Test overlay method selection when duration is set."""
|
||||||
|
tado = dummy_tado_connector(hass=hass, fallback=CONST_OVERLAY_TADO_MODE)
|
||||||
|
overlay_mode = decide_overlay_mode(tado=tado, duration="01:00:00", zone_id=1)
|
||||||
|
# Must select TIMER overlay
|
||||||
|
assert overlay_mode == CONST_OVERLAY_TIMER
|
||||||
|
|
||||||
|
|
||||||
|
async def test_overlay_mode_next_time_block_fallback(hass: HomeAssistant) -> None:
|
||||||
|
"""Test overlay method selection when duration is not set."""
|
||||||
|
integration_fallback = CONST_OVERLAY_TADO_MODE
|
||||||
|
tado = dummy_tado_connector(hass=hass, fallback=integration_fallback)
|
||||||
|
overlay_mode = decide_overlay_mode(tado=tado, duration=None, zone_id=1)
|
||||||
|
# Must fallback to integration wide setting
|
||||||
|
assert overlay_mode == integration_fallback
|
||||||
|
|
||||||
|
|
||||||
|
async def test_overlay_mode_tado_default_fallback(hass: HomeAssistant) -> None:
|
||||||
|
"""Test overlay method selection when tado default is selected."""
|
||||||
|
integration_fallback = CONST_OVERLAY_TADO_DEFAULT
|
||||||
|
zone_fallback = CONST_OVERLAY_MANUAL
|
||||||
|
tado = dummy_tado_connector(hass=hass, fallback=integration_fallback)
|
||||||
|
|
||||||
|
class MockZoneData:
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.default_overlay_termination_type = zone_fallback
|
||||||
|
|
||||||
|
zone_id = 1
|
||||||
|
|
||||||
|
zone_data = {"zone": {zone_id: MockZoneData()}}
|
||||||
|
with patch.dict(tado.data, zone_data):
|
||||||
|
overlay_mode = decide_overlay_mode(tado=tado, duration=None, zone_id=zone_id)
|
||||||
|
# Must fallback to zone setting
|
||||||
|
assert overlay_mode == zone_fallback
|
Loading…
Add table
Reference in a new issue