Skip to content

Commit

Permalink
feat: sets target temps from saved temps from heat-cool
Browse files Browse the repository at this point in the history
  • Loading branch information
= authored and swingerman committed May 29, 2024
1 parent d19ace0 commit 489e888
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 38 deletions.
15 changes: 13 additions & 2 deletions custom_components/dual_smart_thermostat/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ async def _async_startup(*_) -> None:
self.environment.set_default_target_temps(
self.features.is_target_mode,
self.features.is_range_mode,
self.hvac_device.hvac_modes,
self._hvac_mode,
)

# restore previous preset mode if available
Expand Down Expand Up @@ -612,7 +612,7 @@ async def _async_startup(*_) -> None:
self.environment.set_default_target_temps(
self.features.is_target_mode,
self.features.is_range_mode,
self.hvac_device.hvac_modes,
self._hvac_mode,
)

if self.environment.max_floor_temp is None:
Expand Down Expand Up @@ -903,6 +903,17 @@ def _set_temperatures_dual_mode(self, temperatures: TargetTemperatures) -> None:

elif self.features.is_range_mode:
self.environment.set_temperature_range(temperature, temp_low, temp_high)

# setting saved targets to current so while changing hvac mode
# other hvac modes can pick them up
if self.presets.preset_mode == PRESET_NONE:
self.environment.saved_target_temp_low = (
self.environment.target_temp_low
)
self.environment.saved_target_temp_high = (
self.environment.target_temp_high
)

self._target_temp = self.environment.target_temp
self._target_temp_low = self.environment.target_temp_low
self._target_temp_high = self.environment.target_temp_high
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ def target_temp_low(self) -> float:

@target_temp_low.setter
def target_temp_low(self, temp: float) -> None:
_LOGGER.debug("Setting target temperature low: %s", temp)
self._target_temp_low = temp

@property
Expand Down Expand Up @@ -187,7 +188,6 @@ def max_floor_temp(self) -> float:

@max_floor_temp.setter
def max_floor_temp(self, temp: float) -> None:
_LOGGER.debug("Setting max floor temp property: %s", temp)
self._max_floor_temp = temp

@property
Expand All @@ -208,6 +208,7 @@ def saved_target_temp_low(self) -> float:

@saved_target_temp_low.setter
def saved_target_temp_low(self, temp: float) -> None:
_LOGGER.debug("Setting saved target temp low: %s", temp)
self._saved_target_temp_low = temp

@property
Expand Down Expand Up @@ -277,8 +278,13 @@ def set_temperature_target(self, temperature: float) -> None:
def set_temperature_range(
self, temperature: float, temp_low: float, temp_high: float
) -> None:
# if temp_low is None or temp_high is None:
# return

_LOGGER.debug(
"Setting target temperature range: %s, %s, %s",
temperature,
temp_low,
temp_high,
)

if temp_low is None:
temp_low = temperature - PRECISION_WHOLE
Expand Down Expand Up @@ -490,47 +496,66 @@ def set_default_target_humidity(self) -> None:
self._target_humidity = 50

def set_default_target_temps(
self, is_target_mode: bool, is_range_mode: bool, hvac_modes: list[HVACMode]
self, is_target_mode: bool, is_range_mode: bool, hvac_mode: HVACMode
) -> None:
"""Set default values for target temperatures."""
_LOGGER.debug(
"Setting default target temperatures, target mode: %s, range mode: %s, hvac_mode: %s",
is_target_mode,
is_range_mode,
hvac_modes,
hvac_mode,
)
if is_target_mode:
self._set_default_temps_target_mode(hvac_modes)
self._set_default_temps_target_mode(hvac_mode)

elif is_range_mode:
self._set_default_temps_range_mode()

def _set_default_temps_target_mode(self, hvac_modes: list[HVACMode]) -> None:
if self._target_temp is not None:
return
def _set_default_temps_target_mode(self, hvac_mode: HVACMode) -> None:

_LOGGER.info("Setting default target temperature target mode: %s", hvac_modes)
_LOGGER.info(
"Setting default target temperature target mode: %s, target_temp: %s",
hvac_mode,
self._target_temp,
)
_LOGGER.debug(
"saved target temp low: %s, saved target temp high: %s",
self._saved_target_temp_low,
self._saved_target_temp_high,
)

# if HVACMode.COOL in hvac_device.hvac_modes or hvac_mode == HVACMode.COOL:
if HVACMode.COOL in hvac_modes or HVACMode.FAN_ONLY in hvac_modes:
if self._target_temp_high is None:
if hvac_mode == HVACMode.COOL or hvac_mode == HVACMode.FAN_ONLY:
if self._saved_target_temp_high is None:
if self._target_temp is not None:
return
self._target_temp = self.max_temp
_LOGGER.warning(
"Undefined target temperature, falling back to %s",
"Undefined target high temperature, falling back to %s",
self._target_temp,
)
else:
self._target_temp = self._target_temp_high
return
_LOGGER.debug(
"Setting target temp to saved target temp high: %s",
self._saved_target_temp_high,
)
self._target_temp = self._saved_target_temp_high
# return

