mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Expose comfort presets as HA presets (#25491)
* Expose comfort presets as HA presets * Fix bugs * Handle unavailable * log level debug on update * Lint
This commit is contained in:
parent
3649a1b5e9
commit
a398b39e12
@ -97,7 +97,7 @@ class EcobeeData:
|
|||||||
def update(self):
|
def update(self):
|
||||||
"""Get the latest data from pyecobee."""
|
"""Get the latest data from pyecobee."""
|
||||||
self.ecobee.update()
|
self.ecobee.update()
|
||||||
_LOGGER.info("Ecobee data updated successfully")
|
_LOGGER.debug("Ecobee data updated successfully")
|
||||||
|
|
||||||
|
|
||||||
def setup(hass, config):
|
def setup(hass, config):
|
||||||
|
@ -88,16 +88,6 @@ PRESET_TO_ECOBEE_HOLD = {
|
|||||||
PRESET_HOLD_INDEFINITE: "indefinite",
|
PRESET_HOLD_INDEFINITE: "indefinite",
|
||||||
}
|
}
|
||||||
|
|
||||||
PRESET_MODES = [
|
|
||||||
PRESET_NONE,
|
|
||||||
PRESET_AWAY,
|
|
||||||
PRESET_TEMPERATURE,
|
|
||||||
PRESET_HOME,
|
|
||||||
PRESET_SLEEP,
|
|
||||||
PRESET_HOLD_NEXT_TRANSITION,
|
|
||||||
PRESET_HOLD_INDEFINITE,
|
|
||||||
]
|
|
||||||
|
|
||||||
SERVICE_SET_FAN_MIN_ON_TIME = "ecobee_set_fan_min_on_time"
|
SERVICE_SET_FAN_MIN_ON_TIME = "ecobee_set_fan_min_on_time"
|
||||||
SERVICE_RESUME_PROGRAM = "ecobee_resume_program"
|
SERVICE_RESUME_PROGRAM = "ecobee_resume_program"
|
||||||
|
|
||||||
@ -199,7 +189,6 @@ class Thermostat(ClimateDevice):
|
|||||||
self._name = self.thermostat["name"]
|
self._name = self.thermostat["name"]
|
||||||
self.hold_temp = hold_temp
|
self.hold_temp = hold_temp
|
||||||
self.vacation = None
|
self.vacation = None
|
||||||
self._climate_list = self.climate_list
|
|
||||||
|
|
||||||
self._operation_list = []
|
self._operation_list = []
|
||||||
if self.thermostat["settings"]["heatStages"]:
|
if self.thermostat["settings"]["heatStages"]:
|
||||||
@ -210,6 +199,10 @@ class Thermostat(ClimateDevice):
|
|||||||
self._operation_list.insert(0, HVAC_MODE_AUTO)
|
self._operation_list.insert(0, HVAC_MODE_AUTO)
|
||||||
self._operation_list.append(HVAC_MODE_OFF)
|
self._operation_list.append(HVAC_MODE_OFF)
|
||||||
|
|
||||||
|
self._preset_modes = {
|
||||||
|
comfort["climateRef"]: comfort["name"]
|
||||||
|
for comfort in self.thermostat["program"]["climates"]
|
||||||
|
}
|
||||||
self._fan_modes = [FAN_AUTO, FAN_ON]
|
self._fan_modes = [FAN_AUTO, FAN_ON]
|
||||||
self.update_without_throttle = False
|
self.update_without_throttle = False
|
||||||
|
|
||||||
@ -223,6 +216,11 @@ class Thermostat(ClimateDevice):
|
|||||||
|
|
||||||
self.thermostat = self.data.ecobee.get_thermostat(self.thermostat_index)
|
self.thermostat = self.data.ecobee.get_thermostat(self.thermostat_index)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available(self):
|
||||||
|
"""Return if device is available."""
|
||||||
|
return self.thermostat["runtime"]["connected"]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supported_features(self):
|
def supported_features(self):
|
||||||
"""Return the list of supported features."""
|
"""Return the list of supported features."""
|
||||||
@ -294,15 +292,9 @@ class Thermostat(ClimateDevice):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if event["type"] == "hold":
|
if event["type"] == "hold":
|
||||||
if event["holdClimateRef"] == "away":
|
if event["holdClimateRef"] in self._preset_modes:
|
||||||
if int(event["endDate"][0:4]) - int(event["startDate"][0:4]) <= 1:
|
return self._preset_modes[event["holdClimateRef"]]
|
||||||
# A temporary hold from away climate is a hold
|
|
||||||
return PRESET_AWAY
|
|
||||||
# A permanent hold from away climate
|
|
||||||
return PRESET_AWAY
|
|
||||||
if event["holdClimateRef"] != "":
|
|
||||||
# Any other hold based on climate
|
|
||||||
return event["holdClimateRef"]
|
|
||||||
# Any hold not based on a climate is a temp hold
|
# Any hold not based on a climate is a temp hold
|
||||||
return PRESET_TEMPERATURE
|
return PRESET_TEMPERATURE
|
||||||
if event["type"].startswith("auto"):
|
if event["type"].startswith("auto"):
|
||||||
@ -324,14 +316,6 @@ class Thermostat(ClimateDevice):
|
|||||||
"""Return the operation modes list."""
|
"""Return the operation modes list."""
|
||||||
return self._operation_list
|
return self._operation_list
|
||||||
|
|
||||||
@property
|
|
||||||
def climate_mode(self):
|
|
||||||
"""Return current mode, as the user-visible name."""
|
|
||||||
cur = self.thermostat["program"]["currentClimateRef"]
|
|
||||||
climates = self.thermostat["program"]["climates"]
|
|
||||||
current = list(filter(lambda x: x["climateRef"] == cur, climates))
|
|
||||||
return current[0]["name"]
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_humidity(self) -> Optional[int]:
|
def current_humidity(self) -> Optional[int]:
|
||||||
"""Return the current humidity."""
|
"""Return the current humidity."""
|
||||||
@ -373,9 +357,7 @@ class Thermostat(ClimateDevice):
|
|||||||
status = self.thermostat["equipmentStatus"]
|
status = self.thermostat["equipmentStatus"]
|
||||||
return {
|
return {
|
||||||
"fan": self.fan,
|
"fan": self.fan,
|
||||||
"climate_mode": self.climate_mode,
|
|
||||||
"equipment_running": status,
|
"equipment_running": status,
|
||||||
"climate_list": self.climate_list,
|
|
||||||
"fan_min_on_time": self.thermostat["settings"]["fanMinOnTime"],
|
"fan_min_on_time": self.thermostat["settings"]["fanMinOnTime"],
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,6 +395,21 @@ class Thermostat(ClimateDevice):
|
|||||||
elif preset_mode == PRESET_NONE:
|
elif preset_mode == PRESET_NONE:
|
||||||
self.data.ecobee.resume_program(self.thermostat_index)
|
self.data.ecobee.resume_program(self.thermostat_index)
|
||||||
|
|
||||||
|
elif preset_mode in self.preset_modes:
|
||||||
|
climate_ref = None
|
||||||
|
|
||||||
|
for comfort in self.thermostat["program"]["climates"]:
|
||||||
|
if comfort["name"] == preset_mode:
|
||||||
|
climate_ref = comfort["climateRef"]
|
||||||
|
break
|
||||||
|
|
||||||
|
if climate_ref is not None:
|
||||||
|
self.data.ecobee.set_climate_hold(
|
||||||
|
self.thermostat_index, climate_ref, self.hold_preference()
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
_LOGGER.warning("Received unknown preset mode: %s", preset_mode)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.data.ecobee.set_climate_hold(
|
self.data.ecobee.set_climate_hold(
|
||||||
self.thermostat_index, preset_mode, self.hold_preference()
|
self.thermostat_index, preset_mode, self.hold_preference()
|
||||||
@ -421,7 +418,7 @@ class Thermostat(ClimateDevice):
|
|||||||
@property
|
@property
|
||||||
def preset_modes(self):
|
def preset_modes(self):
|
||||||
"""Return available preset modes."""
|
"""Return available preset modes."""
|
||||||
return PRESET_MODES
|
return list(self._preset_modes.values())
|
||||||
|
|
||||||
def set_auto_temp_hold(self, heat_temp, cool_temp):
|
def set_auto_temp_hold(self, heat_temp, cool_temp):
|
||||||
"""Set temperature hold in auto mode."""
|
"""Set temperature hold in auto mode."""
|
||||||
@ -543,9 +540,3 @@ class Thermostat(ClimateDevice):
|
|||||||
# supported; note that this should not include 'indefinite'
|
# supported; note that this should not include 'indefinite'
|
||||||
# as an indefinite away hold is interpreted as away_mode
|
# as an indefinite away hold is interpreted as away_mode
|
||||||
return "nextTransition"
|
return "nextTransition"
|
||||||
|
|
||||||
@property
|
|
||||||
def climate_list(self):
|
|
||||||
"""Return the list of climates currently available."""
|
|
||||||
climates = self.thermostat["program"]["climates"]
|
|
||||||
return list(map((lambda x: x["name"]), climates))
|
|
||||||
|
@ -130,44 +130,34 @@ class TestEcobee(unittest.TestCase):
|
|||||||
"""Test device state attributes property."""
|
"""Test device state attributes property."""
|
||||||
self.ecobee["equipmentStatus"] = "heatPump2"
|
self.ecobee["equipmentStatus"] = "heatPump2"
|
||||||
assert {
|
assert {
|
||||||
"climate_list": ["Climate1", "Climate2"],
|
|
||||||
"fan": "off",
|
"fan": "off",
|
||||||
"fan_min_on_time": 10,
|
"fan_min_on_time": 10,
|
||||||
"climate_mode": "Climate1",
|
|
||||||
"equipment_running": "heatPump2",
|
"equipment_running": "heatPump2",
|
||||||
} == self.thermostat.device_state_attributes
|
} == self.thermostat.device_state_attributes
|
||||||
|
|
||||||
self.ecobee["equipmentStatus"] = "auxHeat2"
|
self.ecobee["equipmentStatus"] = "auxHeat2"
|
||||||
assert {
|
assert {
|
||||||
"climate_list": ["Climate1", "Climate2"],
|
|
||||||
"fan": "off",
|
"fan": "off",
|
||||||
"fan_min_on_time": 10,
|
"fan_min_on_time": 10,
|
||||||
"climate_mode": "Climate1",
|
|
||||||
"equipment_running": "auxHeat2",
|
"equipment_running": "auxHeat2",
|
||||||
} == self.thermostat.device_state_attributes
|
} == self.thermostat.device_state_attributes
|
||||||
self.ecobee["equipmentStatus"] = "compCool1"
|
self.ecobee["equipmentStatus"] = "compCool1"
|
||||||
assert {
|
assert {
|
||||||
"climate_list": ["Climate1", "Climate2"],
|
|
||||||
"fan": "off",
|
"fan": "off",
|
||||||
"fan_min_on_time": 10,
|
"fan_min_on_time": 10,
|
||||||
"climate_mode": "Climate1",
|
|
||||||
"equipment_running": "compCool1",
|
"equipment_running": "compCool1",
|
||||||
} == self.thermostat.device_state_attributes
|
} == self.thermostat.device_state_attributes
|
||||||
self.ecobee["equipmentStatus"] = ""
|
self.ecobee["equipmentStatus"] = ""
|
||||||
assert {
|
assert {
|
||||||
"climate_list": ["Climate1", "Climate2"],
|
|
||||||
"fan": "off",
|
"fan": "off",
|
||||||
"fan_min_on_time": 10,
|
"fan_min_on_time": 10,
|
||||||
"climate_mode": "Climate1",
|
|
||||||
"equipment_running": "",
|
"equipment_running": "",
|
||||||
} == self.thermostat.device_state_attributes
|
} == self.thermostat.device_state_attributes
|
||||||
|
|
||||||
self.ecobee["equipmentStatus"] = "Unknown"
|
self.ecobee["equipmentStatus"] = "Unknown"
|
||||||
assert {
|
assert {
|
||||||
"climate_list": ["Climate1", "Climate2"],
|
|
||||||
"fan": "off",
|
"fan": "off",
|
||||||
"fan_min_on_time": 10,
|
"fan_min_on_time": 10,
|
||||||
"climate_mode": "Climate1",
|
|
||||||
"equipment_running": "Unknown",
|
"equipment_running": "Unknown",
|
||||||
} == self.thermostat.device_state_attributes
|
} == self.thermostat.device_state_attributes
|
||||||
|
|
||||||
@ -267,10 +257,6 @@ class TestEcobee(unittest.TestCase):
|
|||||||
self.ecobee["settings"]["holdAction"] = action
|
self.ecobee["settings"]["holdAction"] = action
|
||||||
assert "nextTransition" == self.thermostat.hold_preference()
|
assert "nextTransition" == self.thermostat.hold_preference()
|
||||||
|
|
||||||
def test_climate_list(self):
|
|
||||||
"""Test climate list property."""
|
|
||||||
assert ["Climate1", "Climate2"] == self.thermostat.climate_list
|
|
||||||
|
|
||||||
def test_set_fan_mode_on(self):
|
def test_set_fan_mode_on(self):
|
||||||
"""Test set fan mode to on."""
|
"""Test set fan mode to on."""
|
||||||
self.data.reset_mock()
|
self.data.reset_mock()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user