Add action attribute to Humidifier entity (#95131)

* Add HumidifierAction StrEnum

* Add action attribute to HumidifierEntity

* Update strings.json

* Add action to demo humidifier

* Add tests

* Fix imports

* Add 'off' humidifier action

* Set action to 'off' when state is 'off'

* Add 'off' action to strings.json

* Test that action sets to "off" when state is "off"

* Use is_on instead of state

* Fix typo

* black
This commit is contained in:
Denis Shulyaka 2023-06-28 14:21:17 +03:00 committed by GitHub
parent 8b6ed9c6b9
commit ae21ab2945
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 0 deletions

View file

@ -4,6 +4,7 @@ from __future__ import annotations
from typing import Any
from homeassistant.components.humidifier import (
HumidifierAction,
HumidifierDeviceClass,
HumidifierEntity,
HumidifierEntityFeature,
@ -30,6 +31,7 @@ async def async_setup_platform(
mode=None,
target_humidity=68,
current_humidity=45,
action=HumidifierAction.HUMIDIFYING,
device_class=HumidifierDeviceClass.HUMIDIFIER,
),
DemoHumidifier(
@ -37,6 +39,7 @@ async def async_setup_platform(
mode=None,
target_humidity=54,
current_humidity=59,
action=HumidifierAction.DRYING,
device_class=HumidifierDeviceClass.DEHUMIDIFIER,
),
DemoHumidifier(
@ -71,11 +74,13 @@ class DemoHumidifier(HumidifierEntity):
current_humidity: int | None = None,
available_modes: list[str] | None = None,
is_on: bool = True,
action: HumidifierAction | None = None,
device_class: HumidifierDeviceClass | None = None,
) -> None:
"""Initialize the humidifier device."""
self._attr_name = name
self._attr_is_on = is_on
self._attr_action = action
self._attr_supported_features = SUPPORT_FLAGS
if mode is not None:
self._attr_supported_features |= HumidifierEntityFeature.MODES

View file

@ -29,6 +29,7 @@ from homeassistant.helpers.typing import ConfigType
from homeassistant.loader import bind_hass
from .const import ( # noqa: F401
ATTR_ACTION,
ATTR_AVAILABLE_MODES,
ATTR_CURRENT_HUMIDITY,
ATTR_HUMIDITY,
@ -45,6 +46,7 @@ from .const import ( # noqa: F401
SERVICE_SET_HUMIDITY,
SERVICE_SET_MODE,
SUPPORT_MODES,
HumidifierAction,
HumidifierEntityFeature,
)
@ -133,6 +135,7 @@ class HumidifierEntity(ToggleEntity):
"""Base class for humidifier entities."""
entity_description: HumidifierEntityDescription
_attr_action: HumidifierAction | None = None
_attr_available_modes: list[str] | None
_attr_current_humidity: int | None = None
_attr_device_class: HumidifierDeviceClass | None
@ -170,6 +173,9 @@ class HumidifierEntity(ToggleEntity):
"""Return the optional state attributes."""
data: dict[str, int | str | None] = {}
if self.action is not None:
data[ATTR_ACTION] = self.action if self.is_on else HumidifierAction.OFF
if self.current_humidity is not None:
data[ATTR_CURRENT_HUMIDITY] = self.current_humidity
@ -181,6 +187,11 @@ class HumidifierEntity(ToggleEntity):
return data
@property
def action(self) -> HumidifierAction | None:
"""Return the current action."""
return self._attr_action
@property
def current_humidity(self) -> int | None:
"""Return the current humidity."""

View file

@ -1,6 +1,8 @@
"""Provides the constants needed for component."""
from enum import IntFlag
from homeassistant.backports.enum import StrEnum
MODE_NORMAL = "normal"
MODE_ECO = "eco"
MODE_AWAY = "away"
@ -11,6 +13,17 @@ MODE_SLEEP = "sleep"
MODE_AUTO = "auto"
MODE_BABY = "baby"
class HumidifierAction(StrEnum):
"""Actions for humidifier devices."""
HUMIDIFYING = "humidifying"
DRYING = "drying"
IDLE = "idle"
OFF = "off"
ATTR_ACTION = "action"
ATTR_AVAILABLE_MODES = "available_modes"
ATTR_CURRENT_HUMIDITY = "current_humidity"
ATTR_HUMIDITY = "humidity"

View file

@ -28,6 +28,15 @@
"on": "[%key:common::state::on%]"
},
"state_attributes": {
"action": {
"name": "Action",
"state": {
"humidifying": "Humidifying",
"drying": "Drying",
"idle": "Idle",
"off": "Off"
}
},
"available_modes": {
"name": "Available modes"
},

View file

@ -4,6 +4,7 @@ import pytest
import voluptuous as vol
from homeassistant.components.humidifier import (
ATTR_ACTION,
ATTR_CURRENT_HUMIDITY,
ATTR_HUMIDITY,
ATTR_MAX_HUMIDITY,
@ -45,6 +46,7 @@ def test_setup_params(hass: HomeAssistant) -> None:
assert state.state == STATE_ON
assert state.attributes.get(ATTR_HUMIDITY) == 54
assert state.attributes.get(ATTR_CURRENT_HUMIDITY) == 59
assert state.attributes.get(ATTR_ACTION) == "drying"
def test_default_setup_params(hass: HomeAssistant) -> None:
@ -124,12 +126,14 @@ async def test_turn_on(hass: HomeAssistant) -> None:
)
state = hass.states.get(ENTITY_DEHUMIDIFIER)
assert state.state == STATE_OFF
assert state.attributes.get(ATTR_ACTION) == "off"
await hass.services.async_call(
DOMAIN, SERVICE_TURN_ON, {ATTR_ENTITY_ID: ENTITY_DEHUMIDIFIER}, blocking=True
)
state = hass.states.get(ENTITY_DEHUMIDIFIER)
assert state.state == STATE_ON
assert state.attributes.get(ATTR_ACTION) == "drying"
async def test_turn_off(hass: HomeAssistant) -> None:
@ -139,12 +143,14 @@ async def test_turn_off(hass: HomeAssistant) -> None:
)
state = hass.states.get(ENTITY_DEHUMIDIFIER)
assert state.state == STATE_ON
assert state.attributes.get(ATTR_ACTION) == "drying"
await hass.services.async_call(
DOMAIN, SERVICE_TURN_OFF, {ATTR_ENTITY_ID: ENTITY_DEHUMIDIFIER}, blocking=True
)
state = hass.states.get(ENTITY_DEHUMIDIFIER)
assert state.state == STATE_OFF
assert state.attributes.get(ATTR_ACTION) == "off"
async def test_toggle(hass: HomeAssistant) -> None: