From 3b184ad11c2916a61add781e88c1c17055f4053a Mon Sep 17 00:00:00 2001 From: Jamin Collins Date: Fri, 8 Jan 2021 04:09:22 +0000 Subject: [PATCH] Implement support for additional ecobee hold modes (#40520) * useEndTime2hour - 2 hours * useEndTime4hour - 4 hours * indefinite - Until I change it These changes have been tested with an ecobee3 lite running firmware version 4.5.81.200 Signed-off-by: Jamin W. Collins --- homeassistant/components/ecobee/climate.py | 36 +++++++++++++++----- tests/components/ecobee/test_climate.py | 38 +++++++++++++++++----- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/homeassistant/components/ecobee/climate.py b/homeassistant/components/ecobee/climate.py index 6bb7dc1a870..c61428cbc78 100644 --- a/homeassistant/components/ecobee/climate.py +++ b/homeassistant/components/ecobee/climate.py @@ -617,6 +617,7 @@ class Thermostat(ClimateEntity): cool_temp_setpoint, heat_temp_setpoint, self.hold_preference(), + self.hold_hours(), ) _LOGGER.debug( "Setting ecobee hold_temp to: heat=%s, is=%s, cool=%s, is=%s", @@ -717,15 +718,32 @@ class Thermostat(ClimateEntity): def hold_preference(self): """Return user preference setting for hold time.""" - # Values returned from thermostat are 'useEndTime4hour', - # 'useEndTime2hour', 'nextTransition', 'indefinite', 'askMe' - default = self.thermostat["settings"]["holdAction"] - if default == "nextTransition": - return default - # add further conditions if other hold durations should be - # supported; note that this should not include 'indefinite' - # as an indefinite away hold is interpreted as away_mode - return "nextTransition" + # Values returned from thermostat are: + # "useEndTime2hour", "useEndTime4hour" + # "nextPeriod", "askMe" + # "indefinite" + device_preference = self.thermostat["settings"]["holdAction"] + # Currently supported pyecobee holdTypes: + # dateTime, nextTransition, indefinite, holdHours + hold_pref_map = { + "useEndTime2hour": "holdHours", + "useEndTime4hour": "holdHours", + "indefinite": "indefinite", + } + return hold_pref_map.get(device_preference, "nextTransition") + + def hold_hours(self): + """Return user preference setting for hold duration in hours.""" + # Values returned from thermostat are: + # "useEndTime2hour", "useEndTime4hour" + # "nextPeriod", "askMe" + # "indefinite" + device_preference = self.thermostat["settings"]["holdAction"] + hold_hours_map = { + "useEndTime2hour": 2, + "useEndTime4hour": 4, + } + return hold_hours_map.get(device_preference, 0) def create_vacation(self, service_data): """Create a vacation with user-specified parameters.""" diff --git a/tests/components/ecobee/test_climate.py b/tests/components/ecobee/test_climate.py index 32575e7188a..a9b9165d713 100644 --- a/tests/components/ecobee/test_climate.py +++ b/tests/components/ecobee/test_climate.py @@ -208,26 +208,32 @@ async def test_set_temperature(ecobee_fixture, thermostat, data): # Auto -> Auto data.reset_mock() thermostat.set_temperature(target_temp_low=20, target_temp_high=30) - data.ecobee.set_hold_temp.assert_has_calls([mock.call(1, 30, 20, "nextTransition")]) + data.ecobee.set_hold_temp.assert_has_calls( + [mock.call(1, 30, 20, "nextTransition", 0)] + ) # Auto -> Hold data.reset_mock() thermostat.set_temperature(temperature=20) - data.ecobee.set_hold_temp.assert_has_calls([mock.call(1, 25, 15, "nextTransition")]) + data.ecobee.set_hold_temp.assert_has_calls( + [mock.call(1, 25, 15, "nextTransition", 0)] + ) # Cool -> Hold data.reset_mock() ecobee_fixture["settings"]["hvacMode"] = "cool" thermostat.set_temperature(temperature=20.5) data.ecobee.set_hold_temp.assert_has_calls( - [mock.call(1, 20.5, 20.5, "nextTransition")] + [mock.call(1, 20.5, 20.5, "nextTransition", 0)] ) # Heat -> Hold data.reset_mock() ecobee_fixture["settings"]["hvacMode"] = "heat" thermostat.set_temperature(temperature=20) - data.ecobee.set_hold_temp.assert_has_calls([mock.call(1, 20, 20, "nextTransition")]) + data.ecobee.set_hold_temp.assert_has_calls( + [mock.call(1, 20, 20, "nextTransition", 0)] + ) # Heat -> Auto data.reset_mock() @@ -280,16 +286,32 @@ async def test_resume_program(thermostat, data): async def test_hold_preference(ecobee_fixture, thermostat): """Test hold preference.""" - assert thermostat.hold_preference() == "nextTransition" + ecobee_fixture["settings"]["holdAction"] = "indefinite" + assert thermostat.hold_preference() == "indefinite" + for action in ["useEndTime2hour", "useEndTime4hour"]: + ecobee_fixture["settings"]["holdAction"] = action + assert thermostat.hold_preference() == "holdHours" + for action in [ + "nextPeriod", + "askMe", + ]: + ecobee_fixture["settings"]["holdAction"] = action + assert thermostat.hold_preference() == "nextTransition" + + +def test_hold_hours(ecobee_fixture, thermostat): + """Test hold hours preference.""" + ecobee_fixture["settings"]["holdAction"] = "useEndTime2hour" + assert thermostat.hold_hours() == 2 + ecobee_fixture["settings"]["holdAction"] = "useEndTime4hour" + assert thermostat.hold_hours() == 4 for action in [ - "useEndTime4hour", - "useEndTime2hour", "nextPeriod", "indefinite", "askMe", ]: ecobee_fixture["settings"]["holdAction"] = action - assert thermostat.hold_preference() == "nextTransition" + assert thermostat.hold_hours() == 0 async def test_set_fan_mode_on(thermostat, data):