Use wemo enums in fan entity (#64397)
This commit is contained in:
parent
2f8d99bf5d
commit
35cf6d7a7b
2 changed files with 74 additions and 35 deletions
|
@ -6,6 +6,7 @@ from datetime import timedelta
|
||||||
import math
|
import math
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from pywemo.ouimeaux_device.humidifier import DesiredHumidity, FanMode, Humidifier
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.fan import SUPPORT_SET_SPEED, FanEntity
|
from homeassistant.components.fan import SUPPORT_SET_SPEED, FanEntity
|
||||||
|
@ -38,22 +39,7 @@ ATTR_FILTER_LIFE = "filter_life"
|
||||||
ATTR_FILTER_EXPIRED = "filter_expired"
|
ATTR_FILTER_EXPIRED = "filter_expired"
|
||||||
ATTR_WATER_LEVEL = "water_level"
|
ATTR_WATER_LEVEL = "water_level"
|
||||||
|
|
||||||
WEMO_HUMIDITY_45 = 0
|
SPEED_RANGE = (FanMode.Minimum, FanMode.Maximum) # off is not included
|
||||||
WEMO_HUMIDITY_50 = 1
|
|
||||||
WEMO_HUMIDITY_55 = 2
|
|
||||||
WEMO_HUMIDITY_60 = 3
|
|
||||||
WEMO_HUMIDITY_100 = 4
|
|
||||||
|
|
||||||
WEMO_FAN_OFF = 0
|
|
||||||
WEMO_FAN_MINIMUM = 1
|
|
||||||
WEMO_FAN_MEDIUM = 4
|
|
||||||
WEMO_FAN_MAXIMUM = 5
|
|
||||||
|
|
||||||
SPEED_RANGE = (WEMO_FAN_MINIMUM, WEMO_FAN_MAXIMUM) # off is not included
|
|
||||||
|
|
||||||
WEMO_WATER_EMPTY = 0
|
|
||||||
WEMO_WATER_LOW = 1
|
|
||||||
WEMO_WATER_GOOD = 2
|
|
||||||
|
|
||||||
SUPPORTED_FEATURES = SUPPORT_SET_SPEED
|
SUPPORTED_FEATURES = SUPPORT_SET_SPEED
|
||||||
|
|
||||||
|
@ -101,13 +87,15 @@ async def async_setup_entry(
|
||||||
class WemoHumidifier(WemoBinaryStateEntity, FanEntity):
|
class WemoHumidifier(WemoBinaryStateEntity, FanEntity):
|
||||||
"""Representation of a WeMo humidifier."""
|
"""Representation of a WeMo humidifier."""
|
||||||
|
|
||||||
|
wemo: Humidifier
|
||||||
|
|
||||||
def __init__(self, coordinator: DeviceCoordinator) -> None:
|
def __init__(self, coordinator: DeviceCoordinator) -> None:
|
||||||
"""Initialize the WeMo switch."""
|
"""Initialize the WeMo switch."""
|
||||||
super().__init__(coordinator)
|
super().__init__(coordinator)
|
||||||
if self.wemo.fan_mode != WEMO_FAN_OFF:
|
if self.wemo.fan_mode != FanMode.Off:
|
||||||
self._last_fan_on_mode = self.wemo.fan_mode
|
self._last_fan_on_mode = self.wemo.fan_mode
|
||||||
else:
|
else:
|
||||||
self._last_fan_on_mode = WEMO_FAN_MEDIUM
|
self._last_fan_on_mode = FanMode.High
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def icon(self) -> str:
|
def icon(self) -> str:
|
||||||
|
@ -144,7 +132,7 @@ class WemoHumidifier(WemoBinaryStateEntity, FanEntity):
|
||||||
@callback
|
@callback
|
||||||
def _handle_coordinator_update(self) -> None:
|
def _handle_coordinator_update(self) -> None:
|
||||||
"""Handle updated data from the coordinator."""
|
"""Handle updated data from the coordinator."""
|
||||||
if self.wemo.fan_mode != WEMO_FAN_OFF:
|
if self.wemo.fan_mode != FanMode.Off:
|
||||||
self._last_fan_on_mode = self.wemo.fan_mode
|
self._last_fan_on_mode = self.wemo.fan_mode
|
||||||
super()._handle_coordinator_update()
|
super()._handle_coordinator_update()
|
||||||
|
|
||||||
|
@ -161,16 +149,18 @@ class WemoHumidifier(WemoBinaryStateEntity, FanEntity):
|
||||||
def turn_off(self, **kwargs: Any) -> None:
|
def turn_off(self, **kwargs: Any) -> None:
|
||||||
"""Turn the switch off."""
|
"""Turn the switch off."""
|
||||||
with self._wemo_call_wrapper("turn off"):
|
with self._wemo_call_wrapper("turn off"):
|
||||||
self.wemo.set_state(WEMO_FAN_OFF)
|
self.wemo.set_state(FanMode.Off)
|
||||||
|
|
||||||
def set_percentage(self, percentage: int | None) -> None:
|
def set_percentage(self, percentage: int | None) -> None:
|
||||||
"""Set the fan_mode of the Humidifier."""
|
"""Set the fan_mode of the Humidifier."""
|
||||||
if percentage is None:
|
if percentage is None:
|
||||||
named_speed = self._last_fan_on_mode
|
named_speed = self._last_fan_on_mode
|
||||||
elif percentage == 0:
|
elif percentage == 0:
|
||||||
named_speed = WEMO_FAN_OFF
|
named_speed = FanMode.Off
|
||||||
else:
|
else:
|
||||||
named_speed = math.ceil(percentage_to_ranged_value(SPEED_RANGE, percentage))
|
named_speed = FanMode(
|
||||||
|
math.ceil(percentage_to_ranged_value(SPEED_RANGE, percentage))
|
||||||
|
)
|
||||||
|
|
||||||
with self._wemo_call_wrapper("set speed"):
|
with self._wemo_call_wrapper("set speed"):
|
||||||
self.wemo.set_state(named_speed)
|
self.wemo.set_state(named_speed)
|
||||||
|
@ -178,15 +168,15 @@ class WemoHumidifier(WemoBinaryStateEntity, FanEntity):
|
||||||
def set_humidity(self, target_humidity: float) -> None:
|
def set_humidity(self, target_humidity: float) -> None:
|
||||||
"""Set the target humidity level for the Humidifier."""
|
"""Set the target humidity level for the Humidifier."""
|
||||||
if target_humidity < 50:
|
if target_humidity < 50:
|
||||||
pywemo_humidity = WEMO_HUMIDITY_45
|
pywemo_humidity = DesiredHumidity.FortyFivePercent
|
||||||
elif 50 <= target_humidity < 55:
|
elif 50 <= target_humidity < 55:
|
||||||
pywemo_humidity = WEMO_HUMIDITY_50
|
pywemo_humidity = DesiredHumidity.FiftyPercent
|
||||||
elif 55 <= target_humidity < 60:
|
elif 55 <= target_humidity < 60:
|
||||||
pywemo_humidity = WEMO_HUMIDITY_55
|
pywemo_humidity = DesiredHumidity.FiftyFivePercent
|
||||||
elif 60 <= target_humidity < 100:
|
elif 60 <= target_humidity < 100:
|
||||||
pywemo_humidity = WEMO_HUMIDITY_60
|
pywemo_humidity = DesiredHumidity.SixtyPercent
|
||||||
elif target_humidity >= 100:
|
elif target_humidity >= 100:
|
||||||
pywemo_humidity = WEMO_HUMIDITY_100
|
pywemo_humidity = DesiredHumidity.OneHundredPercent
|
||||||
|
|
||||||
with self._wemo_call_wrapper("set humidity"):
|
with self._wemo_call_wrapper("set humidity"):
|
||||||
self.wemo.set_humidity(pywemo_humidity)
|
self.wemo.set_humidity(pywemo_humidity)
|
||||||
|
|
|
@ -2,15 +2,20 @@
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from pywemo.exceptions import ActionException
|
from pywemo.exceptions import ActionException
|
||||||
|
from pywemo.ouimeaux_device.humidifier import DesiredHumidity, FanMode
|
||||||
|
|
||||||
from homeassistant.components.fan import DOMAIN as FAN_DOMAIN
|
from homeassistant.components.fan import (
|
||||||
|
ATTR_PERCENTAGE,
|
||||||
|
DOMAIN as FAN_DOMAIN,
|
||||||
|
SERVICE_SET_PERCENTAGE,
|
||||||
|
)
|
||||||
from homeassistant.components.homeassistant import (
|
from homeassistant.components.homeassistant import (
|
||||||
DOMAIN as HA_DOMAIN,
|
DOMAIN as HA_DOMAIN,
|
||||||
SERVICE_UPDATE_ENTITY,
|
SERVICE_UPDATE_ENTITY,
|
||||||
)
|
)
|
||||||
from homeassistant.components.wemo import fan
|
from homeassistant.components.wemo import fan
|
||||||
from homeassistant.components.wemo.const import DOMAIN
|
from homeassistant.components.wemo.const import DOMAIN
|
||||||
from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON
|
from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_ON, STATE_OFF, STATE_ON
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from . import entity_test_helpers
|
from . import entity_test_helpers
|
||||||
|
@ -108,12 +113,12 @@ async def test_fan_reset_filter_service(hass, pywemo_device, wemo_entity):
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"test_input,expected",
|
"test_input,expected",
|
||||||
[
|
[
|
||||||
(0, fan.WEMO_HUMIDITY_45),
|
(0, DesiredHumidity.FortyFivePercent),
|
||||||
(45, fan.WEMO_HUMIDITY_45),
|
(45, DesiredHumidity.FortyFivePercent),
|
||||||
(50, fan.WEMO_HUMIDITY_50),
|
(50, DesiredHumidity.FiftyPercent),
|
||||||
(55, fan.WEMO_HUMIDITY_55),
|
(55, DesiredHumidity.FiftyFivePercent),
|
||||||
(60, fan.WEMO_HUMIDITY_60),
|
(60, DesiredHumidity.SixtyPercent),
|
||||||
(100, fan.WEMO_HUMIDITY_100),
|
(100, DesiredHumidity.OneHundredPercent),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
async def test_fan_set_humidity_service(
|
async def test_fan_set_humidity_service(
|
||||||
|
@ -130,3 +135,47 @@ async def test_fan_set_humidity_service(
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
pywemo_device.set_humidity.assert_called_with(expected)
|
pywemo_device.set_humidity.assert_called_with(expected)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"percentage,expected_fan_mode",
|
||||||
|
[
|
||||||
|
(0, FanMode.Off),
|
||||||
|
(10, FanMode.Minimum),
|
||||||
|
(30, FanMode.Low),
|
||||||
|
(50, FanMode.Medium),
|
||||||
|
(70, FanMode.High),
|
||||||
|
(100, FanMode.Maximum),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_fan_set_percentage(
|
||||||
|
hass, pywemo_device, wemo_entity, percentage, expected_fan_mode
|
||||||
|
):
|
||||||
|
"""Verify set_percentage works properly through the entire range of FanModes."""
|
||||||
|
assert await hass.services.async_call(
|
||||||
|
FAN_DOMAIN,
|
||||||
|
SERVICE_SET_PERCENTAGE,
|
||||||
|
{ATTR_ENTITY_ID: [wemo_entity.entity_id], ATTR_PERCENTAGE: percentage},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
pywemo_device.set_state.assert_called_with(expected_fan_mode)
|
||||||
|
|
||||||
|
|
||||||
|
class TestInitialFanMode:
|
||||||
|
"""Test that the FanMode is set to High when turned on the first time."""
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def pywemo_device(self, pywemo_device):
|
||||||
|
"""Set the FanMode to off initially."""
|
||||||
|
pywemo_device.fan_mode = FanMode.Off
|
||||||
|
yield pywemo_device
|
||||||
|
|
||||||
|
async def test_fan_mode_high_initially(self, hass, pywemo_device, wemo_entity):
|
||||||
|
"""Verify the FanMode is set to High when turned on."""
|
||||||
|
assert await hass.services.async_call(
|
||||||
|
FAN_DOMAIN,
|
||||||
|
SERVICE_TURN_ON,
|
||||||
|
{ATTR_ENTITY_ID: [wemo_entity.entity_id]},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
pywemo_device.set_state.assert_called_with(FanMode.High)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue