Ecobee: Report Humidifier Action (#138756)

Co-authored-by: Josef Zweck <josef@zweck.dev>
This commit is contained in:
SLaks 2025-02-18 14:11:37 -05:00 committed by GitHub
parent c48797804d
commit 82ac3e3fdf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 10 deletions

View File

@ -3,11 +3,13 @@
from __future__ import annotations
from datetime import timedelta
from typing import Any
from homeassistant.components.humidifier import (
DEFAULT_MAX_HUMIDITY,
DEFAULT_MIN_HUMIDITY,
MODE_AUTO,
HumidifierAction,
HumidifierDeviceClass,
HumidifierEntity,
HumidifierEntityFeature,
@ -41,6 +43,12 @@ async def async_setup_entry(
async_add_entities(entities, True)
ECOBEE_HUMIDIFIER_ACTION_TO_HASS = {
"humidifier": HumidifierAction.HUMIDIFYING,
"dehumidifier": HumidifierAction.DRYING,
}
class EcobeeHumidifier(HumidifierEntity):
"""A humidifier class for an ecobee thermostat with humidifier attached."""
@ -52,7 +60,7 @@ class EcobeeHumidifier(HumidifierEntity):
_attr_has_entity_name = True
_attr_name = None
def __init__(self, data, thermostat_index):
def __init__(self, data, thermostat_index) -> None:
"""Initialize ecobee humidifier platform."""
self.data = data
self.thermostat_index = thermostat_index
@ -80,11 +88,11 @@ class EcobeeHumidifier(HumidifierEntity):
)
@property
def available(self):
def available(self) -> bool:
"""Return if device is available."""
return self.thermostat["runtime"]["connected"]
async def async_update(self):
async def async_update(self) -> None:
"""Get the latest state from the thermostat."""
if self.update_without_throttle:
await self.data.update(no_throttle=True)
@ -96,12 +104,20 @@ class EcobeeHumidifier(HumidifierEntity):
self._last_humidifier_on_mode = self.mode
@property
def is_on(self):
def action(self) -> HumidifierAction:
"""Return the current action."""
for status in self.thermostat["equipmentStatus"].split(","):
if status in ECOBEE_HUMIDIFIER_ACTION_TO_HASS:
return ECOBEE_HUMIDIFIER_ACTION_TO_HASS[status]
return HumidifierAction.IDLE if self.is_on else HumidifierAction.OFF
@property
def is_on(self) -> bool:
"""Return True if the humidifier is on."""
return self.mode != MODE_OFF
@property
def mode(self):
def mode(self) -> str:
"""Return the current mode, e.g., off, auto, manual."""
return self.thermostat["settings"]["humidifierMode"]
@ -118,9 +134,11 @@ class EcobeeHumidifier(HumidifierEntity):
except KeyError:
return None
def set_mode(self, mode):
def set_mode(self, mode: str) -> None:
"""Set humidifier mode (auto, off, manual)."""
if mode.lower() not in (self.available_modes):
if self.available_modes is None:
raise NotImplementedError("Humidifier does not support modes.")
if mode.lower() not in self.available_modes:
raise ValueError(
f"Invalid mode value: {mode} Valid values are"
f" {', '.join(self.available_modes)}."
@ -134,10 +152,10 @@ class EcobeeHumidifier(HumidifierEntity):
self.data.ecobee.set_humidity(self.thermostat_index, humidity)
self.update_without_throttle = True
def turn_off(self, **kwargs):
def turn_off(self, **kwargs: Any) -> None:
"""Set humidifier to off mode."""
self.set_mode(MODE_OFF)
def turn_on(self, **kwargs):
def turn_on(self, **kwargs: Any) -> None:
"""Set humidifier to on mode."""
self.set_mode(self._last_humidifier_on_mode)

View File

@ -67,7 +67,7 @@
"hasHeatPump": false,
"humidity": "30"
},
"equipmentStatus": "fan",
"equipmentStatus": "fan,humidifier",
"events": [
{
"name": "Event1",

View File

@ -6,6 +6,7 @@ import pytest
from homeassistant.components.ecobee.humidifier import MODE_MANUAL, MODE_OFF
from homeassistant.components.humidifier import (
ATTR_ACTION,
ATTR_AVAILABLE_MODES,
ATTR_CURRENT_HUMIDITY,
ATTR_HUMIDITY,
@ -17,6 +18,7 @@ from homeassistant.components.humidifier import (
MODE_AUTO,
SERVICE_SET_HUMIDITY,
SERVICE_SET_MODE,
HumidifierAction,
HumidifierDeviceClass,
HumidifierEntityFeature,
)
@ -44,6 +46,7 @@ async def test_attributes(hass: HomeAssistant) -> None:
state = hass.states.get(DEVICE_ID)
assert state.state == STATE_ON
assert state.attributes[ATTR_ACTION] == HumidifierAction.HUMIDIFYING
assert state.attributes[ATTR_CURRENT_HUMIDITY] == 15
assert state.attributes[ATTR_MIN_HUMIDITY] == DEFAULT_MIN_HUMIDITY
assert state.attributes[ATTR_MAX_HUMIDITY] == DEFAULT_MAX_HUMIDITY