mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Add new humidifier entity integration (#28693)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
747490ab34
commit
c28493098a
@ -185,6 +185,7 @@ homeassistant/components/http/* @home-assistant/core
|
|||||||
homeassistant/components/huawei_lte/* @scop @fphammerle
|
homeassistant/components/huawei_lte/* @scop @fphammerle
|
||||||
homeassistant/components/huawei_router/* @abmantis
|
homeassistant/components/huawei_router/* @abmantis
|
||||||
homeassistant/components/hue/* @balloob
|
homeassistant/components/hue/* @balloob
|
||||||
|
homeassistant/components/humidifier/* @home-assistant/core @Shulyaka
|
||||||
homeassistant/components/hunterdouglas_powerview/* @bdraco
|
homeassistant/components/hunterdouglas_powerview/* @bdraco
|
||||||
homeassistant/components/hvv_departures/* @vigonotion
|
homeassistant/components/hvv_departures/* @vigonotion
|
||||||
homeassistant/components/hydrawise/* @ptcryan
|
homeassistant/components/hydrawise/* @ptcryan
|
||||||
|
@ -18,6 +18,7 @@ COMPONENTS_WITH_CONFIG_ENTRY_DEMO_PLATFORM = [
|
|||||||
"climate",
|
"climate",
|
||||||
"cover",
|
"cover",
|
||||||
"fan",
|
"fan",
|
||||||
|
"humidifier",
|
||||||
"light",
|
"light",
|
||||||
"lock",
|
"lock",
|
||||||
"media_player",
|
"media_player",
|
||||||
|
124
homeassistant/components/demo/humidifier.py
Normal file
124
homeassistant/components/demo/humidifier.py
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
"""Demo platform that offers a fake humidifier device."""
|
||||||
|
from homeassistant.components.humidifier import HumidifierEntity
|
||||||
|
from homeassistant.components.humidifier.const import (
|
||||||
|
DEVICE_CLASS_DEHUMIDIFIER,
|
||||||
|
DEVICE_CLASS_HUMIDIFIER,
|
||||||
|
SUPPORT_MODES,
|
||||||
|
)
|
||||||
|
|
||||||
|
SUPPORT_FLAGS = 0
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||||
|
"""Set up the Demo humidifier devices."""
|
||||||
|
async_add_entities(
|
||||||
|
[
|
||||||
|
DemoHumidifier(
|
||||||
|
name="Humidifier",
|
||||||
|
mode=None,
|
||||||
|
target_humidity=68,
|
||||||
|
device_class=DEVICE_CLASS_HUMIDIFIER,
|
||||||
|
),
|
||||||
|
DemoHumidifier(
|
||||||
|
name="Dehumidifier",
|
||||||
|
mode=None,
|
||||||
|
target_humidity=54,
|
||||||
|
device_class=DEVICE_CLASS_DEHUMIDIFIER,
|
||||||
|
),
|
||||||
|
DemoHumidifier(
|
||||||
|
name="Hygrostat",
|
||||||
|
mode="home",
|
||||||
|
available_modes=["home", "eco"],
|
||||||
|
target_humidity=50,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||||
|
"""Set up the Demo humidifier devices config entry."""
|
||||||
|
await async_setup_platform(hass, {}, async_add_entities)
|
||||||
|
|
||||||
|
|
||||||
|
class DemoHumidifier(HumidifierEntity):
|
||||||
|
"""Representation of a demo humidifier device."""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
name,
|
||||||
|
mode,
|
||||||
|
target_humidity,
|
||||||
|
available_modes=None,
|
||||||
|
is_on=True,
|
||||||
|
device_class=None,
|
||||||
|
):
|
||||||
|
"""Initialize the humidifier device."""
|
||||||
|
self._name = name
|
||||||
|
self._state = is_on
|
||||||
|
self._support_flags = SUPPORT_FLAGS
|
||||||
|
if mode is not None:
|
||||||
|
self._support_flags = self._support_flags | SUPPORT_MODES
|
||||||
|
self._target_humidity = target_humidity
|
||||||
|
self._mode = mode
|
||||||
|
self._available_modes = available_modes
|
||||||
|
self._device_class = device_class
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self):
|
||||||
|
"""Return the list of supported features."""
|
||||||
|
return self._support_flags
|
||||||
|
|
||||||
|
@property
|
||||||
|
def should_poll(self):
|
||||||
|
"""Return the polling state."""
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Return the name of the humidity device."""
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_humidity(self):
|
||||||
|
"""Return the humidity we try to reach."""
|
||||||
|
return self._target_humidity
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mode(self):
|
||||||
|
"""Return current mode."""
|
||||||
|
return self._mode
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available_modes(self):
|
||||||
|
"""Return available modes."""
|
||||||
|
return self._available_modes
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_on(self):
|
||||||
|
"""Return true if the humidifier is on."""
|
||||||
|
return self._state
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_class(self):
|
||||||
|
"""Return the device class of the humidifier."""
|
||||||
|
return self._device_class
|
||||||
|
|
||||||
|
async def async_turn_on(self, **kwargs):
|
||||||
|
"""Turn the device on."""
|
||||||
|
self._state = True
|
||||||
|
self.async_write_ha_state()
|
||||||
|
|
||||||
|
async def async_turn_off(self, **kwargs):
|
||||||
|
"""Turn the device off."""
|
||||||
|
self._state = False
|
||||||
|
self.async_write_ha_state()
|
||||||
|
|
||||||
|
async def async_set_humidity(self, humidity):
|
||||||
|
"""Set new humidity level."""
|
||||||
|
self._target_humidity = humidity
|
||||||
|
self.async_write_ha_state()
|
||||||
|
|
||||||
|
async def async_set_mode(self, mode):
|
||||||
|
"""Update mode."""
|
||||||
|
self._mode = mode
|
||||||
|
self.async_write_ha_state()
|
@ -50,9 +50,21 @@ CONFIG_SCHEMA = vol.Schema(
|
|||||||
extra=vol.ALLOW_EXTRA,
|
extra=vol.ALLOW_EXTRA,
|
||||||
)
|
)
|
||||||
|
|
||||||
SIGNIFICANT_DOMAINS = ("climate", "device_tracker", "thermostat", "water_heater")
|
SIGNIFICANT_DOMAINS = (
|
||||||
|
"climate",
|
||||||
|
"device_tracker",
|
||||||
|
"humidifier",
|
||||||
|
"thermostat",
|
||||||
|
"water_heater",
|
||||||
|
)
|
||||||
IGNORE_DOMAINS = ("zone", "scene")
|
IGNORE_DOMAINS = ("zone", "scene")
|
||||||
NEED_ATTRIBUTE_DOMAINS = {"climate", "water_heater", "thermostat", "script"}
|
NEED_ATTRIBUTE_DOMAINS = {
|
||||||
|
"climate",
|
||||||
|
"humidifier",
|
||||||
|
"script",
|
||||||
|
"thermostat",
|
||||||
|
"water_heater",
|
||||||
|
}
|
||||||
SCRIPT_DOMAIN = "script"
|
SCRIPT_DOMAIN = "script"
|
||||||
ATTR_CAN_CANCEL = "can_cancel"
|
ATTR_CAN_CANCEL = "can_cancel"
|
||||||
|
|
||||||
|
175
homeassistant/components/humidifier/__init__.py
Normal file
175
homeassistant/components/humidifier/__init__.py
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
"""Provides functionality to interact with humidifier devices."""
|
||||||
|
from datetime import timedelta
|
||||||
|
import logging
|
||||||
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.const import (
|
||||||
|
SERVICE_TOGGLE,
|
||||||
|
SERVICE_TURN_OFF,
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
STATE_ON,
|
||||||
|
)
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
from homeassistant.helpers.config_validation import ( # noqa: F401
|
||||||
|
PLATFORM_SCHEMA,
|
||||||
|
PLATFORM_SCHEMA_BASE,
|
||||||
|
)
|
||||||
|
from homeassistant.helpers.entity import ToggleEntity
|
||||||
|
from homeassistant.helpers.entity_component import EntityComponent
|
||||||
|
from homeassistant.helpers.typing import ConfigType, HomeAssistantType
|
||||||
|
from homeassistant.loader import bind_hass
|
||||||
|
|
||||||
|
from .const import (
|
||||||
|
ATTR_AVAILABLE_MODES,
|
||||||
|
ATTR_HUMIDITY,
|
||||||
|
ATTR_MAX_HUMIDITY,
|
||||||
|
ATTR_MIN_HUMIDITY,
|
||||||
|
ATTR_MODE,
|
||||||
|
DEFAULT_MAX_HUMIDITY,
|
||||||
|
DEFAULT_MIN_HUMIDITY,
|
||||||
|
DEVICE_CLASS_DEHUMIDIFIER,
|
||||||
|
DEVICE_CLASS_HUMIDIFIER,
|
||||||
|
DOMAIN,
|
||||||
|
SERVICE_SET_HUMIDITY,
|
||||||
|
SERVICE_SET_MODE,
|
||||||
|
SUPPORT_MODES,
|
||||||
|
)
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
SCAN_INTERVAL = timedelta(seconds=60)
|
||||||
|
|
||||||
|
DEVICE_CLASSES = [DEVICE_CLASS_HUMIDIFIER, DEVICE_CLASS_DEHUMIDIFIER]
|
||||||
|
|
||||||
|
DEVICE_CLASSES_SCHEMA = vol.All(vol.Lower, vol.In(DEVICE_CLASSES))
|
||||||
|
|
||||||
|
|
||||||
|
@bind_hass
|
||||||
|
def is_on(hass, entity_id):
|
||||||
|
"""Return if the humidifier is on based on the statemachine.
|
||||||
|
|
||||||
|
Async friendly.
|
||||||
|
"""
|
||||||
|
return hass.states.is_state(entity_id, STATE_ON)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup(hass: HomeAssistantType, config: ConfigType) -> bool:
|
||||||
|
"""Set up humidifier devices."""
|
||||||
|
component = hass.data[DOMAIN] = EntityComponent(
|
||||||
|
_LOGGER, DOMAIN, hass, SCAN_INTERVAL
|
||||||
|
)
|
||||||
|
await component.async_setup(config)
|
||||||
|
|
||||||
|
component.async_register_entity_service(SERVICE_TURN_ON, {}, "async_turn_on")
|
||||||
|
component.async_register_entity_service(SERVICE_TURN_OFF, {}, "async_turn_off")
|
||||||
|
component.async_register_entity_service(SERVICE_TOGGLE, {}, "async_toggle")
|
||||||
|
component.async_register_entity_service(
|
||||||
|
SERVICE_SET_MODE,
|
||||||
|
{vol.Required(ATTR_MODE): cv.string},
|
||||||
|
"async_set_mode",
|
||||||
|
[SUPPORT_MODES],
|
||||||
|
)
|
||||||
|
component.async_register_entity_service(
|
||||||
|
SERVICE_SET_HUMIDITY,
|
||||||
|
{
|
||||||
|
vol.Required(ATTR_HUMIDITY): vol.All(
|
||||||
|
vol.Coerce(int), vol.Range(min=0, max=100)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"async_set_humidity",
|
||||||
|
)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool:
|
||||||
|
"""Set up a config entry."""
|
||||||
|
return await hass.data[DOMAIN].async_setup_entry(entry)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_unload_entry(hass: HomeAssistantType, entry: ConfigEntry) -> bool:
|
||||||
|
"""Unload a config entry."""
|
||||||
|
return await hass.data[DOMAIN].async_unload_entry(entry)
|
||||||
|
|
||||||
|
|
||||||
|
class HumidifierEntity(ToggleEntity):
|
||||||
|
"""Representation of a humidifier device."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def capability_attributes(self) -> Dict[str, Any]:
|
||||||
|
"""Return capability attributes."""
|
||||||
|
supported_features = self.supported_features or 0
|
||||||
|
data = {
|
||||||
|
ATTR_MIN_HUMIDITY: self.min_humidity,
|
||||||
|
ATTR_MAX_HUMIDITY: self.max_humidity,
|
||||||
|
}
|
||||||
|
|
||||||
|
if supported_features & SUPPORT_MODES:
|
||||||
|
data[ATTR_AVAILABLE_MODES] = self.available_modes
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state_attributes(self) -> Dict[str, Any]:
|
||||||
|
"""Return the optional state attributes."""
|
||||||
|
supported_features = self.supported_features or 0
|
||||||
|
data = {}
|
||||||
|
|
||||||
|
if self.target_humidity is not None:
|
||||||
|
data[ATTR_HUMIDITY] = self.target_humidity
|
||||||
|
|
||||||
|
if supported_features & SUPPORT_MODES:
|
||||||
|
data[ATTR_MODE] = self.mode
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
@property
|
||||||
|
def target_humidity(self) -> Optional[int]:
|
||||||
|
"""Return the humidity we try to reach."""
|
||||||
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def mode(self) -> Optional[str]:
|
||||||
|
"""Return the current mode, e.g., home, auto, baby.
|
||||||
|
|
||||||
|
Requires SUPPORT_MODES.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available_modes(self) -> Optional[List[str]]:
|
||||||
|
"""Return a list of available modes.
|
||||||
|
|
||||||
|
Requires SUPPORT_MODES.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def set_humidity(self, humidity: int) -> None:
|
||||||
|
"""Set new target humidity."""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
async def async_set_humidity(self, humidity: int) -> None:
|
||||||
|
"""Set new target humidity."""
|
||||||
|
await self.hass.async_add_executor_job(self.set_humidity, humidity)
|
||||||
|
|
||||||
|
def set_mode(self, mode: str) -> None:
|
||||||
|
"""Set new mode."""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
async def async_set_mode(self, mode: str) -> None:
|
||||||
|
"""Set new mode."""
|
||||||
|
await self.hass.async_add_executor_job(self.set_mode, mode)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_humidity(self) -> int:
|
||||||
|
"""Return the minimum humidity."""
|
||||||
|
return DEFAULT_MIN_HUMIDITY
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_humidity(self) -> int:
|
||||||
|
"""Return the maximum humidity."""
|
||||||
|
return DEFAULT_MAX_HUMIDITY
|
30
homeassistant/components/humidifier/const.py
Normal file
30
homeassistant/components/humidifier/const.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
"""Provides the constants needed for component."""
|
||||||
|
|
||||||
|
MODE_NORMAL = "normal"
|
||||||
|
MODE_ECO = "eco"
|
||||||
|
MODE_AWAY = "away"
|
||||||
|
MODE_BOOST = "boost"
|
||||||
|
MODE_COMFORT = "comfort"
|
||||||
|
MODE_HOME = "home"
|
||||||
|
MODE_SLEEP = "sleep"
|
||||||
|
MODE_AUTO = "auto"
|
||||||
|
MODE_BABY = "baby"
|
||||||
|
|
||||||
|
ATTR_MODE = "mode"
|
||||||
|
ATTR_AVAILABLE_MODES = "available_modes"
|
||||||
|
ATTR_HUMIDITY = "humidity"
|
||||||
|
ATTR_MAX_HUMIDITY = "max_humidity"
|
||||||
|
ATTR_MIN_HUMIDITY = "min_humidity"
|
||||||
|
|
||||||
|
DEFAULT_MIN_HUMIDITY = 0
|
||||||
|
DEFAULT_MAX_HUMIDITY = 100
|
||||||
|
|
||||||
|
DOMAIN = "humidifier"
|
||||||
|
|
||||||
|
DEVICE_CLASS_HUMIDIFIER = "humidifier"
|
||||||
|
DEVICE_CLASS_DEHUMIDIFIER = "dehumidifier"
|
||||||
|
|
||||||
|
SERVICE_SET_MODE = "set_mode"
|
||||||
|
SERVICE_SET_HUMIDITY = "set_humidity"
|
||||||
|
|
||||||
|
SUPPORT_MODES = 1
|
7
homeassistant/components/humidifier/manifest.json
Normal file
7
homeassistant/components/humidifier/manifest.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"domain": "humidifier",
|
||||||
|
"name": "Humidifier",
|
||||||
|
"documentation": "https://www.home-assistant.io/integrations/humidifier",
|
||||||
|
"codeowners": ["@home-assistant/core", "@Shulyaka"],
|
||||||
|
"quality_scale": "internal"
|
||||||
|
}
|
42
homeassistant/components/humidifier/services.yaml
Normal file
42
homeassistant/components/humidifier/services.yaml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# Describes the format for available humidifier services
|
||||||
|
|
||||||
|
set_mode:
|
||||||
|
description: Set mode for humidifier device.
|
||||||
|
fields:
|
||||||
|
entity_id:
|
||||||
|
description: Name(s) of entities to change.
|
||||||
|
example: 'humidifier.bedroom'
|
||||||
|
mode:
|
||||||
|
description: New mode
|
||||||
|
example: 'away'
|
||||||
|
|
||||||
|
set_humidity:
|
||||||
|
description: Set target humidity of humidifier device.
|
||||||
|
fields:
|
||||||
|
entity_id:
|
||||||
|
description: Name(s) of entities to change.
|
||||||
|
example: 'humidifier.bedroom'
|
||||||
|
humidity:
|
||||||
|
description: New target humidity for humidifier device.
|
||||||
|
example: 50
|
||||||
|
|
||||||
|
turn_on:
|
||||||
|
description: Turn humidifier device on.
|
||||||
|
fields:
|
||||||
|
entity_id:
|
||||||
|
description: Name(s) of entities to change.
|
||||||
|
example: 'humidifier.bedroom'
|
||||||
|
|
||||||
|
turn_off:
|
||||||
|
description: Turn humidifier device off.
|
||||||
|
fields:
|
||||||
|
entity_id:
|
||||||
|
description: Name(s) of entities to change.
|
||||||
|
example: 'humidifier.bedroom'
|
||||||
|
|
||||||
|
toggle:
|
||||||
|
description: Toggles a humidifier device.
|
||||||
|
fields:
|
||||||
|
entity_id:
|
||||||
|
description: Name(s) of entities to toggle.
|
||||||
|
example: 'humidifier.bedroom'
|
166
tests/components/demo/test_humidifier.py
Normal file
166
tests/components/demo/test_humidifier.py
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
"""The tests for the demo humidifier component."""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components.humidifier.const import (
|
||||||
|
ATTR_HUMIDITY,
|
||||||
|
ATTR_MAX_HUMIDITY,
|
||||||
|
ATTR_MIN_HUMIDITY,
|
||||||
|
ATTR_MODE,
|
||||||
|
DOMAIN,
|
||||||
|
MODE_AWAY,
|
||||||
|
MODE_ECO,
|
||||||
|
SERVICE_SET_HUMIDITY,
|
||||||
|
SERVICE_SET_MODE,
|
||||||
|
)
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_ENTITY_ID,
|
||||||
|
SERVICE_TOGGLE,
|
||||||
|
SERVICE_TURN_OFF,
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
STATE_OFF,
|
||||||
|
STATE_ON,
|
||||||
|
)
|
||||||
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
|
ENTITY_DEHUMIDIFIER = "humidifier.dehumidifier"
|
||||||
|
ENTITY_HYGROSTAT = "humidifier.hygrostat"
|
||||||
|
ENTITY_HUMIDIFIER = "humidifier.humidifier"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
async def setup_demo_humidifier(hass):
|
||||||
|
"""Initialize setup demo humidifier."""
|
||||||
|
assert await async_setup_component(
|
||||||
|
hass, DOMAIN, {"humidifier": {"platform": "demo"}}
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
|
||||||
|
def test_setup_params(hass):
|
||||||
|
"""Test the initial parameters."""
|
||||||
|
state = hass.states.get(ENTITY_DEHUMIDIFIER)
|
||||||
|
assert state.state == STATE_ON
|
||||||
|
assert state.attributes.get(ATTR_HUMIDITY) == 54
|
||||||
|
|
||||||
|
|
||||||
|
def test_default_setup_params(hass):
|
||||||
|
"""Test the setup with default parameters."""
|
||||||
|
state = hass.states.get(ENTITY_DEHUMIDIFIER)
|
||||||
|
assert state.attributes.get(ATTR_MIN_HUMIDITY) == 0
|
||||||
|
assert state.attributes.get(ATTR_MAX_HUMIDITY) == 100
|
||||||
|
|
||||||
|
|
||||||
|
async def test_set_target_humidity_bad_attr(hass):
|
||||||
|
"""Test setting the target humidity without required attribute."""
|
||||||
|
state = hass.states.get(ENTITY_DEHUMIDIFIER)
|
||||||
|
assert state.attributes.get(ATTR_HUMIDITY) == 54
|
||||||
|
|
||||||
|
with pytest.raises(vol.Invalid):
|
||||||
|
await hass.services.async_call(
|
||||||
|
DOMAIN,
|
||||||
|
SERVICE_SET_HUMIDITY,
|
||||||
|
{ATTR_HUMIDITY: None, ATTR_ENTITY_ID: ENTITY_DEHUMIDIFIER},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get(ENTITY_DEHUMIDIFIER)
|
||||||
|
assert state.attributes.get(ATTR_HUMIDITY) == 54
|
||||||
|
|
||||||
|
|
||||||
|
async def test_set_target_humidity(hass):
|
||||||
|
"""Test the setting of the target humidity."""
|
||||||
|
state = hass.states.get(ENTITY_DEHUMIDIFIER)
|
||||||
|
assert state.attributes.get(ATTR_HUMIDITY) == 54
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
DOMAIN,
|
||||||
|
SERVICE_SET_HUMIDITY,
|
||||||
|
{ATTR_HUMIDITY: 64, ATTR_ENTITY_ID: ENTITY_DEHUMIDIFIER},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get(ENTITY_DEHUMIDIFIER)
|
||||||
|
assert state.attributes.get(ATTR_HUMIDITY) == 64
|
||||||
|
|
||||||
|
|
||||||
|
async def test_set_hold_mode_away(hass):
|
||||||
|
"""Test setting the hold mode away."""
|
||||||
|
await hass.services.async_call(
|
||||||
|
DOMAIN,
|
||||||
|
SERVICE_SET_MODE,
|
||||||
|
{ATTR_MODE: MODE_AWAY, ATTR_ENTITY_ID: ENTITY_HYGROSTAT},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get(ENTITY_HYGROSTAT)
|
||||||
|
assert state.attributes.get(ATTR_MODE) == MODE_AWAY
|
||||||
|
|
||||||
|
|
||||||
|
async def test_set_hold_mode_eco(hass):
|
||||||
|
"""Test setting the hold mode eco."""
|
||||||
|
await hass.services.async_call(
|
||||||
|
DOMAIN,
|
||||||
|
SERVICE_SET_MODE,
|
||||||
|
{ATTR_MODE: MODE_ECO, ATTR_ENTITY_ID: ENTITY_HYGROSTAT},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get(ENTITY_HYGROSTAT)
|
||||||
|
assert state.attributes.get(ATTR_MODE) == MODE_ECO
|
||||||
|
|
||||||
|
|
||||||
|
async def test_turn_on(hass):
|
||||||
|
"""Test turn on device."""
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
async def test_turn_off(hass):
|
||||||
|
"""Test turn off device."""
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
async def test_toggle(hass):
|
||||||
|
"""Test toggle device."""
|
||||||
|
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
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: ENTITY_DEHUMIDIFIER}, blocking=True
|
||||||
|
)
|
||||||
|
state = hass.states.get(ENTITY_DEHUMIDIFIER)
|
||||||
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: ENTITY_DEHUMIDIFIER}, blocking=True
|
||||||
|
)
|
||||||
|
state = hass.states.get(ENTITY_DEHUMIDIFIER)
|
||||||
|
assert state.state == STATE_ON
|
1
tests/components/humidifier/__init__.py
Normal file
1
tests/components/humidifier/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
"""The tests for humidifier component."""
|
35
tests/components/humidifier/test_init.py
Normal file
35
tests/components/humidifier/test_init.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
"""The tests for the humidifier component."""
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
|
from homeassistant.components.humidifier import HumidifierEntity
|
||||||
|
|
||||||
|
|
||||||
|
class MockHumidifierEntity(HumidifierEntity):
|
||||||
|
"""Mock Humidifier device to use in tests."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> int:
|
||||||
|
"""Return the list of supported features."""
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sync_turn_on(hass):
|
||||||
|
"""Test if async turn_on calls sync turn_on."""
|
||||||
|
humidifier = MockHumidifierEntity()
|
||||||
|
humidifier.hass = hass
|
||||||
|
|
||||||
|
humidifier.turn_on = MagicMock()
|
||||||
|
await humidifier.async_turn_on()
|
||||||
|
|
||||||
|
assert humidifier.turn_on.called
|
||||||
|
|
||||||
|
|
||||||
|
async def test_sync_turn_off(hass):
|
||||||
|
"""Test if async turn_off calls sync turn_off."""
|
||||||
|
humidifier = MockHumidifierEntity()
|
||||||
|
humidifier.hass = hass
|
||||||
|
|
||||||
|
humidifier.turn_off = MagicMock()
|
||||||
|
await humidifier.async_turn_off()
|
||||||
|
|
||||||
|
assert humidifier.turn_off.called
|
Loading…
x
Reference in New Issue
Block a user