mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 13:47:35 +00:00
Change Dyson PureCoolLink fan speeds to adhere the standard (#45331)
This commit is contained in:
parent
a7741be9bb
commit
96448c6778
@ -1,5 +1,6 @@
|
|||||||
"""Support for Dyson Pure Cool link fan."""
|
"""Support for Dyson Pure Cool link fan."""
|
||||||
import logging
|
import logging
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from libpurecool.const import FanMode, FanSpeed, NightMode, Oscillation
|
from libpurecool.const import FanMode, FanSpeed, NightMode, Oscillation
|
||||||
from libpurecool.dyson_pure_cool import DysonPureCool
|
from libpurecool.dyson_pure_cool import DysonPureCool
|
||||||
@ -16,8 +17,7 @@ from homeassistant.components.fan import (
|
|||||||
SUPPORT_SET_SPEED,
|
SUPPORT_SET_SPEED,
|
||||||
FanEntity,
|
FanEntity,
|
||||||
)
|
)
|
||||||
from homeassistant.const import ATTR_ENTITY_ID
|
from homeassistant.helpers import config_validation as cv, entity_platform
|
||||||
import homeassistant.helpers.config_validation as cv
|
|
||||||
|
|
||||||
from . import DYSON_DEVICES, DysonEntity
|
from . import DYSON_DEVICES, DysonEntity
|
||||||
|
|
||||||
@ -44,51 +44,69 @@ SERVICE_SET_FLOW_DIRECTION_FRONT = "set_flow_direction_front"
|
|||||||
SERVICE_SET_TIMER = "set_timer"
|
SERVICE_SET_TIMER = "set_timer"
|
||||||
SERVICE_SET_DYSON_SPEED = "set_speed"
|
SERVICE_SET_DYSON_SPEED = "set_speed"
|
||||||
|
|
||||||
DYSON_SET_NIGHT_MODE_SCHEMA = vol.Schema(
|
SET_NIGHT_MODE_SCHEMA = {
|
||||||
{
|
vol.Required(ATTR_NIGHT_MODE): cv.boolean,
|
||||||
vol.Required(ATTR_ENTITY_ID): cv.entity_id,
|
}
|
||||||
vol.Required(ATTR_NIGHT_MODE): cv.boolean,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
SET_AUTO_MODE_SCHEMA = vol.Schema(
|
SET_AUTO_MODE_SCHEMA = {
|
||||||
{
|
vol.Required(ATTR_AUTO_MODE): cv.boolean,
|
||||||
vol.Required(ATTR_ENTITY_ID): cv.entity_id,
|
}
|
||||||
vol.Required(ATTR_AUTO_MODE): cv.boolean,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
SET_ANGLE_SCHEMA = vol.Schema(
|
SET_ANGLE_SCHEMA = {
|
||||||
{
|
vol.Required(ATTR_ANGLE_LOW): cv.positive_int,
|
||||||
vol.Required(ATTR_ENTITY_ID): cv.entity_id,
|
vol.Required(ATTR_ANGLE_HIGH): cv.positive_int,
|
||||||
vol.Required(ATTR_ANGLE_LOW): cv.positive_int,
|
}
|
||||||
vol.Required(ATTR_ANGLE_HIGH): cv.positive_int,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
SET_FLOW_DIRECTION_FRONT_SCHEMA = vol.Schema(
|
SET_FLOW_DIRECTION_FRONT_SCHEMA = {
|
||||||
{
|
vol.Required(ATTR_FLOW_DIRECTION_FRONT): cv.boolean,
|
||||||
vol.Required(ATTR_ENTITY_ID): cv.entity_id,
|
}
|
||||||
vol.Required(ATTR_FLOW_DIRECTION_FRONT): cv.boolean,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
SET_TIMER_SCHEMA = vol.Schema(
|
SET_TIMER_SCHEMA = {
|
||||||
{
|
vol.Required(ATTR_TIMER): cv.positive_int,
|
||||||
vol.Required(ATTR_ENTITY_ID): cv.entity_id,
|
}
|
||||||
vol.Required(ATTR_TIMER): cv.positive_int,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
SET_DYSON_SPEED_SCHEMA = vol.Schema(
|
SET_DYSON_SPEED_SCHEMA = {
|
||||||
{
|
vol.Required(ATTR_DYSON_SPEED): cv.positive_int,
|
||||||
vol.Required(ATTR_ENTITY_ID): cv.entity_id,
|
}
|
||||||
vol.Required(ATTR_DYSON_SPEED): cv.positive_int,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
SPEED_LIST_HA = [SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH]
|
||||||
|
|
||||||
|
SPEED_LIST_DYSON = [
|
||||||
|
int(FanSpeed.FAN_SPEED_1.value),
|
||||||
|
int(FanSpeed.FAN_SPEED_2.value),
|
||||||
|
int(FanSpeed.FAN_SPEED_3.value),
|
||||||
|
int(FanSpeed.FAN_SPEED_4.value),
|
||||||
|
int(FanSpeed.FAN_SPEED_5.value),
|
||||||
|
int(FanSpeed.FAN_SPEED_6.value),
|
||||||
|
int(FanSpeed.FAN_SPEED_7.value),
|
||||||
|
int(FanSpeed.FAN_SPEED_8.value),
|
||||||
|
int(FanSpeed.FAN_SPEED_9.value),
|
||||||
|
int(FanSpeed.FAN_SPEED_10.value),
|
||||||
|
]
|
||||||
|
|
||||||
|
SPEED_DYSON_TO_HA = {
|
||||||
|
FanSpeed.FAN_SPEED_1.value: SPEED_LOW,
|
||||||
|
FanSpeed.FAN_SPEED_2.value: SPEED_LOW,
|
||||||
|
FanSpeed.FAN_SPEED_3.value: SPEED_LOW,
|
||||||
|
FanSpeed.FAN_SPEED_4.value: SPEED_LOW,
|
||||||
|
FanSpeed.FAN_SPEED_AUTO.value: SPEED_MEDIUM,
|
||||||
|
FanSpeed.FAN_SPEED_5.value: SPEED_MEDIUM,
|
||||||
|
FanSpeed.FAN_SPEED_6.value: SPEED_MEDIUM,
|
||||||
|
FanSpeed.FAN_SPEED_7.value: SPEED_MEDIUM,
|
||||||
|
FanSpeed.FAN_SPEED_8.value: SPEED_HIGH,
|
||||||
|
FanSpeed.FAN_SPEED_9.value: SPEED_HIGH,
|
||||||
|
FanSpeed.FAN_SPEED_10.value: SPEED_HIGH,
|
||||||
|
}
|
||||||
|
|
||||||
|
SPEED_HA_TO_DYSON = {
|
||||||
|
SPEED_LOW: FanSpeed.FAN_SPEED_4,
|
||||||
|
SPEED_MEDIUM: FanSpeed.FAN_SPEED_7,
|
||||||
|
SPEED_HIGH: FanSpeed.FAN_SPEED_10,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
|
||||||
"""Set up the Dyson fan components."""
|
"""Set up the Dyson fan components."""
|
||||||
|
|
||||||
if discovery_info is None:
|
if discovery_info is None:
|
||||||
@ -111,82 +129,102 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||||||
dyson_entity = DysonPureCoolLinkEntity(device)
|
dyson_entity = DysonPureCoolLinkEntity(device)
|
||||||
hass.data[DYSON_FAN_DEVICES].append(dyson_entity)
|
hass.data[DYSON_FAN_DEVICES].append(dyson_entity)
|
||||||
|
|
||||||
add_entities(hass.data[DYSON_FAN_DEVICES])
|
async_add_entities(hass.data[DYSON_FAN_DEVICES])
|
||||||
|
|
||||||
def service_handle(service):
|
# Register custom services
|
||||||
"""Handle the Dyson services."""
|
platform = entity_platform.current_platform.get()
|
||||||
entity_id = service.data[ATTR_ENTITY_ID]
|
platform.async_register_entity_service(
|
||||||
fan_device = next(
|
SERVICE_SET_NIGHT_MODE, SET_NIGHT_MODE_SCHEMA, "set_night_mode"
|
||||||
(fan for fan in hass.data[DYSON_FAN_DEVICES] if fan.entity_id == entity_id),
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
if fan_device is None:
|
|
||||||
_LOGGER.warning("Unable to find Dyson fan device %s", str(entity_id))
|
|
||||||
return
|
|
||||||
|
|
||||||
if service.service == SERVICE_SET_NIGHT_MODE:
|
|
||||||
fan_device.set_night_mode(service.data[ATTR_NIGHT_MODE])
|
|
||||||
|
|
||||||
if service.service == SERVICE_SET_AUTO_MODE:
|
|
||||||
fan_device.set_auto_mode(service.data[ATTR_AUTO_MODE])
|
|
||||||
|
|
||||||
if service.service == SERVICE_SET_ANGLE:
|
|
||||||
fan_device.set_angle(
|
|
||||||
service.data[ATTR_ANGLE_LOW], service.data[ATTR_ANGLE_HIGH]
|
|
||||||
)
|
|
||||||
|
|
||||||
if service.service == SERVICE_SET_FLOW_DIRECTION_FRONT:
|
|
||||||
fan_device.set_flow_direction_front(service.data[ATTR_FLOW_DIRECTION_FRONT])
|
|
||||||
|
|
||||||
if service.service == SERVICE_SET_TIMER:
|
|
||||||
fan_device.set_timer(service.data[ATTR_TIMER])
|
|
||||||
|
|
||||||
if service.service == SERVICE_SET_DYSON_SPEED:
|
|
||||||
fan_device.set_dyson_speed(service.data[ATTR_DYSON_SPEED])
|
|
||||||
|
|
||||||
# Register dyson service(s)
|
|
||||||
hass.services.register(
|
|
||||||
DYSON_DOMAIN,
|
|
||||||
SERVICE_SET_NIGHT_MODE,
|
|
||||||
service_handle,
|
|
||||||
schema=DYSON_SET_NIGHT_MODE_SCHEMA,
|
|
||||||
)
|
)
|
||||||
|
platform.async_register_entity_service(
|
||||||
hass.services.register(
|
SERVICE_SET_AUTO_MODE, SET_AUTO_MODE_SCHEMA, "set_auto_mode"
|
||||||
DYSON_DOMAIN, SERVICE_SET_AUTO_MODE, service_handle, schema=SET_AUTO_MODE_SCHEMA
|
)
|
||||||
|
platform.async_register_entity_service(
|
||||||
|
SERVICE_SET_DYSON_SPEED, SET_DYSON_SPEED_SCHEMA, "service_set_dyson_speed"
|
||||||
)
|
)
|
||||||
if has_purecool_devices:
|
if has_purecool_devices:
|
||||||
hass.services.register(
|
platform.async_register_entity_service(
|
||||||
DYSON_DOMAIN, SERVICE_SET_ANGLE, service_handle, schema=SET_ANGLE_SCHEMA
|
SERVICE_SET_ANGLE, SET_ANGLE_SCHEMA, "set_angle"
|
||||||
)
|
)
|
||||||
|
platform.async_register_entity_service(
|
||||||
hass.services.register(
|
|
||||||
DYSON_DOMAIN,
|
|
||||||
SERVICE_SET_FLOW_DIRECTION_FRONT,
|
SERVICE_SET_FLOW_DIRECTION_FRONT,
|
||||||
service_handle,
|
SET_FLOW_DIRECTION_FRONT_SCHEMA,
|
||||||
schema=SET_FLOW_DIRECTION_FRONT_SCHEMA,
|
"set_flow_direction_front",
|
||||||
)
|
)
|
||||||
|
platform.async_register_entity_service(
|
||||||
hass.services.register(
|
SERVICE_SET_TIMER, SET_TIMER_SCHEMA, "set_timer"
|
||||||
DYSON_DOMAIN, SERVICE_SET_TIMER, service_handle, schema=SET_TIMER_SCHEMA
|
|
||||||
)
|
|
||||||
|
|
||||||
hass.services.register(
|
|
||||||
DYSON_DOMAIN,
|
|
||||||
SERVICE_SET_DYSON_SPEED,
|
|
||||||
service_handle,
|
|
||||||
schema=SET_DYSON_SPEED_SCHEMA,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class DysonFanEntity(DysonEntity, FanEntity):
|
class DysonFanEntity(DysonEntity, FanEntity):
|
||||||
"""Representation of a Dyson fan."""
|
"""Representation of a Dyson fan."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def speed(self):
|
||||||
|
"""Return the current speed."""
|
||||||
|
return SPEED_DYSON_TO_HA[self._device.state.speed]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def speed_list(self) -> list:
|
||||||
|
"""Get the list of available speeds."""
|
||||||
|
return SPEED_LIST_HA
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dyson_speed(self):
|
||||||
|
"""Return the current speed."""
|
||||||
|
if self._device.state.speed == FanSpeed.FAN_SPEED_AUTO.value:
|
||||||
|
return self._device.state.speed
|
||||||
|
return int(self._device.state.speed)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dyson_speed_list(self) -> list:
|
||||||
|
"""Get the list of available dyson speeds."""
|
||||||
|
return SPEED_LIST_DYSON
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def night_mode(self):
|
def night_mode(self):
|
||||||
"""Return Night mode."""
|
"""Return Night mode."""
|
||||||
return self._device.state.night_mode == "ON"
|
return self._device.state.night_mode == "ON"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def auto_mode(self):
|
||||||
|
"""Return auto mode."""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@property
|
||||||
|
def supported_features(self) -> int:
|
||||||
|
"""Flag supported features."""
|
||||||
|
return SUPPORT_OSCILLATE | SUPPORT_SET_SPEED
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_state_attributes(self) -> dict:
|
||||||
|
"""Return optional state attributes."""
|
||||||
|
return {
|
||||||
|
ATTR_NIGHT_MODE: self.night_mode,
|
||||||
|
ATTR_AUTO_MODE: self.auto_mode,
|
||||||
|
ATTR_DYSON_SPEED: self.dyson_speed,
|
||||||
|
ATTR_DYSON_SPEED_LIST: self.dyson_speed_list,
|
||||||
|
}
|
||||||
|
|
||||||
|
def set_speed(self, speed: str) -> None:
|
||||||
|
"""Set the speed of the fan."""
|
||||||
|
if speed not in SPEED_LIST_HA:
|
||||||
|
raise ValueError(f'"{speed}" is not a valid speed')
|
||||||
|
_LOGGER.debug("Set fan speed to: %s", speed)
|
||||||
|
self.set_dyson_speed(SPEED_HA_TO_DYSON[speed])
|
||||||
|
|
||||||
|
def set_dyson_speed(self, speed: FanSpeed) -> None:
|
||||||
|
"""Set the exact speed of the fan."""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def service_set_dyson_speed(self, dyson_speed: str) -> None:
|
||||||
|
"""Handle the service to set dyson speed."""
|
||||||
|
if dyson_speed not in SPEED_LIST_DYSON:
|
||||||
|
raise ValueError(f'"{dyson_speed}" is not a valid Dyson speed')
|
||||||
|
_LOGGER.debug("Set exact speed to %s", dyson_speed)
|
||||||
|
speed = FanSpeed(f"{int(dyson_speed):04d}")
|
||||||
|
self.set_dyson_speed(speed)
|
||||||
|
|
||||||
|
|
||||||
class DysonPureCoolLinkEntity(DysonFanEntity):
|
class DysonPureCoolLinkEntity(DysonFanEntity):
|
||||||
"""Representation of a Dyson fan."""
|
"""Representation of a Dyson fan."""
|
||||||
@ -195,27 +233,11 @@ class DysonPureCoolLinkEntity(DysonFanEntity):
|
|||||||
"""Initialize the fan."""
|
"""Initialize the fan."""
|
||||||
super().__init__(device, DysonPureCoolState)
|
super().__init__(device, DysonPureCoolState)
|
||||||
|
|
||||||
def set_speed(self, speed: str) -> None:
|
def turn_on(self, speed: Optional[str] = None, **kwargs) -> None:
|
||||||
"""Set the speed of the fan. Never called ??."""
|
|
||||||
_LOGGER.debug("Set fan speed to: %s", speed)
|
|
||||||
|
|
||||||
if speed == FanSpeed.FAN_SPEED_AUTO.value:
|
|
||||||
self._device.set_configuration(fan_mode=FanMode.AUTO)
|
|
||||||
else:
|
|
||||||
fan_speed = FanSpeed(f"{int(speed):04d}")
|
|
||||||
self._device.set_configuration(fan_mode=FanMode.FAN, fan_speed=fan_speed)
|
|
||||||
|
|
||||||
def turn_on(self, speed: str = None, **kwargs) -> None:
|
|
||||||
"""Turn on the fan."""
|
"""Turn on the fan."""
|
||||||
_LOGGER.debug("Turn on fan %s with speed %s", self.name, speed)
|
_LOGGER.debug("Turn on fan %s with speed %s", self.name, speed)
|
||||||
if speed:
|
if speed is not None:
|
||||||
if speed == FanSpeed.FAN_SPEED_AUTO.value:
|
self.set_speed(speed)
|
||||||
self._device.set_configuration(fan_mode=FanMode.AUTO)
|
|
||||||
else:
|
|
||||||
fan_speed = FanSpeed(f"{int(speed):04d}")
|
|
||||||
self._device.set_configuration(
|
|
||||||
fan_mode=FanMode.FAN, fan_speed=fan_speed
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
# Speed not set, just turn on
|
# Speed not set, just turn on
|
||||||
self._device.set_configuration(fan_mode=FanMode.FAN)
|
self._device.set_configuration(fan_mode=FanMode.FAN)
|
||||||
@ -225,6 +247,10 @@ class DysonPureCoolLinkEntity(DysonFanEntity):
|
|||||||
_LOGGER.debug("Turn off fan %s", self.name)
|
_LOGGER.debug("Turn off fan %s", self.name)
|
||||||
self._device.set_configuration(fan_mode=FanMode.OFF)
|
self._device.set_configuration(fan_mode=FanMode.OFF)
|
||||||
|
|
||||||
|
def set_dyson_speed(self, speed: FanSpeed) -> None:
|
||||||
|
"""Set the exact speed of the fan."""
|
||||||
|
self._device.set_configuration(fan_mode=FanMode.FAN, fan_speed=speed)
|
||||||
|
|
||||||
def oscillate(self, oscillating: bool) -> None:
|
def oscillate(self, oscillating: bool) -> None:
|
||||||
"""Turn on/off oscillating."""
|
"""Turn on/off oscillating."""
|
||||||
_LOGGER.debug("Turn oscillation %s for device %s", oscillating, self.name)
|
_LOGGER.debug("Turn oscillation %s for device %s", oscillating, self.name)
|
||||||
@ -244,13 +270,6 @@ class DysonPureCoolLinkEntity(DysonFanEntity):
|
|||||||
"""Return true if the entity is on."""
|
"""Return true if the entity is on."""
|
||||||
return self._device.state.fan_mode in ["FAN", "AUTO"]
|
return self._device.state.fan_mode in ["FAN", "AUTO"]
|
||||||
|
|
||||||
@property
|
|
||||||
def speed(self) -> str:
|
|
||||||
"""Return the current speed."""
|
|
||||||
if self._device.state.speed == FanSpeed.FAN_SPEED_AUTO.value:
|
|
||||||
return self._device.state.speed
|
|
||||||
return int(self._device.state.speed)
|
|
||||||
|
|
||||||
def set_night_mode(self, night_mode: bool) -> None:
|
def set_night_mode(self, night_mode: bool) -> None:
|
||||||
"""Turn fan in night mode."""
|
"""Turn fan in night mode."""
|
||||||
_LOGGER.debug("Set %s night mode %s", self.name, night_mode)
|
_LOGGER.debug("Set %s night mode %s", self.name, night_mode)
|
||||||
@ -272,35 +291,6 @@ class DysonPureCoolLinkEntity(DysonFanEntity):
|
|||||||
else:
|
else:
|
||||||
self._device.set_configuration(fan_mode=FanMode.FAN)
|
self._device.set_configuration(fan_mode=FanMode.FAN)
|
||||||
|
|
||||||
@property
|
|
||||||
def speed_list(self) -> list:
|
|
||||||
"""Get the list of available speeds."""
|
|
||||||
supported_speeds = [
|
|
||||||
FanSpeed.FAN_SPEED_AUTO.value,
|
|
||||||
int(FanSpeed.FAN_SPEED_1.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_2.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_3.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_4.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_5.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_6.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_7.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_8.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_9.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_10.value),
|
|
||||||
]
|
|
||||||
|
|
||||||
return supported_speeds
|
|
||||||
|
|
||||||
@property
|
|
||||||
def supported_features(self) -> int:
|
|
||||||
"""Flag supported features."""
|
|
||||||
return SUPPORT_OSCILLATE | SUPPORT_SET_SPEED
|
|
||||||
|
|
||||||
@property
|
|
||||||
def device_state_attributes(self) -> dict:
|
|
||||||
"""Return optional state attributes."""
|
|
||||||
return {ATTR_NIGHT_MODE: self.night_mode, ATTR_AUTO_MODE: self.auto_mode}
|
|
||||||
|
|
||||||
|
|
||||||
class DysonPureCoolEntity(DysonFanEntity):
|
class DysonPureCoolEntity(DysonFanEntity):
|
||||||
"""Representation of a Dyson Purecool (TP04/DP04) fan."""
|
"""Representation of a Dyson Purecool (TP04/DP04) fan."""
|
||||||
@ -309,7 +299,7 @@ class DysonPureCoolEntity(DysonFanEntity):
|
|||||||
"""Initialize the fan."""
|
"""Initialize the fan."""
|
||||||
super().__init__(device, DysonPureCoolV2State)
|
super().__init__(device, DysonPureCoolV2State)
|
||||||
|
|
||||||
def turn_on(self, speed: str = None, **kwargs) -> None:
|
def turn_on(self, speed: Optional[str] = None, **kwargs) -> None:
|
||||||
"""Turn on the fan."""
|
"""Turn on the fan."""
|
||||||
_LOGGER.debug("Turn on fan %s", self.name)
|
_LOGGER.debug("Turn on fan %s", self.name)
|
||||||
|
|
||||||
@ -318,26 +308,14 @@ class DysonPureCoolEntity(DysonFanEntity):
|
|||||||
else:
|
else:
|
||||||
self._device.turn_on()
|
self._device.turn_on()
|
||||||
|
|
||||||
def set_speed(self, speed: str) -> None:
|
|
||||||
"""Set the speed of the fan."""
|
|
||||||
if speed == SPEED_LOW:
|
|
||||||
self._device.set_fan_speed(FanSpeed.FAN_SPEED_4)
|
|
||||||
elif speed == SPEED_MEDIUM:
|
|
||||||
self._device.set_fan_speed(FanSpeed.FAN_SPEED_7)
|
|
||||||
elif speed == SPEED_HIGH:
|
|
||||||
self._device.set_fan_speed(FanSpeed.FAN_SPEED_10)
|
|
||||||
|
|
||||||
def turn_off(self, **kwargs):
|
def turn_off(self, **kwargs):
|
||||||
"""Turn off the fan."""
|
"""Turn off the fan."""
|
||||||
_LOGGER.debug("Turn off fan %s", self.name)
|
_LOGGER.debug("Turn off fan %s", self.name)
|
||||||
self._device.turn_off()
|
self._device.turn_off()
|
||||||
|
|
||||||
def set_dyson_speed(self, speed: str = None) -> None:
|
def set_dyson_speed(self, speed: FanSpeed) -> None:
|
||||||
"""Set the exact speed of the purecool fan."""
|
"""Set the exact speed of the purecool fan."""
|
||||||
_LOGGER.debug("Set exact speed for fan %s", self.name)
|
self._device.set_fan_speed(speed)
|
||||||
|
|
||||||
fan_speed = FanSpeed(f"{int(speed):04d}")
|
|
||||||
self._device.set_fan_speed(fan_speed)
|
|
||||||
|
|
||||||
def oscillate(self, oscillating: bool) -> None:
|
def oscillate(self, oscillating: bool) -> None:
|
||||||
"""Turn on/off oscillating."""
|
"""Turn on/off oscillating."""
|
||||||
@ -407,33 +385,6 @@ class DysonPureCoolEntity(DysonFanEntity):
|
|||||||
"""Return true if the entity is on."""
|
"""Return true if the entity is on."""
|
||||||
return self._device.state.fan_power == "ON"
|
return self._device.state.fan_power == "ON"
|
||||||
|
|
||||||
@property
|
|
||||||
def speed(self):
|
|
||||||
"""Return the current speed."""
|
|
||||||
speed_map = {
|
|
||||||
FanSpeed.FAN_SPEED_1.value: SPEED_LOW,
|
|
||||||
FanSpeed.FAN_SPEED_2.value: SPEED_LOW,
|
|
||||||
FanSpeed.FAN_SPEED_3.value: SPEED_LOW,
|
|
||||||
FanSpeed.FAN_SPEED_4.value: SPEED_LOW,
|
|
||||||
FanSpeed.FAN_SPEED_AUTO.value: SPEED_MEDIUM,
|
|
||||||
FanSpeed.FAN_SPEED_5.value: SPEED_MEDIUM,
|
|
||||||
FanSpeed.FAN_SPEED_6.value: SPEED_MEDIUM,
|
|
||||||
FanSpeed.FAN_SPEED_7.value: SPEED_MEDIUM,
|
|
||||||
FanSpeed.FAN_SPEED_8.value: SPEED_HIGH,
|
|
||||||
FanSpeed.FAN_SPEED_9.value: SPEED_HIGH,
|
|
||||||
FanSpeed.FAN_SPEED_10.value: SPEED_HIGH,
|
|
||||||
}
|
|
||||||
|
|
||||||
return speed_map[self._device.state.speed]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def dyson_speed(self):
|
|
||||||
"""Return the current speed."""
|
|
||||||
if self._device.state:
|
|
||||||
if self._device.state.speed == FanSpeed.FAN_SPEED_AUTO.value:
|
|
||||||
return self._device.state.speed
|
|
||||||
return int(self._device.state.speed)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def auto_mode(self):
|
def auto_mode(self):
|
||||||
"""Return Auto mode."""
|
"""Return Auto mode."""
|
||||||
@ -471,44 +422,15 @@ class DysonPureCoolEntity(DysonFanEntity):
|
|||||||
return self._device.state.carbon_filter_state
|
return self._device.state.carbon_filter_state
|
||||||
return int(self._device.state.carbon_filter_state)
|
return int(self._device.state.carbon_filter_state)
|
||||||
|
|
||||||
@property
|
|
||||||
def speed_list(self) -> list:
|
|
||||||
"""Get the list of available speeds."""
|
|
||||||
return [SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def dyson_speed_list(self) -> list:
|
|
||||||
"""Get the list of available dyson speeds."""
|
|
||||||
return [
|
|
||||||
int(FanSpeed.FAN_SPEED_1.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_2.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_3.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_4.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_5.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_6.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_7.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_8.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_9.value),
|
|
||||||
int(FanSpeed.FAN_SPEED_10.value),
|
|
||||||
]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def supported_features(self) -> int:
|
|
||||||
"""Flag supported features."""
|
|
||||||
return SUPPORT_OSCILLATE | SUPPORT_SET_SPEED
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_state_attributes(self) -> dict:
|
def device_state_attributes(self) -> dict:
|
||||||
"""Return optional state attributes."""
|
"""Return optional state attributes."""
|
||||||
return {
|
return {
|
||||||
ATTR_NIGHT_MODE: self.night_mode,
|
**super().device_state_attributes,
|
||||||
ATTR_AUTO_MODE: self.auto_mode,
|
|
||||||
ATTR_ANGLE_LOW: self.angle_low,
|
ATTR_ANGLE_LOW: self.angle_low,
|
||||||
ATTR_ANGLE_HIGH: self.angle_high,
|
ATTR_ANGLE_HIGH: self.angle_high,
|
||||||
ATTR_FLOW_DIRECTION_FRONT: self.flow_direction_front,
|
ATTR_FLOW_DIRECTION_FRONT: self.flow_direction_front,
|
||||||
ATTR_TIMER: self.timer,
|
ATTR_TIMER: self.timer,
|
||||||
ATTR_HEPA_FILTER: self.hepa_filter,
|
ATTR_HEPA_FILTER: self.hepa_filter,
|
||||||
ATTR_CARBON_FILTER: self.carbon_filter,
|
ATTR_CARBON_FILTER: self.carbon_filter,
|
||||||
ATTR_DYSON_SPEED: self.dyson_speed,
|
|
||||||
ATTR_DYSON_SPEED_LIST: self.dyson_speed_list,
|
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ from tests.common import async_setup_component
|
|||||||
BASE_PATH = "homeassistant.components.dyson"
|
BASE_PATH = "homeassistant.components.dyson"
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture()
|
||||||
async def device(hass: HomeAssistant, request) -> DysonDevice:
|
async def device(hass: HomeAssistant, request) -> DysonDevice:
|
||||||
"""Fixture to provide Dyson 360 Eye device."""
|
"""Fixture to provide Dyson 360 Eye device."""
|
||||||
platform = request.module.PLATFORM_DOMAIN
|
platform = request.module.PLATFORM_DOMAIN
|
||||||
|
@ -93,10 +93,10 @@ async def test_state_purecoollink(
|
|||||||
attributes = state.attributes
|
attributes = state.attributes
|
||||||
assert attributes[ATTR_NIGHT_MODE] is True
|
assert attributes[ATTR_NIGHT_MODE] is True
|
||||||
assert attributes[ATTR_OSCILLATING] is True
|
assert attributes[ATTR_OSCILLATING] is True
|
||||||
assert attributes[ATTR_SPEED] == 1
|
assert attributes[ATTR_SPEED] == SPEED_LOW
|
||||||
assert attributes[ATTR_SPEED_LIST] == [FanSpeed.FAN_SPEED_AUTO.value] + list(
|
assert attributes[ATTR_SPEED_LIST] == [SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH]
|
||||||
range(1, 11)
|
assert attributes[ATTR_DYSON_SPEED] == 1
|
||||||
)
|
assert attributes[ATTR_DYSON_SPEED_LIST] == list(range(1, 11))
|
||||||
assert attributes[ATTR_AUTO_MODE] is False
|
assert attributes[ATTR_AUTO_MODE] is False
|
||||||
assert attributes[ATTR_SUPPORTED_FEATURES] == SUPPORT_OSCILLATE | SUPPORT_SET_SPEED
|
assert attributes[ATTR_SUPPORTED_FEATURES] == SUPPORT_OSCILLATE | SUPPORT_SET_SPEED
|
||||||
|
|
||||||
@ -115,7 +115,8 @@ async def test_state_purecoollink(
|
|||||||
attributes = state.attributes
|
attributes = state.attributes
|
||||||
assert attributes[ATTR_NIGHT_MODE] is False
|
assert attributes[ATTR_NIGHT_MODE] is False
|
||||||
assert attributes[ATTR_OSCILLATING] is False
|
assert attributes[ATTR_OSCILLATING] is False
|
||||||
assert attributes[ATTR_SPEED] == "AUTO"
|
assert attributes[ATTR_SPEED] == SPEED_MEDIUM
|
||||||
|
assert attributes[ATTR_DYSON_SPEED] == "AUTO"
|
||||||
assert attributes[ATTR_AUTO_MODE] is True
|
assert attributes[ATTR_AUTO_MODE] is True
|
||||||
|
|
||||||
|
|
||||||
@ -173,11 +174,10 @@ async def test_state_purecool(hass: HomeAssistant, device: DysonPureCool) -> Non
|
|||||||
"service,service_data,configuration_args",
|
"service,service_data,configuration_args",
|
||||||
[
|
[
|
||||||
(SERVICE_TURN_ON, {}, {"fan_mode": FanMode.FAN}),
|
(SERVICE_TURN_ON, {}, {"fan_mode": FanMode.FAN}),
|
||||||
(SERVICE_TURN_ON, {ATTR_SPEED: "AUTO"}, {"fan_mode": FanMode.AUTO}),
|
|
||||||
(
|
(
|
||||||
SERVICE_TURN_ON,
|
SERVICE_TURN_ON,
|
||||||
{ATTR_SPEED: 5},
|
{ATTR_SPEED: SPEED_LOW},
|
||||||
{"fan_mode": FanMode.FAN, "fan_speed": FanSpeed("0005")},
|
{"fan_mode": FanMode.FAN, "fan_speed": FanSpeed.FAN_SPEED_4},
|
||||||
),
|
),
|
||||||
(SERVICE_TURN_OFF, {}, {"fan_mode": FanMode.OFF}),
|
(SERVICE_TURN_OFF, {}, {"fan_mode": FanMode.OFF}),
|
||||||
(
|
(
|
||||||
@ -190,11 +190,20 @@ async def test_state_purecool(hass: HomeAssistant, device: DysonPureCool) -> Non
|
|||||||
{ATTR_OSCILLATING: False},
|
{ATTR_OSCILLATING: False},
|
||||||
{"oscillation": Oscillation.OSCILLATION_OFF},
|
{"oscillation": Oscillation.OSCILLATION_OFF},
|
||||||
),
|
),
|
||||||
(SERVICE_SET_SPEED, {ATTR_SPEED: "AUTO"}, {"fan_mode": FanMode.AUTO}),
|
|
||||||
(
|
(
|
||||||
SERVICE_SET_SPEED,
|
SERVICE_SET_SPEED,
|
||||||
{ATTR_SPEED: 5},
|
{ATTR_SPEED: SPEED_LOW},
|
||||||
{"fan_mode": FanMode.FAN, "fan_speed": FanSpeed("0005")},
|
{"fan_mode": FanMode.FAN, "fan_speed": FanSpeed.FAN_SPEED_4},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
SERVICE_SET_SPEED,
|
||||||
|
{ATTR_SPEED: SPEED_MEDIUM},
|
||||||
|
{"fan_mode": FanMode.FAN, "fan_speed": FanSpeed.FAN_SPEED_7},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
SERVICE_SET_SPEED,
|
||||||
|
{ATTR_SPEED: SPEED_HIGH},
|
||||||
|
{"fan_mode": FanMode.FAN, "fan_speed": FanSpeed.FAN_SPEED_10},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -289,6 +298,11 @@ async def test_commands_purecool(
|
|||||||
),
|
),
|
||||||
(SERVICE_SET_AUTO_MODE, {"auto_mode": True}, {"fan_mode": FanMode.AUTO}),
|
(SERVICE_SET_AUTO_MODE, {"auto_mode": True}, {"fan_mode": FanMode.AUTO}),
|
||||||
(SERVICE_SET_AUTO_MODE, {"auto_mode": False}, {"fan_mode": FanMode.FAN}),
|
(SERVICE_SET_AUTO_MODE, {"auto_mode": False}, {"fan_mode": FanMode.FAN}),
|
||||||
|
(
|
||||||
|
SERVICE_SET_DYSON_SPEED,
|
||||||
|
{ATTR_DYSON_SPEED: "4"},
|
||||||
|
{"fan_mode": FanMode.FAN, "fan_speed": FanSpeed.FAN_SPEED_4},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.parametrize("device", [DysonPureCoolLink], indirect=True)
|
@pytest.mark.parametrize("device", [DysonPureCoolLink], indirect=True)
|
||||||
@ -368,3 +382,28 @@ async def test_custom_services_purecool(
|
|||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
getattr(device, command).assert_called_once_with(*command_args)
|
getattr(device, command).assert_called_once_with(*command_args)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"domain,service,data",
|
||||||
|
[
|
||||||
|
(PLATFORM_DOMAIN, SERVICE_TURN_ON, {ATTR_SPEED: "AUTO"}),
|
||||||
|
(PLATFORM_DOMAIN, SERVICE_SET_SPEED, {ATTR_SPEED: "AUTO"}),
|
||||||
|
(DOMAIN, SERVICE_SET_DYSON_SPEED, {ATTR_DYSON_SPEED: "11"}),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
@pytest.mark.parametrize("device", [DysonPureCool], indirect=True)
|
||||||
|
async def test_custom_services_invalid_data(
|
||||||
|
hass: HomeAssistant, device: DysonPureCool, domain: str, service: str, data: dict
|
||||||
|
) -> None:
|
||||||
|
"""Test custom services calling with invalid data."""
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
await hass.services.async_call(
|
||||||
|
domain,
|
||||||
|
service,
|
||||||
|
{
|
||||||
|
ATTR_ENTITY_ID: ENTITY_ID,
|
||||||
|
**data,
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user