Expose comfort presets as HA presets (#25491)
* Expose comfort presets as HA presets * Fix bugs * Handle unavailable * log level debug on update * Lintpull/25639/head
parent
3649a1b5e9
commit
a398b39e12
|
@ -97,7 +97,7 @@ class EcobeeData:
|
|||
def update(self):
|
||||
"""Get the latest data from pyecobee."""
|
||||
self.ecobee.update()
|
||||
_LOGGER.info("Ecobee data updated successfully")
|
||||
_LOGGER.debug("Ecobee data updated successfully")
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
|
|
|
@ -88,16 +88,6 @@ PRESET_TO_ECOBEE_HOLD = {
|
|||
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_RESUME_PROGRAM = "ecobee_resume_program"
|
||||
|
||||
|
@ -199,7 +189,6 @@ class Thermostat(ClimateDevice):
|
|||
self._name = self.thermostat["name"]
|
||||
self.hold_temp = hold_temp
|
||||
self.vacation = None
|
||||
self._climate_list = self.climate_list
|
||||
|
||||
self._operation_list = []
|
||||
if self.thermostat["settings"]["heatStages"]:
|
||||
|
@ -210,6 +199,10 @@ class Thermostat(ClimateDevice):
|
|||
self._operation_list.insert(0, HVAC_MODE_AUTO)
|
||||
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.update_without_throttle = False
|
||||
|
||||
|
@ -223,6 +216,11 @@ class Thermostat(ClimateDevice):
|
|||
|
||||
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
|
||||
def supported_features(self):
|
||||
"""Return the list of supported features."""
|
||||
|
@ -294,15 +292,9 @@ class Thermostat(ClimateDevice):
|
|||
continue
|
||||
|
||||
if event["type"] == "hold":
|
||||
if event["holdClimateRef"] == "away":
|
||||
if int(event["endDate"][0:4]) - int(event["startDate"][0:4]) <= 1:
|
||||
# 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"]
|
||||
if event["holdClimateRef"] in self._preset_modes:
|
||||
return self._preset_modes[event["holdClimateRef"]]
|
||||
|
||||
# Any hold not based on a climate is a temp hold
|
||||
return PRESET_TEMPERATURE
|
||||
if event["type"].startswith("auto"):
|
||||
|
@ -324,14 +316,6 @@ class Thermostat(ClimateDevice):
|
|||
"""Return the operation modes 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
|
||||
def current_humidity(self) -> Optional[int]:
|
||||
"""Return the current humidity."""
|
||||
|
@ -373,9 +357,7 @@ class Thermostat(ClimateDevice):
|
|||
status = self.thermostat["equipmentStatus"]
|
||||
return {
|
||||
"fan": self.fan,
|
||||
"climate_mode": self.climate_mode,
|
||||
"equipment_running": status,
|
||||
"climate_list": self.climate_list,
|
||||
"fan_min_on_time": self.thermostat["settings"]["fanMinOnTime"],
|
||||
}
|
||||
|
||||
|
@ -413,6 +395,21 @@ class Thermostat(ClimateDevice):
|
|||
elif preset_mode == PRESET_NONE:
|
||||
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:
|
||||
self.data.ecobee.set_climate_hold(
|
||||
self.thermostat_index, preset_mode, self.hold_preference()
|
||||
|
@ -421,7 +418,7 @@ class Thermostat(ClimateDevice):
|
|||
@property
|
||||
def preset_modes(self):
|
||||
"""Return available preset modes."""
|
||||
return PRESET_MODES
|
||||
return list(self._preset_modes.values())
|
||||
|
||||
def set_auto_temp_hold(self, heat_temp, cool_temp):
|
||||
"""Set temperature hold in auto mode."""
|
||||
|
@ -543,9 +540,3 @@ class Thermostat(ClimateDevice):
|
|||
# supported; note that this should not include 'indefinite'
|
||||
# as an indefinite away hold is interpreted as away_mode
|
||||
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."""
|
||||
self.ecobee["equipmentStatus"] = "heatPump2"
|
||||
assert {
|
||||
"climate_list": ["Climate1", "Climate2"],
|
||||
"fan": "off",
|
||||
"fan_min_on_time": 10,
|
||||
"climate_mode": "Climate1",
|
||||
"equipment_running": "heatPump2",
|
||||
} == self.thermostat.device_state_attributes
|
||||
|
||||
self.ecobee["equipmentStatus"] = "auxHeat2"
|
||||
assert {
|
||||
"climate_list": ["Climate1", "Climate2"],
|
||||
"fan": "off",
|
||||
"fan_min_on_time": 10,
|
||||
"climate_mode": "Climate1",
|
||||
"equipment_running": "auxHeat2",
|
||||
} == self.thermostat.device_state_attributes
|
||||
self.ecobee["equipmentStatus"] = "compCool1"
|
||||
assert {
|
||||
"climate_list": ["Climate1", "Climate2"],
|
||||
"fan": "off",
|
||||
"fan_min_on_time": 10,
|
||||
"climate_mode": "Climate1",
|
||||
"equipment_running": "compCool1",
|
||||
} == self.thermostat.device_state_attributes
|
||||
self.ecobee["equipmentStatus"] = ""
|
||||
assert {
|
||||
"climate_list": ["Climate1", "Climate2"],
|
||||
"fan": "off",
|
||||
"fan_min_on_time": 10,
|
||||
"climate_mode": "Climate1",
|
||||
"equipment_running": "",
|
||||
} == self.thermostat.device_state_attributes
|
||||
|
||||
self.ecobee["equipmentStatus"] = "Unknown"
|
||||
assert {
|
||||
"climate_list": ["Climate1", "Climate2"],
|
||||
"fan": "off",
|
||||
"fan_min_on_time": 10,
|
||||
"climate_mode": "Climate1",
|
||||
"equipment_running": "Unknown",
|
||||
} == self.thermostat.device_state_attributes
|
||||
|
||||
|
@ -267,10 +257,6 @@ class TestEcobee(unittest.TestCase):
|
|||
self.ecobee["settings"]["holdAction"] = action
|
||||
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):
|
||||
"""Test set fan mode to on."""
|
||||
self.data.reset_mock()
|
||||
|
|
Loading…
Reference in New Issue