if self._target_temp_low is None:
self._target_temp = self.min_temp
_LOGGER.warning(
"Undefined target temperature, falling back to %s",
self._target_temp,
)
else:
self._target_temp = self._target_temp_low
if hvac_mode == HVACMode.HEAT:
if self._saved_target_temp_low is None:
if self._target_temp is not None:
return
self._target_temp = self.min_temp
_LOGGER.warning(
"Undefined target low temperature, falling back to %s",
self._target_temp,
)
else:
_LOGGER.debug(
"Setting target temp to saved target temp low: %s",
self._saved_target_temp_low,
)
self._target_temp = self._saved_target_temp_low

def _set_default_temps_range_mode(self) -> None:
if self._target_temp_low is not None and self._target_temp_high is not None:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ def set_support_flags(
self._supported_features,
)
self.environment.set_default_target_temps(
self.is_target_mode, self.is_range_mode, hvac_modes
self.is_target_mode, self.is_range_mode, current_hvac_mode
)

if self.is_configured_for_dryer_mode:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,12 @@ def set_preset_mode(self, preset_mode: str) -> None:
def _set_presets_when_no_preset_mode(self):
"""Sets target environment when preset is none."""
_LOGGER.debug("Setting presets when no preset mode")
_LOGGER.debug(
"saved_target_temp_low: %s", self._environment.saved_target_temp_low
)
_LOGGER.debug(
"saved_target_temp_high: %s", self._environment.saved_target_temp_high
)
self._preset_mode = PRESET_NONE
if self._features.is_range_mode:
self._environment.target_temp_low = self._environment.saved_target_temp_low
Expand Down
4 changes: 2 additions & 2 deletions tests/test_cooler_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,9 @@ async def test_set_target_temp_ac_off(
"""Test if target temperature turn ac off."""
calls = setup_switch(hass, True)
setup_sensor(hass, 25)
await hass.async_block_till_done()
await common.async_set_temperature(hass, 30)
assert len(calls) == 2
await hass.async_block_till_done()
assert len(calls) == 1
call = calls[0]
assert call.domain == HASS_DOMAIN
assert call.service == SERVICE_TURN_OFF
Expand Down
80 changes: 77 additions & 3 deletions tests/test_dual_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ async def test_dual_default_setup_params(
state = hass.states.get(common.ENTITY)
assert state.attributes.get("min_temp") == 7
assert state.attributes.get("max_temp") == 35
assert state.attributes.get("temperature") == 35
assert state.attributes.get("temperature") == 7


async def test_heat_cool_default_setup_params(
Expand Down Expand Up @@ -1094,6 +1094,8 @@ async def test_heat_cool_set_preset_mode_set_temp_keeps_preset_mode(
test_target_temp_low = 3
test_target_temp_high = 33
await common.async_set_temperature(hass, 18, common.ENTITY, 22, 18)
await hass.async_block_till_done()

await common.async_set_preset_mode(hass, preset)
state = hass.states.get(common.ENTITY)
assert state.attributes.get("target_temp_low") == temp_low
Expand All @@ -1110,6 +1112,7 @@ async def test_heat_cool_set_preset_mode_set_temp_keeps_preset_mode(
assert state.attributes.get("target_temp_high") == test_target_temp_high
assert state.attributes.get("preset_mode") == preset
assert state.attributes.get("supported_features") == 402

await common.async_set_preset_mode(hass, PRESET_NONE)
state = hass.states.get(common.ENTITY)
if preset == PRESET_NONE:
Expand Down Expand Up @@ -1217,7 +1220,7 @@ async def test_heat_cool_fan_set_preset_mode_change_hvac_mode(

state = hass.states.get(common.ENTITY)
assert state.attributes.get("preset_mode") == preset
assert state.attributes.get("temperature") == 18
assert state.attributes.get("temperature") == 22
assert state.attributes.get("target_temp_low") is None
assert state.attributes.get("target_temp_high") is None

Expand All @@ -1226,7 +1229,7 @@ async def test_heat_cool_fan_set_preset_mode_change_hvac_mode(

state = hass.states.get(common.ENTITY)
assert state.attributes.get("preset_mode") == preset
assert state.attributes.get("temperature") == 18
assert state.attributes.get("temperature") == 22
assert state.attributes.get("target_temp_low") is None
assert state.attributes.get("target_temp_high") is None

Expand Down Expand Up @@ -2062,6 +2065,77 @@ async def test_hvac_mode_mode_heat_cool_hvac_modes_temps_avoid_unrealism(
assert state.attributes["target_temp_high"] == 21 # temp_low + precision


async def test_hvac_mode_mode_heat_cool_hvac_modes_temps_picks_range_values(
hass: HomeAssistant, setup_comp_1 # noqa: F811
):
"""Test thermostat target tempreratures get from range mode
when switched from heat-cool mode to heat or cool mode"""

heater_switch = "input_boolean.heater"
cooler_switch = "input_boolean.cooler"
assert await async_setup_component(
hass,
input_boolean.DOMAIN,
{"input_boolean": {"heater": None, "cooler": None}},
)

assert await async_setup_component(
hass,
input_number.DOMAIN,
{
"input_number": {
"temp": {"name": "test", "initial": 10, "min": 0, "max": 40, "step": 1}
}
},
)

assert await async_setup_component(
hass,
CLIMATE,
{
"climate": {
"platform": DOMAIN,
"name": "test",
"cooler": cooler_switch,
"heater": heater_switch,
"heat_cool_mode": True,
"target_sensor": common.ENT_SENSOR,
}
},
)
await hass.async_block_till_done()

state = hass.states.get(common.ENTITY)
assert state.attributes["supported_features"] == 386

assert hass.states.get(heater_switch).state == STATE_OFF
assert hass.states.get(cooler_switch).state == STATE_OFF

await common.async_set_hvac_mode(hass, HVACMode.HEAT_COOL)
await common.async_set_temperature(hass, 18, ENTITY_MATCH_ALL, 25, 22)
await hass.async_block_till_done()

state = hass.states.get(common.ENTITY)
assert state.attributes["target_temp_low"] == 22
assert state.attributes["target_temp_high"] == 25
assert state.attributes.get("temperature") is None

# switch to heat only mode
await common.async_set_hvac_mode(hass, HVACMode.HEAT)
await hass.async_block_till_done()

state = hass.states.get(common.ENTITY)
assert state.attributes.get("temperature") == 22

# switch to cool only mode
await common.async_set_hvac_mode(hass, HVACMode.COOL)
await hass.async_block_till_done()

state = hass.states.get(common.ENTITY)
assert state.attributes.get("temperature") == 25


async def test_hvac_mode_heat_cool_floor_temp(
hass: HomeAssistant, setup_comp_1 # noqa: F811
):
Expand Down
12 changes: 6 additions & 6 deletions tests/test_fan_mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -728,9 +728,9 @@ async def test_set_target_temp_fan_off(
"""Test if target temperature turn fan off."""
calls = setup_switch(hass, True)
setup_sensor(hass, 25)
await hass.async_block_till_done()
await common.async_set_temperature(hass, 30)
assert len(calls) == 2
await hass.async_block_till_done()
assert len(calls) == 1
call = calls[0]
assert call.domain == HASS_DOMAIN
assert call.service == SERVICE_TURN_OFF
Expand Down Expand Up @@ -782,8 +782,8 @@ async def test_set_target_temp_cooler_on(
setup_sensor(hass, 30)
# only turns on if in COOL mode
await common.async_set_hvac_mode(hass, HVACMode.COOL)
await hass.async_block_till_done()
await common.async_set_temperature(hass, 25)
await hass.async_block_till_done()
assert len(calls) == 1
call = calls[0]
assert call.domain == HASS_DOMAIN
Expand All @@ -799,8 +799,8 @@ async def test_set_target_temp_cooler_fan_on(
setup_sensor(hass, 30)
# only turns on if in COOL mode
await common.async_set_hvac_mode(hass, HVACMode.FAN_ONLY)
await hass.async_block_till_done()
await common.async_set_temperature(hass, 25)
await hass.async_block_till_done()
assert len(calls) == 1
call = calls[0]
assert call.domain == HASS_DOMAIN
Expand Down Expand Up @@ -2343,9 +2343,9 @@ async def test_set_target_temp_ac_fan_on(
calls = setup_fan(hass, False)
await common.async_set_hvac_mode(hass, HVACMode.FAN_ONLY)
setup_sensor(hass, 30)
await common.async_set_temperature(hass, 25)
await hass.async_block_till_done()

await common.async_set_temperature(hass, 25)
assert len(calls) == 1
call = calls[0]
assert call.domain == HASS_DOMAIN
Expand All @@ -2360,9 +2360,9 @@ async def test_set_target_temp_ac_on_after_fan_tolerance(
calls = setup_switch_dual(hass, common.ENT_FAN, False, False)
await common.async_set_hvac_mode(hass, HVACMode.COOL)
setup_sensor(hass, 26)
await common.async_set_temperature(hass, 21)
await hass.async_block_till_done()

await common.async_set_temperature(hass, 21)
assert len(calls) == 1
call = calls[0]
assert call.domain == HASS_DOMAIN
Expand Down

0 comments on commit 489e888

Please sign in to comment.