Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: sets target temps from saved temps from heat-cool #209

Merged
merged 1 commit into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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