parent
c6952a0ee3
commit
723dcbafca
|
@ -10,7 +10,6 @@ from homeassistant.components.climate.const import (
|
|||
HVAC_MODE_HEAT,
|
||||
HVAC_MODE_OFF,
|
||||
)
|
||||
from homeassistant.components.fan import SPEED_HIGH, SPEED_LOW, SPEED_OFF
|
||||
from homeassistant.const import Platform
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -21,7 +20,6 @@ CLIMATE_SUPPORTED_FANSTATES = [FAN_OFF, FAN_LOW, FAN_MEDIUM, FAN_HIGH]
|
|||
CLIMATE_SUPPORTED_MODES = [HVAC_MODE_AUTO, HVAC_MODE_HEAT, HVAC_MODE_OFF]
|
||||
CONF_SYNC_TIME = "sync_time"
|
||||
DEFAULT_SYNC_TIME = False
|
||||
FAN_SUPPORTED_SPEEDS = [SPEED_OFF, SPEED_LOW, SPEED_HIGH]
|
||||
PLATFORMS = [Platform.BINARY_SENSOR, Platform.CLIMATE]
|
||||
|
||||
AUX = "Aux"
|
||||
|
|
|
@ -10,7 +10,6 @@ from bond_api import Action, BPUPSubscriptions, DeviceType, Direction
|
|||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.fan import (
|
||||
ATTR_SPEED,
|
||||
DIRECTION_FORWARD,
|
||||
DIRECTION_REVERSE,
|
||||
SUPPORT_DIRECTION,
|
||||
|
@ -57,7 +56,7 @@ async def async_setup_entry(
|
|||
|
||||
platform.async_register_entity_service(
|
||||
SERVICE_SET_FAN_SPEED_TRACKED_STATE,
|
||||
{vol.Required(ATTR_SPEED): vol.All(vol.Number(scale=0), vol.Range(0, 100))},
|
||||
{vol.Required("speed"): vol.All(vol.Number(scale=0), vol.Range(0, 100))},
|
||||
"async_set_speed_belief",
|
||||
)
|
||||
|
||||
|
@ -107,7 +106,9 @@ class BondFan(BondEntity, FanEntity):
|
|||
"""Return the current speed percentage for the fan."""
|
||||
if not self._speed or not self._power:
|
||||
return 0
|
||||
return ranged_value_to_percentage(self._speed_range, self._speed)
|
||||
return min(
|
||||
100, max(0, ranged_value_to_percentage(self._speed_range, self._speed))
|
||||
)
|
||||
|
||||
@property
|
||||
def speed_count(self) -> int:
|
||||
|
@ -183,7 +184,6 @@ class BondFan(BondEntity, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -120,7 +120,6 @@ class ComfoConnectFan(FanEntity):
|
|||
|
||||
def turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs,
|
||||
|
|
|
@ -13,15 +13,7 @@ from pydeconz.light import (
|
|||
Fan,
|
||||
)
|
||||
|
||||
from homeassistant.components.fan import (
|
||||
DOMAIN,
|
||||
SPEED_HIGH,
|
||||
SPEED_LOW,
|
||||
SPEED_MEDIUM,
|
||||
SPEED_OFF,
|
||||
SUPPORT_SET_SPEED,
|
||||
FanEntity,
|
||||
)
|
||||
from homeassistant.components.fan import DOMAIN, SUPPORT_SET_SPEED, FanEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
@ -41,19 +33,6 @@ ORDERED_NAMED_FAN_SPEEDS = [
|
|||
FAN_SPEED_100_PERCENT,
|
||||
]
|
||||
|
||||
LEGACY_SPEED_TO_DECONZ = {
|
||||
SPEED_OFF: FAN_SPEED_OFF,
|
||||
SPEED_LOW: FAN_SPEED_25_PERCENT,
|
||||
SPEED_MEDIUM: FAN_SPEED_50_PERCENT,
|
||||
SPEED_HIGH: FAN_SPEED_100_PERCENT,
|
||||
}
|
||||
LEGACY_DECONZ_TO_SPEED = {
|
||||
FAN_SPEED_OFF: SPEED_OFF,
|
||||
FAN_SPEED_25_PERCENT: SPEED_LOW,
|
||||
FAN_SPEED_50_PERCENT: SPEED_MEDIUM,
|
||||
FAN_SPEED_100_PERCENT: SPEED_HIGH,
|
||||
}
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
|
@ -130,41 +109,6 @@ class DeconzFan(DeconzDevice, FanEntity):
|
|||
"""Return the number of speeds the fan supports."""
|
||||
return len(ORDERED_NAMED_FAN_SPEEDS)
|
||||
|
||||
@property
|
||||
def speed_list(self) -> list:
|
||||
"""Get the list of available speeds.
|
||||
|
||||
Legacy fan support.
|
||||
"""
|
||||
return list(LEGACY_SPEED_TO_DECONZ)
|
||||
|
||||
def speed_to_percentage(self, speed: str) -> int:
|
||||
"""Convert speed to percentage.
|
||||
|
||||
Legacy fan support.
|
||||
"""
|
||||
if speed == SPEED_OFF:
|
||||
return 0
|
||||
|
||||
if speed not in LEGACY_SPEED_TO_DECONZ:
|
||||
speed = SPEED_MEDIUM
|
||||
|
||||
return ordered_list_item_to_percentage(
|
||||
ORDERED_NAMED_FAN_SPEEDS, LEGACY_SPEED_TO_DECONZ[speed]
|
||||
)
|
||||
|
||||
def percentage_to_speed(self, percentage: int) -> str:
|
||||
"""Convert percentage to speed.
|
||||
|
||||
Legacy fan support.
|
||||
"""
|
||||
if percentage == 0:
|
||||
return SPEED_OFF
|
||||
return LEGACY_DECONZ_TO_SPEED.get(
|
||||
percentage_to_ordered_list_item(ORDERED_NAMED_FAN_SPEEDS, percentage),
|
||||
SPEED_MEDIUM,
|
||||
)
|
||||
|
||||
@callback
|
||||
def async_update_callback(self) -> None:
|
||||
"""Store latest configured speed from the device."""
|
||||
|
@ -174,36 +118,23 @@ class DeconzFan(DeconzDevice, FanEntity):
|
|||
|
||||
async def async_set_percentage(self, percentage: int) -> None:
|
||||
"""Set the speed percentage of the fan."""
|
||||
if percentage == 0:
|
||||
return await self.async_turn_off()
|
||||
await self._device.set_speed(
|
||||
percentage_to_ordered_list_item(ORDERED_NAMED_FAN_SPEEDS, percentage)
|
||||
)
|
||||
|
||||
async def async_set_speed(self, speed: str) -> None:
|
||||
"""Set the speed of the fan.
|
||||
|
||||
Legacy fan support.
|
||||
"""
|
||||
if speed not in LEGACY_SPEED_TO_DECONZ:
|
||||
raise ValueError(f"Unsupported speed {speed}")
|
||||
|
||||
await self._device.set_speed(LEGACY_SPEED_TO_DECONZ[speed])
|
||||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
"""Turn on fan."""
|
||||
new_speed = self._default_on_speed
|
||||
|
||||
if percentage is not None:
|
||||
new_speed = percentage_to_ordered_list_item(
|
||||
ORDERED_NAMED_FAN_SPEEDS, percentage
|
||||
)
|
||||
|
||||
await self._device.set_speed(new_speed)
|
||||
await self.async_set_percentage(percentage)
|
||||
return
|
||||
await self._device.set_speed(self._default_on_speed)
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn off fan."""
|
||||
|
|
|
@ -196,7 +196,6 @@ class DemoPercentageFan(BaseDemoFan, FanEntity):
|
|||
|
||||
def turn_on(
|
||||
self,
|
||||
speed: str = None,
|
||||
percentage: int = None,
|
||||
preset_mode: str = None,
|
||||
**kwargs,
|
||||
|
@ -267,7 +266,6 @@ class AsyncDemoPercentageFan(BaseDemoFan, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str = None,
|
||||
percentage: int = None,
|
||||
preset_mode: str = None,
|
||||
**kwargs,
|
||||
|
|
|
@ -26,14 +26,7 @@ from homeassistant.components.cover import (
|
|||
ATTR_POSITION,
|
||||
SUPPORT_SET_POSITION,
|
||||
)
|
||||
from homeassistant.components.fan import (
|
||||
ATTR_SPEED,
|
||||
SPEED_HIGH,
|
||||
SPEED_LOW,
|
||||
SPEED_MEDIUM,
|
||||
SPEED_OFF,
|
||||
SUPPORT_SET_SPEED,
|
||||
)
|
||||
from homeassistant.components.fan import ATTR_PERCENTAGE, SUPPORT_SET_SPEED
|
||||
from homeassistant.components.http import HomeAssistantView
|
||||
from homeassistant.components.humidifier.const import (
|
||||
ATTR_HUMIDITY,
|
||||
|
@ -540,14 +533,7 @@ class HueOneLightChangeView(HomeAssistantView):
|
|||
):
|
||||
domain = entity.domain
|
||||
# Convert 0-100 to a fan speed
|
||||
if (brightness := parsed[STATE_BRIGHTNESS]) == 0:
|
||||
data[ATTR_SPEED] = SPEED_OFF
|
||||
elif 0 < brightness <= 33.3:
|
||||
data[ATTR_SPEED] = SPEED_LOW
|
||||
elif 33.3 < brightness <= 66.6:
|
||||
data[ATTR_SPEED] = SPEED_MEDIUM
|
||||
elif 66.6 < brightness <= 100:
|
||||
data[ATTR_SPEED] = SPEED_HIGH
|
||||
data[ATTR_PERCENTAGE] = parsed[STATE_BRIGHTNESS]
|
||||
|
||||
# Map the off command to on
|
||||
if entity.domain in config.off_maps_to_on_domains:
|
||||
|
@ -679,15 +665,9 @@ def get_entity_state(config, entity):
|
|||
# Convert 0.0-1.0 to 0-254
|
||||
data[STATE_BRIGHTNESS] = round(min(1.0, level) * HUE_API_STATE_BRI_MAX)
|
||||
elif entity.domain == fan.DOMAIN:
|
||||
speed = entity.attributes.get(ATTR_SPEED, 0)
|
||||
# Convert 0.0-1.0 to 0-254
|
||||
data[STATE_BRIGHTNESS] = 0
|
||||
if speed == SPEED_LOW:
|
||||
data[STATE_BRIGHTNESS] = 85
|
||||
elif speed == SPEED_MEDIUM:
|
||||
data[STATE_BRIGHTNESS] = 170
|
||||
elif speed == SPEED_HIGH:
|
||||
data[STATE_BRIGHTNESS] = HUE_API_STATE_BRI_MAX
|
||||
percentage = entity.attributes.get(ATTR_PERCENTAGE) or 0
|
||||
# Convert 0-100 to 0-254
|
||||
data[STATE_BRIGHTNESS] = round(percentage * HUE_API_STATE_BRI_MAX / 100)
|
||||
elif entity.domain == cover.DOMAIN:
|
||||
level = entity.attributes.get(ATTR_CURRENT_POSITION, 0)
|
||||
data[STATE_BRIGHTNESS] = round(level / 100 * HUE_API_STATE_BRI_MAX)
|
||||
|
|
|
@ -92,7 +92,6 @@ class EsphomeFan(EsphomeEntity[FanInfo, FanState], FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -28,8 +28,6 @@ from homeassistant.helpers.entity_component import EntityComponent
|
|||
from homeassistant.helpers.typing import ConfigType
|
||||
from homeassistant.loader import bind_hass
|
||||
from homeassistant.util.percentage import (
|
||||
ordered_list_item_to_percentage,
|
||||
percentage_to_ordered_list_item,
|
||||
percentage_to_ranged_value,
|
||||
ranged_value_to_percentage,
|
||||
)
|
||||
|
@ -47,7 +45,6 @@ SUPPORT_OSCILLATE = 2
|
|||
SUPPORT_DIRECTION = 4
|
||||
SUPPORT_PRESET_MODE = 8
|
||||
|
||||
SERVICE_SET_SPEED = "set_speed"
|
||||
SERVICE_INCREASE_SPEED = "increase_speed"
|
||||
SERVICE_DECREASE_SPEED = "decrease_speed"
|
||||
SERVICE_OSCILLATE = "oscillate"
|
||||
|
@ -55,37 +52,16 @@ SERVICE_SET_DIRECTION = "set_direction"
|
|||
SERVICE_SET_PERCENTAGE = "set_percentage"
|
||||
SERVICE_SET_PRESET_MODE = "set_preset_mode"
|
||||
|
||||
SPEED_OFF = "off"
|
||||
SPEED_LOW = "low"
|
||||
SPEED_MEDIUM = "medium"
|
||||
SPEED_HIGH = "high"
|
||||
|
||||
DIRECTION_FORWARD = "forward"
|
||||
DIRECTION_REVERSE = "reverse"
|
||||
|
||||
ATTR_SPEED = "speed"
|
||||
ATTR_PERCENTAGE = "percentage"
|
||||
ATTR_PERCENTAGE_STEP = "percentage_step"
|
||||
ATTR_SPEED_LIST = "speed_list"
|
||||
ATTR_OSCILLATING = "oscillating"
|
||||
ATTR_DIRECTION = "direction"
|
||||
ATTR_PRESET_MODE = "preset_mode"
|
||||
ATTR_PRESET_MODES = "preset_modes"
|
||||
|
||||
_NOT_SPEED_OFF = "off"
|
||||
|
||||
OFF_SPEED_VALUES = [SPEED_OFF, None]
|
||||
|
||||
LEGACY_SPEED_LIST = [SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH]
|
||||
|
||||
|
||||
class NoValidSpeedsError(ValueError):
|
||||
"""Exception class when there are no valid speeds."""
|
||||
|
||||
|
||||
class NotValidSpeedError(ValueError):
|
||||
"""Exception class when the speed in not in the speed list."""
|
||||
|
||||
|
||||
class NotValidPresetModeError(ValueError):
|
||||
"""Exception class when the preset_mode in not in the preset_modes list."""
|
||||
|
@ -94,10 +70,7 @@ class NotValidPresetModeError(ValueError):
|
|||
@bind_hass
|
||||
def is_on(hass, entity_id: str) -> bool:
|
||||
"""Return if the fans are on based on the statemachine."""
|
||||
state = hass.states.get(entity_id)
|
||||
if ATTR_SPEED in state.attributes:
|
||||
return state.attributes[ATTR_SPEED] not in OFF_SPEED_VALUES
|
||||
return state.state == STATE_ON
|
||||
return hass.states.get(entity_id).state == STATE_ON
|
||||
|
||||
|
||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
|
@ -113,24 +86,15 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
component.async_register_entity_service(
|
||||
SERVICE_TURN_ON,
|
||||
{
|
||||
vol.Optional(ATTR_SPEED): cv.string,
|
||||
vol.Optional(ATTR_PERCENTAGE): vol.All(
|
||||
vol.Coerce(int), vol.Range(min=0, max=100)
|
||||
),
|
||||
vol.Optional(ATTR_PRESET_MODE): cv.string,
|
||||
},
|
||||
"async_turn_on_compat",
|
||||
"async_turn_on",
|
||||
)
|
||||
component.async_register_entity_service(SERVICE_TURN_OFF, {}, "async_turn_off")
|
||||
component.async_register_entity_service(SERVICE_TOGGLE, {}, "async_toggle")
|
||||
# After the transition to percentage and preset_modes concludes,
|
||||
# remove this service
|
||||
component.async_register_entity_service(
|
||||
SERVICE_SET_SPEED,
|
||||
{vol.Required(ATTR_SPEED): cv.string},
|
||||
"async_set_speed_deprecated",
|
||||
[SUPPORT_SET_SPEED],
|
||||
)
|
||||
component.async_register_entity_service(
|
||||
SERVICE_INCREASE_SPEED,
|
||||
{
|
||||
|
@ -212,29 +176,6 @@ class FanEntity(ToggleEntity):
|
|||
_attr_speed_count: int
|
||||
_attr_supported_features: int = 0
|
||||
|
||||
def set_speed(self, speed: str) -> None:
|
||||
"""Set the speed of the fan."""
|
||||
raise NotImplementedError()
|
||||
|
||||
async def async_set_speed_deprecated(self, speed: str):
|
||||
"""Set the speed of the fan."""
|
||||
_LOGGER.error(
|
||||
"The fan.set_speed service is deprecated and will fail in 2022.3 and later, use fan.set_percentage or fan.set_preset_mode instead"
|
||||
)
|
||||
await self.async_set_speed(speed)
|
||||
|
||||
async def async_set_speed(self, speed: str):
|
||||
"""Set the speed of the fan."""
|
||||
if speed == SPEED_OFF:
|
||||
await self.async_turn_off()
|
||||
return
|
||||
|
||||
if self.preset_modes and speed in self.preset_modes:
|
||||
await self.async_set_preset_mode(speed)
|
||||
return
|
||||
|
||||
await self.async_set_percentage(self.speed_to_percentage(speed))
|
||||
|
||||
def set_percentage(self, percentage: int) -> None:
|
||||
"""Set the speed of the fan, as a percentage."""
|
||||
raise NotImplementedError()
|
||||
|
@ -301,7 +242,6 @@ class FanEntity(ToggleEntity):
|
|||
# pylint: disable=arguments-differ
|
||||
def turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs,
|
||||
|
@ -309,64 +249,22 @@ class FanEntity(ToggleEntity):
|
|||
"""Turn on the fan."""
|
||||
raise NotImplementedError()
|
||||
|
||||
async def async_turn_on_compat(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
"""Turn on the fan.
|
||||
|
||||
This _compat version wraps async_turn_on with
|
||||
backwards and forward compatibility.
|
||||
|
||||
This compatibility shim will be removed in 2022.3
|
||||
"""
|
||||
if preset_mode is not None:
|
||||
self._valid_preset_mode_or_raise(preset_mode)
|
||||
speed = preset_mode
|
||||
percentage = None
|
||||
elif speed is not None:
|
||||
_LOGGER.error(
|
||||
"Calling fan.turn_on with the speed argument is deprecated and will fail in 2022.3 and later, use percentage or preset_mode instead"
|
||||
)
|
||||
if self.preset_modes and speed in self.preset_modes:
|
||||
preset_mode = speed
|
||||
percentage = None
|
||||
else:
|
||||
percentage = self.speed_to_percentage(speed)
|
||||
elif percentage is not None:
|
||||
speed = self.percentage_to_speed(percentage)
|
||||
|
||||
await self.async_turn_on(
|
||||
speed=speed,
|
||||
percentage=percentage,
|
||||
preset_mode=preset_mode,
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
# pylint: disable=arguments-differ
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs,
|
||||
) -> None:
|
||||
"""Turn on the fan."""
|
||||
if speed == SPEED_OFF:
|
||||
await self.async_turn_off()
|
||||
else:
|
||||
await self.hass.async_add_executor_job(
|
||||
ft.partial(
|
||||
self.turn_on,
|
||||
speed=speed,
|
||||
percentage=percentage,
|
||||
preset_mode=preset_mode,
|
||||
**kwargs,
|
||||
)
|
||||
await self.hass.async_add_executor_job(
|
||||
ft.partial(
|
||||
self.turn_on,
|
||||
percentage=percentage,
|
||||
preset_mode=preset_mode,
|
||||
**kwargs,
|
||||
)
|
||||
)
|
||||
|
||||
def oscillate(self, oscillating: bool) -> None:
|
||||
"""Oscillate the fan."""
|
||||
|
@ -379,16 +277,9 @@ class FanEntity(ToggleEntity):
|
|||
@property
|
||||
def is_on(self):
|
||||
"""Return true if the entity is on."""
|
||||
return self.speed not in [SPEED_OFF, None]
|
||||
|
||||
@property
|
||||
def speed(self) -> str | None:
|
||||
"""Return the current speed."""
|
||||
if preset_mode := self.preset_mode:
|
||||
return preset_mode
|
||||
if (percentage := self.percentage) is None:
|
||||
return None
|
||||
return self.percentage_to_speed(percentage)
|
||||
return (
|
||||
self.percentage is not None and self.percentage > 0
|
||||
) or self.preset_mode is not None
|
||||
|
||||
@property
|
||||
def percentage(self) -> int | None:
|
||||
|
@ -409,14 +300,6 @@ class FanEntity(ToggleEntity):
|
|||
"""Return the step size for percentage."""
|
||||
return 100 / self.speed_count
|
||||
|
||||
@property
|
||||
def speed_list(self) -> list:
|
||||
"""Get the list of available speeds."""
|
||||
speeds = [SPEED_OFF, *LEGACY_SPEED_LIST]
|
||||
if preset_modes := self.preset_modes:
|
||||
speeds.extend(preset_modes)
|
||||
return speeds
|
||||
|
||||
@property
|
||||
def current_direction(self) -> str | None:
|
||||
"""Return the current direction of the fan."""
|
||||
|
@ -431,8 +314,6 @@ class FanEntity(ToggleEntity):
|
|||
def capability_attributes(self):
|
||||
"""Return capability attributes."""
|
||||
attrs = {}
|
||||
if self.supported_features & SUPPORT_SET_SPEED:
|
||||
attrs[ATTR_SPEED_LIST] = self.speed_list
|
||||
|
||||
if (
|
||||
self.supported_features & SUPPORT_SET_SPEED
|
||||
|
@ -442,22 +323,6 @@ class FanEntity(ToggleEntity):
|
|||
|
||||
return attrs
|
||||
|
||||
def speed_to_percentage(self, speed: str) -> int: # pylint: disable=no-self-use
|
||||
"""Map a legacy speed to a percentage."""
|
||||
if speed in OFF_SPEED_VALUES:
|
||||
return 0
|
||||
if speed not in LEGACY_SPEED_LIST:
|
||||
raise NotValidSpeedError(f"The speed {speed} is not a valid speed.")
|
||||
return ordered_list_item_to_percentage(LEGACY_SPEED_LIST, speed)
|
||||
|
||||
def percentage_to_speed( # pylint: disable=no-self-use
|
||||
self, percentage: int
|
||||
) -> str:
|
||||
"""Map a percentage to a legacy speed."""
|
||||
if percentage == 0:
|
||||
return SPEED_OFF
|
||||
return percentage_to_ordered_list_item(LEGACY_SPEED_LIST, percentage)
|
||||
|
||||
@final
|
||||
@property
|
||||
def state_attributes(self) -> dict:
|
||||
|
@ -472,7 +337,6 @@ class FanEntity(ToggleEntity):
|
|||
data[ATTR_OSCILLATING] = self.oscillating
|
||||
|
||||
if supported_features & SUPPORT_SET_SPEED:
|
||||
data[ATTR_SPEED] = self.speed
|
||||
data[ATTR_PERCENTAGE] = self.percentage
|
||||
data[ATTR_PERCENTAGE_STEP] = self.percentage_step
|
||||
|
||||
|
|
|
@ -20,13 +20,11 @@ from . import (
|
|||
ATTR_OSCILLATING,
|
||||
ATTR_PERCENTAGE,
|
||||
ATTR_PRESET_MODE,
|
||||
ATTR_SPEED,
|
||||
DOMAIN,
|
||||
SERVICE_OSCILLATE,
|
||||
SERVICE_SET_DIRECTION,
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
SERVICE_SET_PRESET_MODE,
|
||||
SERVICE_SET_SPEED,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -35,7 +33,6 @@ VALID_STATES = {STATE_ON, STATE_OFF}
|
|||
ATTRIBUTES = { # attribute: service
|
||||
ATTR_DIRECTION: SERVICE_SET_DIRECTION,
|
||||
ATTR_OSCILLATING: SERVICE_OSCILLATE,
|
||||
ATTR_SPEED: SERVICE_SET_SPEED,
|
||||
ATTR_PERCENTAGE: SERVICE_SET_PERCENTAGE,
|
||||
ATTR_PRESET_MODE: SERVICE_SET_PRESET_MODE,
|
||||
}
|
||||
|
|
|
@ -100,7 +100,6 @@ class Fan(CoordinatorEntity[State], FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str = None,
|
||||
percentage: int = None,
|
||||
preset_mode: str = None,
|
||||
**kwargs,
|
||||
|
|
|
@ -92,9 +92,7 @@ class FreedomproFan(CoordinatorEntity, FanEntity):
|
|||
await super().async_added_to_hass()
|
||||
self._handle_coordinator_update()
|
||||
|
||||
async def async_turn_on(
|
||||
self, speed=None, percentage=None, preset_mode=None, **kwargs
|
||||
):
|
||||
async def async_turn_on(self, percentage=None, preset_mode=None, **kwargs):
|
||||
"""Async function to turn on the fan."""
|
||||
payload = {"on": True}
|
||||
payload = json.dumps(payload)
|
||||
|
|
|
@ -208,7 +208,6 @@ class FanGroup(GroupEntity, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -117,7 +117,6 @@ class BaseHomeKitFan(HomeKitEntity, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -65,7 +65,6 @@ class InsteonFanEntity(InsteonEntity, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str = None,
|
||||
percentage: int = None,
|
||||
preset_mode: str = None,
|
||||
**kwargs,
|
||||
|
|
|
@ -76,7 +76,6 @@ class ISYFanEntity(ISYNodeEntity, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
|
@ -121,7 +120,6 @@ class ISYFanProgramEntity(ISYProgramEntity, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -106,7 +106,6 @@ class KNXFan(KnxEntity, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -72,7 +72,6 @@ class LutronCasetaFan(LutronCasetaDevice, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str = None,
|
||||
percentage: int = None,
|
||||
preset_mode: str = None,
|
||||
**kwargs,
|
||||
|
|
|
@ -39,7 +39,6 @@ class ModbusFan(BaseSwitch, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -129,7 +129,6 @@ class ModernFormsFanEntity(FanEntity, ModernFormsDeviceEntity):
|
|||
@modernforms_exception_handler
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: int | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: int | None = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -12,10 +12,6 @@ from homeassistant.components.fan import (
|
|||
ATTR_OSCILLATING,
|
||||
ATTR_PERCENTAGE,
|
||||
ATTR_PRESET_MODE,
|
||||
SPEED_HIGH,
|
||||
SPEED_LOW,
|
||||
SPEED_MEDIUM,
|
||||
SPEED_OFF,
|
||||
SUPPORT_OSCILLATE,
|
||||
SUPPORT_PRESET_MODE,
|
||||
SUPPORT_SET_SPEED,
|
||||
|
@ -163,10 +159,6 @@ _PLATFORM_SCHEMA_BASE = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend(
|
|||
vol.Optional(
|
||||
CONF_PAYLOAD_RESET_PRESET_MODE, default=DEFAULT_PAYLOAD_RESET
|
||||
): cv.string,
|
||||
vol.Optional(CONF_PAYLOAD_HIGH_SPEED, default=SPEED_HIGH): cv.string,
|
||||
vol.Optional(CONF_PAYLOAD_LOW_SPEED, default=SPEED_LOW): cv.string,
|
||||
vol.Optional(CONF_PAYLOAD_MEDIUM_SPEED, default=SPEED_MEDIUM): cv.string,
|
||||
vol.Optional(CONF_PAYLOAD_OFF_SPEED, default=SPEED_OFF): cv.string,
|
||||
vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string,
|
||||
vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
|
||||
vol.Optional(
|
||||
|
@ -176,10 +168,6 @@ _PLATFORM_SCHEMA_BASE = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend(
|
|||
CONF_PAYLOAD_OSCILLATION_ON, default=OSCILLATE_ON_PAYLOAD
|
||||
): cv.string,
|
||||
vol.Optional(CONF_SPEED_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Optional(
|
||||
CONF_SPEED_LIST,
|
||||
default=[SPEED_OFF, SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH],
|
||||
): cv.ensure_list,
|
||||
vol.Optional(CONF_SPEED_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_SPEED_VALUE_TEMPLATE): cv.template,
|
||||
vol.Optional(CONF_STATE_VALUE_TEMPLATE): cv.template,
|
||||
|
@ -537,7 +525,6 @@ class MqttFan(MqttEntity, FanEntity):
|
|||
# The speed attribute deprecated in the schema, support will be removed after a quarter (2021.7)
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str = None,
|
||||
percentage: int = None,
|
||||
preset_mode: str = None,
|
||||
**kwargs,
|
||||
|
@ -605,9 +592,7 @@ class MqttFan(MqttEntity, FanEntity):
|
|||
|
||||
This method is a coroutine.
|
||||
"""
|
||||
if preset_mode not in self.preset_modes:
|
||||
_LOGGER.warning("'%s'is not a valid preset mode", preset_mode)
|
||||
return
|
||||
self._valid_preset_mode_or_raise(preset_mode)
|
||||
|
||||
mqtt_payload = self._command_templates[ATTR_PRESET_MODE](preset_mode)
|
||||
|
||||
|
|
|
@ -55,9 +55,7 @@ class ZwaveFan(ZWaveDeviceEntity, FanEntity):
|
|||
zwave_speed = math.ceil(percentage_to_ranged_value(SPEED_RANGE, percentage))
|
||||
self.values.primary.send_value(zwave_speed)
|
||||
|
||||
async def async_turn_on(
|
||||
self, speed=None, percentage=None, preset_mode=None, **kwargs
|
||||
):
|
||||
async def async_turn_on(self, percentage=None, preset_mode=None, **kwargs):
|
||||
"""Turn the device on."""
|
||||
await self.async_set_percentage(percentage)
|
||||
|
||||
|
|
|
@ -84,7 +84,6 @@ class HASensemeFan(SensemeEntity, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -65,7 +65,6 @@ class SmartThingsFan(SmartThingsEntity, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs,
|
||||
|
|
|
@ -99,9 +99,9 @@ class SmartyFan(FanEntity):
|
|||
self._smarty_fan_speed = fan_speed
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
def turn_on(self, speed=None, percentage=None, preset_mode=None, **kwargs):
|
||||
def turn_on(self, percentage=None, preset_mode=None, **kwargs):
|
||||
"""Turn on the fan."""
|
||||
_LOGGER.debug("Turning on fan. Speed is %s", speed)
|
||||
_LOGGER.debug("Turning on fan. percentage is %s", percentage)
|
||||
self.set_percentage(percentage or DEFAULT_ON_PERCENTAGE)
|
||||
|
||||
def turn_off(self, **kwargs):
|
||||
|
|
|
@ -113,7 +113,6 @@ class TasmotaFan(
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -11,7 +11,6 @@ from homeassistant.components.fan import (
|
|||
ATTR_OSCILLATING,
|
||||
ATTR_PERCENTAGE,
|
||||
ATTR_PRESET_MODE,
|
||||
ATTR_SPEED,
|
||||
DIRECTION_FORWARD,
|
||||
DIRECTION_REVERSE,
|
||||
ENTITY_ID_FORMAT,
|
||||
|
@ -250,7 +249,6 @@ class TemplateFan(TemplateEntity, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str = None,
|
||||
percentage: int = None,
|
||||
preset_mode: str = None,
|
||||
**kwargs,
|
||||
|
@ -258,7 +256,6 @@ class TemplateFan(TemplateEntity, FanEntity):
|
|||
"""Turn on the fan."""
|
||||
await self._on_script.async_run(
|
||||
{
|
||||
ATTR_SPEED: speed,
|
||||
ATTR_PERCENTAGE: percentage,
|
||||
ATTR_PRESET_MODE: preset_mode,
|
||||
},
|
||||
|
@ -270,8 +267,6 @@ class TemplateFan(TemplateEntity, FanEntity):
|
|||
await self.async_set_preset_mode(preset_mode)
|
||||
elif percentage is not None:
|
||||
await self.async_set_percentage(percentage)
|
||||
elif speed is not None:
|
||||
await self.async_set_speed(speed)
|
||||
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn off the fan."""
|
||||
|
|
|
@ -43,7 +43,6 @@ class ToloFan(ToloSaunaCoordinatorEntity, FanEntity):
|
|||
|
||||
def turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -148,7 +148,6 @@ class TradfriAirPurifierFan(TradfriBaseEntity, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -161,7 +161,6 @@ class TuyaFanEntity(TuyaEntity, FanEntity):
|
|||
|
||||
def turn_on(
|
||||
self,
|
||||
speed: str = None,
|
||||
percentage: int = None,
|
||||
preset_mode: str = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -168,7 +168,6 @@ class ValloxFan(CoordinatorEntity, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -179,7 +179,6 @@ class VeSyncFanHA(VeSyncDevice, FanEntity):
|
|||
|
||||
def turn_on(
|
||||
self,
|
||||
speed: str = None,
|
||||
percentage: int = None,
|
||||
preset_mode: str = None,
|
||||
**kwargs,
|
||||
|
|
|
@ -138,7 +138,6 @@ class WemoHumidifier(WemoBinaryStateEntity, FanEntity):
|
|||
|
||||
def turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -108,7 +108,6 @@ class WiLightFan(WiLightDevice, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str = None,
|
||||
percentage: int = None,
|
||||
preset_mode: str = None,
|
||||
**kwargs,
|
||||
|
|
|
@ -326,7 +326,6 @@ class XiaomiGenericDevice(XiaomiCoordinatedMiioEntity, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str = None,
|
||||
percentage: int = None,
|
||||
preset_mode: str = None,
|
||||
**kwargs,
|
||||
|
|
|
@ -91,9 +91,7 @@ class BaseFan(FanEntity):
|
|||
"""Return the number of speeds the fan supports."""
|
||||
return int_states_in_range(SPEED_RANGE)
|
||||
|
||||
async def async_turn_on(
|
||||
self, speed=None, percentage=None, preset_mode=None, **kwargs
|
||||
) -> None:
|
||||
async def async_turn_on(self, percentage=None, preset_mode=None, **kwargs) -> None:
|
||||
"""Turn the entity on."""
|
||||
if percentage is None:
|
||||
percentage = DEFAULT_ON_PERCENTAGE
|
||||
|
|
|
@ -62,7 +62,7 @@ class ZwaveFan(ZWaveDeviceEntity, FanEntity):
|
|||
zwave_speed = math.ceil(percentage_to_ranged_value(SPEED_RANGE, percentage))
|
||||
self.node.set_dimmer(self.values.primary.value_id, zwave_speed)
|
||||
|
||||
def turn_on(self, speed=None, percentage=None, preset_mode=None, **kwargs):
|
||||
def turn_on(self, percentage=None, preset_mode=None, **kwargs):
|
||||
"""Turn the device on."""
|
||||
self.set_percentage(percentage)
|
||||
|
||||
|
|
|
@ -83,7 +83,6 @@ class ZwaveFan(ZWaveBaseEntity, FanEntity):
|
|||
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
**kwargs: Any,
|
||||
|
|
|
@ -16,17 +16,15 @@ from homeassistant.components.bond.const import (
|
|||
from homeassistant.components.bond.fan import PRESET_MODE_BREEZE
|
||||
from homeassistant.components.fan import (
|
||||
ATTR_DIRECTION,
|
||||
ATTR_PERCENTAGE,
|
||||
ATTR_PRESET_MODE,
|
||||
ATTR_PRESET_MODES,
|
||||
ATTR_SPEED,
|
||||
ATTR_SPEED_LIST,
|
||||
DIRECTION_FORWARD,
|
||||
DIRECTION_REVERSE,
|
||||
DOMAIN as FAN_DOMAIN,
|
||||
SERVICE_SET_DIRECTION,
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
SERVICE_SET_PRESET_MODE,
|
||||
SERVICE_SET_SPEED,
|
||||
SPEED_OFF,
|
||||
)
|
||||
from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_ON
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
@ -66,7 +64,6 @@ def ceiling_fan_with_breeze(name: str):
|
|||
async def turn_fan_on(
|
||||
hass: core.HomeAssistant,
|
||||
fan_id: str,
|
||||
speed: str | None = None,
|
||||
percentage: int | None = None,
|
||||
preset_mode: str | None = None,
|
||||
) -> None:
|
||||
|
@ -74,9 +71,7 @@ async def turn_fan_on(
|
|||
service_data = {ATTR_ENTITY_ID: fan_id}
|
||||
if preset_mode:
|
||||
service_data[fan.ATTR_PRESET_MODE] = preset_mode
|
||||
if speed:
|
||||
service_data[fan.ATTR_SPEED] = speed
|
||||
if percentage:
|
||||
if percentage is not None:
|
||||
service_data[fan.ATTR_PERCENTAGE] = percentage
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
|
@ -116,35 +111,27 @@ async def test_non_standard_speed_list(hass: core.HomeAssistant):
|
|||
props={"max_speed": 6},
|
||||
)
|
||||
|
||||
actual_speeds = hass.states.get("fan.name_1").attributes[ATTR_SPEED_LIST]
|
||||
assert actual_speeds == [
|
||||
fan.SPEED_OFF,
|
||||
fan.SPEED_LOW,
|
||||
fan.SPEED_MEDIUM,
|
||||
fan.SPEED_HIGH,
|
||||
]
|
||||
|
||||
with patch_bond_device_state():
|
||||
with patch_bond_action() as mock_set_speed_low:
|
||||
await turn_fan_on(hass, "fan.name_1", fan.SPEED_LOW)
|
||||
await turn_fan_on(hass, "fan.name_1", percentage=100 / 6 * 2)
|
||||
mock_set_speed_low.assert_called_once_with(
|
||||
"test-device-id", Action.set_speed(2)
|
||||
)
|
||||
|
||||
with patch_bond_action() as mock_set_speed_medium:
|
||||
await turn_fan_on(hass, "fan.name_1", fan.SPEED_MEDIUM)
|
||||
await turn_fan_on(hass, "fan.name_1", percentage=100 / 6 * 4)
|
||||
mock_set_speed_medium.assert_called_once_with(
|
||||
"test-device-id", Action.set_speed(4)
|
||||
)
|
||||
|
||||
with patch_bond_action() as mock_set_speed_high:
|
||||
await turn_fan_on(hass, "fan.name_1", fan.SPEED_HIGH)
|
||||
await turn_fan_on(hass, "fan.name_1", percentage=100)
|
||||
mock_set_speed_high.assert_called_once_with(
|
||||
"test-device-id", Action.set_speed(6)
|
||||
)
|
||||
|
||||
|
||||
async def test_fan_speed_with_no_max_seed(hass: core.HomeAssistant):
|
||||
async def test_fan_speed_with_no_max_speed(hass: core.HomeAssistant):
|
||||
"""Tests that fans without max speed (increase/decrease controls) map speed to HA standard."""
|
||||
await setup_platform(
|
||||
hass,
|
||||
|
@ -155,7 +142,7 @@ async def test_fan_speed_with_no_max_seed(hass: core.HomeAssistant):
|
|||
state={"power": 1, "speed": 14},
|
||||
)
|
||||
|
||||
assert hass.states.get("fan.name_1").attributes["speed"] == fan.SPEED_HIGH
|
||||
assert hass.states.get("fan.name_1").attributes["percentage"] == 100
|
||||
|
||||
|
||||
async def test_turn_on_fan_with_speed(hass: core.HomeAssistant):
|
||||
|
@ -165,7 +152,7 @@ async def test_turn_on_fan_with_speed(hass: core.HomeAssistant):
|
|||
)
|
||||
|
||||
with patch_bond_action() as mock_set_speed, patch_bond_device_state():
|
||||
await turn_fan_on(hass, "fan.name_1", fan.SPEED_LOW)
|
||||
await turn_fan_on(hass, "fan.name_1", percentage=1)
|
||||
|
||||
mock_set_speed.assert_called_with("test-device-id", Action.set_speed(1))
|
||||
|
||||
|
@ -264,9 +251,7 @@ async def test_turn_on_fan_preset_mode_not_supported(hass: core.HomeAssistant):
|
|||
props={"max_speed": 6},
|
||||
)
|
||||
|
||||
with patch_bond_action(), patch_bond_device_state(), pytest.raises(
|
||||
fan.NotValidPresetModeError
|
||||
):
|
||||
with patch_bond_action(), patch_bond_device_state(), pytest.raises(ValueError):
|
||||
await turn_fan_on(hass, "fan.name_1", preset_mode=PRESET_MODE_BREEZE)
|
||||
|
||||
with patch_bond_action(), patch_bond_device_state(), pytest.raises(ValueError):
|
||||
|
@ -296,7 +281,7 @@ async def test_turn_on_fan_with_off_with_breeze(hass: core.HomeAssistant):
|
|||
)
|
||||
|
||||
with patch_bond_action() as mock_actions, patch_bond_device_state():
|
||||
await turn_fan_on(hass, "fan.name_1", fan.SPEED_OFF)
|
||||
await turn_fan_on(hass, "fan.name_1", percentage=0)
|
||||
|
||||
assert mock_actions.mock_calls == [
|
||||
call("test-device-id", Action(Action.BREEZE_OFF)),
|
||||
|
@ -316,14 +301,14 @@ async def test_turn_on_fan_without_speed(hass: core.HomeAssistant):
|
|||
mock_turn_on.assert_called_with("test-device-id", Action.turn_on())
|
||||
|
||||
|
||||
async def test_turn_on_fan_with_off_speed(hass: core.HomeAssistant):
|
||||
async def test_turn_on_fan_with_off_percentage(hass: core.HomeAssistant):
|
||||
"""Tests that turn off command delegates to turn off API."""
|
||||
await setup_platform(
|
||||
hass, FAN_DOMAIN, ceiling_fan("name-1"), bond_device_id="test-device-id"
|
||||
)
|
||||
|
||||
with patch_bond_action() as mock_turn_off, patch_bond_device_state():
|
||||
await turn_fan_on(hass, "fan.name_1", fan.SPEED_OFF)
|
||||
await turn_fan_on(hass, "fan.name_1", percentage=0)
|
||||
|
||||
mock_turn_off.assert_called_with("test-device-id", Action.turn_off())
|
||||
|
||||
|
@ -337,8 +322,8 @@ async def test_set_speed_off(hass: core.HomeAssistant):
|
|||
with patch_bond_action() as mock_turn_off, patch_bond_device_state():
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_SET_SPEED,
|
||||
service_data={ATTR_ENTITY_ID: "fan.name_1", ATTR_SPEED: SPEED_OFF},
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
service_data={ATTR_ENTITY_ID: "fan.name_1", ATTR_PERCENTAGE: 0},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -374,7 +359,7 @@ async def test_set_speed_belief_speed_zero(hass: core.HomeAssistant):
|
|||
await hass.services.async_call(
|
||||
BOND_DOMAIN,
|
||||
SERVICE_SET_FAN_SPEED_TRACKED_STATE,
|
||||
{ATTR_ENTITY_ID: "fan.name_1", ATTR_SPEED: 0},
|
||||
{ATTR_ENTITY_ID: "fan.name_1", "speed": 0},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -396,7 +381,7 @@ async def test_set_speed_belief_speed_api_error(hass: core.HomeAssistant):
|
|||
await hass.services.async_call(
|
||||
BOND_DOMAIN,
|
||||
SERVICE_SET_FAN_SPEED_TRACKED_STATE,
|
||||
{ATTR_ENTITY_ID: "fan.name_1", ATTR_SPEED: 100},
|
||||
{ATTR_ENTITY_ID: "fan.name_1", "speed": 100},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -412,7 +397,7 @@ async def test_set_speed_belief_speed_100(hass: core.HomeAssistant):
|
|||
await hass.services.async_call(
|
||||
BOND_DOMAIN,
|
||||
SERVICE_SET_FAN_SPEED_TRACKED_STATE,
|
||||
{ATTR_ENTITY_ID: "fan.name_1", ATTR_SPEED: 100},
|
||||
{ATTR_ENTITY_ID: "fan.name_1", "speed": 100},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
|
|
@ -3,19 +3,14 @@
|
|||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from voluptuous.error import MultipleInvalid
|
||||
|
||||
from homeassistant.components.fan import (
|
||||
ATTR_PERCENTAGE,
|
||||
ATTR_SPEED,
|
||||
DOMAIN as FAN_DOMAIN,
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
SERVICE_SET_SPEED,
|
||||
SERVICE_TURN_OFF,
|
||||
SERVICE_TURN_ON,
|
||||
SPEED_HIGH,
|
||||
SPEED_LOW,
|
||||
SPEED_MEDIUM,
|
||||
SPEED_OFF,
|
||||
)
|
||||
from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON, STATE_UNAVAILABLE
|
||||
|
||||
|
@ -212,7 +207,7 @@ async def test_fans(hass, aioclient_mock, mock_deconz_websocket):
|
|||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: 0},
|
||||
blocking=True,
|
||||
)
|
||||
assert aioclient_mock.mock_calls[8][2] == {"speed": 1}
|
||||
assert aioclient_mock.mock_calls[8][2] == {"speed": 0}
|
||||
|
||||
# Events with an unsupported speed does not get converted
|
||||
|
||||
|
@ -273,7 +268,6 @@ async def test_fans_legacy_speed_modes(hass, aioclient_mock, mock_deconz_websock
|
|||
|
||||
assert len(hass.states.async_all()) == 2 # Light and fan
|
||||
assert hass.states.get("fan.ceiling_fan").state == STATE_ON
|
||||
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_SPEED] == SPEED_HIGH
|
||||
|
||||
# Test states
|
||||
|
||||
|
@ -289,7 +283,6 @@ async def test_fans_legacy_speed_modes(hass, aioclient_mock, mock_deconz_websock
|
|||
|
||||
assert hass.states.get("fan.ceiling_fan").state == STATE_ON
|
||||
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 25
|
||||
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_SPEED] == SPEED_LOW
|
||||
|
||||
event_changed_light = {
|
||||
"t": "event",
|
||||
|
@ -303,7 +296,6 @@ async def test_fans_legacy_speed_modes(hass, aioclient_mock, mock_deconz_websock
|
|||
|
||||
assert hass.states.get("fan.ceiling_fan").state == STATE_ON
|
||||
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 50
|
||||
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_SPEED] == SPEED_MEDIUM
|
||||
|
||||
event_changed_light = {
|
||||
"t": "event",
|
||||
|
@ -317,7 +309,6 @@ async def test_fans_legacy_speed_modes(hass, aioclient_mock, mock_deconz_websock
|
|||
|
||||
assert hass.states.get("fan.ceiling_fan").state == STATE_ON
|
||||
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 75
|
||||
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_SPEED] == SPEED_MEDIUM
|
||||
|
||||
event_changed_light = {
|
||||
"t": "event",
|
||||
|
@ -331,7 +322,6 @@ async def test_fans_legacy_speed_modes(hass, aioclient_mock, mock_deconz_websock
|
|||
|
||||
assert hass.states.get("fan.ceiling_fan").state == STATE_ON
|
||||
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 100
|
||||
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_SPEED] == SPEED_HIGH
|
||||
|
||||
event_changed_light = {
|
||||
"t": "event",
|
||||
|
@ -345,7 +335,6 @@ async def test_fans_legacy_speed_modes(hass, aioclient_mock, mock_deconz_websock
|
|||
|
||||
assert hass.states.get("fan.ceiling_fan").state == STATE_OFF
|
||||
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 0
|
||||
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_SPEED] == SPEED_OFF
|
||||
|
||||
# Test service calls
|
||||
|
||||
|
@ -367,99 +356,99 @@ async def test_fans_legacy_speed_modes(hass, aioclient_mock, mock_deconz_websock
|
|||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_SPEED: SPEED_OFF},
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: 0},
|
||||
blocking=True,
|
||||
)
|
||||
assert aioclient_mock.mock_calls[2][2] == {"speed": 1}
|
||||
assert aioclient_mock.mock_calls[2][2] == {"speed": 0}
|
||||
|
||||
# Service turn on fan with bad speed
|
||||
# async_turn_on_compat use speed_to_percentage which will convert to SPEED_MEDIUM -> 2
|
||||
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_SPEED: "bad"},
|
||||
blocking=True,
|
||||
)
|
||||
assert aioclient_mock.mock_calls[3][2] == {"speed": 2}
|
||||
with pytest.raises(MultipleInvalid):
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: "bad"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
# Service turn on fan to low speed
|
||||
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_SPEED: SPEED_LOW},
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: 25},
|
||||
blocking=True,
|
||||
)
|
||||
assert aioclient_mock.mock_calls[4][2] == {"speed": 1}
|
||||
assert aioclient_mock.mock_calls[3][2] == {"speed": 1}
|
||||
|
||||
# Service turn on fan to medium speed
|
||||
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_SPEED: SPEED_MEDIUM},
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: 50},
|
||||
blocking=True,
|
||||
)
|
||||
assert aioclient_mock.mock_calls[5][2] == {"speed": 2}
|
||||
assert aioclient_mock.mock_calls[4][2] == {"speed": 2}
|
||||
|
||||
# Service turn on fan to high speed
|
||||
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_SPEED: SPEED_HIGH},
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: 100},
|
||||
blocking=True,
|
||||
)
|
||||
assert aioclient_mock.mock_calls[6][2] == {"speed": 4}
|
||||
assert aioclient_mock.mock_calls[5][2] == {"speed": 4}
|
||||
|
||||
# Service set fan speed to low
|
||||
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_SET_SPEED,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_SPEED: SPEED_LOW},
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: 25},
|
||||
blocking=True,
|
||||
)
|
||||
assert aioclient_mock.mock_calls[7][2] == {"speed": 1}
|
||||
assert aioclient_mock.mock_calls[6][2] == {"speed": 1}
|
||||
|
||||
# Service set fan speed to medium
|
||||
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_SET_SPEED,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_SPEED: SPEED_MEDIUM},
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: 50},
|
||||
blocking=True,
|
||||
)
|
||||
assert aioclient_mock.mock_calls[8][2] == {"speed": 2}
|
||||
assert aioclient_mock.mock_calls[7][2] == {"speed": 2}
|
||||
|
||||
# Service set fan speed to high
|
||||
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_SET_SPEED,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_SPEED: SPEED_HIGH},
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: 100},
|
||||
blocking=True,
|
||||
)
|
||||
assert aioclient_mock.mock_calls[9][2] == {"speed": 4}
|
||||
assert aioclient_mock.mock_calls[8][2] == {"speed": 4}
|
||||
|
||||
# Service set fan speed to off
|
||||
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_SET_SPEED,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_SPEED: SPEED_OFF},
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: 0},
|
||||
blocking=True,
|
||||
)
|
||||
assert aioclient_mock.mock_calls[10][2] == {"speed": 0}
|
||||
assert aioclient_mock.mock_calls[9][2] == {"speed": 0}
|
||||
|
||||
# Service set fan speed to unsupported value
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
with pytest.raises(MultipleInvalid):
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_SET_SPEED,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_SPEED: "bad value"},
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
{ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: "bad value"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
@ -476,7 +465,7 @@ async def test_fans_legacy_speed_modes(hass, aioclient_mock, mock_deconz_websock
|
|||
await hass.async_block_till_done()
|
||||
|
||||
assert hass.states.get("fan.ceiling_fan").state == STATE_ON
|
||||
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_SPEED] == SPEED_MEDIUM
|
||||
assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 75
|
||||
|
||||
await hass.config_entries.async_unload(config_entry.entry_id)
|
||||
|
||||
|
|
|
@ -55,39 +55,6 @@ async def test_turn_on_with_speed_and_percentage(hass, fan_entity_id):
|
|||
"""Test turning on the device."""
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_OFF
|
||||
await hass.services.async_call(
|
||||
fan.DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: fan_entity_id, fan.ATTR_SPEED: fan.SPEED_HIGH},
|
||||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_HIGH
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 100
|
||||
|
||||
await hass.services.async_call(
|
||||
fan.DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: fan_entity_id, fan.ATTR_SPEED: fan.SPEED_MEDIUM},
|
||||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_MEDIUM
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 66
|
||||
|
||||
await hass.services.async_call(
|
||||
fan.DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: fan_entity_id, fan.ATTR_SPEED: fan.SPEED_LOW},
|
||||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_LOW
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 33
|
||||
|
||||
await hass.services.async_call(
|
||||
fan.DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
|
@ -96,7 +63,6 @@ async def test_turn_on_with_speed_and_percentage(hass, fan_entity_id):
|
|||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_HIGH
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 100
|
||||
|
||||
await hass.services.async_call(
|
||||
|
@ -107,7 +73,6 @@ async def test_turn_on_with_speed_and_percentage(hass, fan_entity_id):
|
|||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_MEDIUM
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 66
|
||||
|
||||
await hass.services.async_call(
|
||||
|
@ -118,7 +83,36 @@ async def test_turn_on_with_speed_and_percentage(hass, fan_entity_id):
|
|||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_LOW
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 33
|
||||
|
||||
await hass.services.async_call(
|
||||
fan.DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: fan_entity_id, fan.ATTR_PERCENTAGE: 100},
|
||||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 100
|
||||
|
||||
await hass.services.async_call(
|
||||
fan.DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: fan_entity_id, fan.ATTR_PERCENTAGE: 66},
|
||||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 66
|
||||
|
||||
await hass.services.async_call(
|
||||
fan.DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{ATTR_ENTITY_ID: fan_entity_id, fan.ATTR_PERCENTAGE: 33},
|
||||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 33
|
||||
|
||||
await hass.services.async_call(
|
||||
|
@ -129,7 +123,6 @@ async def test_turn_on_with_speed_and_percentage(hass, fan_entity_id):
|
|||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_OFF
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_OFF
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 0
|
||||
|
||||
|
||||
|
@ -198,19 +191,8 @@ async def test_turn_on_with_preset_mode_and_speed(hass, fan_entity_id):
|
|||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[fan.ATTR_SPEED] == PRESET_MODE_AUTO
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] is None
|
||||
assert state.attributes[fan.ATTR_PRESET_MODE] == PRESET_MODE_AUTO
|
||||
assert state.attributes[fan.ATTR_SPEED_LIST] == [
|
||||
fan.SPEED_OFF,
|
||||
fan.SPEED_LOW,
|
||||
fan.SPEED_MEDIUM,
|
||||
fan.SPEED_HIGH,
|
||||
PRESET_MODE_AUTO,
|
||||
PRESET_MODE_SMART,
|
||||
PRESET_MODE_SLEEP,
|
||||
PRESET_MODE_ON,
|
||||
]
|
||||
assert state.attributes[fan.ATTR_PRESET_MODES] == [
|
||||
PRESET_MODE_AUTO,
|
||||
PRESET_MODE_SMART,
|
||||
|
@ -226,7 +208,6 @@ async def test_turn_on_with_preset_mode_and_speed(hass, fan_entity_id):
|
|||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_HIGH
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 100
|
||||
assert state.attributes[fan.ATTR_PRESET_MODE] is None
|
||||
|
||||
|
@ -238,7 +219,6 @@ async def test_turn_on_with_preset_mode_and_speed(hass, fan_entity_id):
|
|||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[fan.ATTR_SPEED] == PRESET_MODE_SMART
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] is None
|
||||
assert state.attributes[fan.ATTR_PRESET_MODE] == PRESET_MODE_SMART
|
||||
|
||||
|
@ -247,7 +227,6 @@ async def test_turn_on_with_preset_mode_and_speed(hass, fan_entity_id):
|
|||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_OFF
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_OFF
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 0
|
||||
assert state.attributes[fan.ATTR_PRESET_MODE] is None
|
||||
|
||||
|
@ -262,7 +241,6 @@ async def test_turn_on_with_preset_mode_and_speed(hass, fan_entity_id):
|
|||
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_OFF
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_OFF
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 0
|
||||
assert state.attributes[fan.ATTR_PRESET_MODE] is None
|
||||
|
||||
|
@ -321,50 +299,6 @@ async def test_set_direction(hass, fan_entity_id):
|
|||
assert state.attributes[fan.ATTR_DIRECTION] == fan.DIRECTION_REVERSE
|
||||
|
||||
|
||||
@pytest.mark.parametrize("fan_entity_id", LIMITED_AND_FULL_FAN_ENTITY_IDS)
|
||||
async def test_set_speed(hass, fan_entity_id):
|
||||
"""Test setting the speed of the device."""
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_OFF
|
||||
|
||||
await hass.services.async_call(
|
||||
fan.DOMAIN,
|
||||
fan.SERVICE_SET_SPEED,
|
||||
{ATTR_ENTITY_ID: fan_entity_id, fan.ATTR_SPEED: fan.SPEED_LOW},
|
||||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_LOW
|
||||
|
||||
await hass.services.async_call(
|
||||
fan.DOMAIN,
|
||||
fan.SERVICE_SET_SPEED,
|
||||
{ATTR_ENTITY_ID: fan_entity_id, fan.ATTR_SPEED: fan.SPEED_OFF},
|
||||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_OFF
|
||||
|
||||
|
||||
@pytest.mark.parametrize("fan_entity_id", FANS_WITH_PRESET_MODES)
|
||||
async def test_set_preset_mode_with_legacy_speed_service(hass, fan_entity_id):
|
||||
"""Test setting the preset mode is possible with the legacy service for backwards compat."""
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_OFF
|
||||
|
||||
await hass.services.async_call(
|
||||
fan.DOMAIN,
|
||||
fan.SERVICE_SET_SPEED,
|
||||
{ATTR_ENTITY_ID: fan_entity_id, fan.ATTR_SPEED: PRESET_MODE_AUTO},
|
||||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[fan.ATTR_SPEED] == PRESET_MODE_AUTO
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] is None
|
||||
assert state.attributes[fan.ATTR_PRESET_MODE] == PRESET_MODE_AUTO
|
||||
|
||||
|
||||
@pytest.mark.parametrize("fan_entity_id", FANS_WITH_PRESET_MODES)
|
||||
async def test_set_preset_mode(hass, fan_entity_id):
|
||||
"""Test setting the preset mode of the device."""
|
||||
|
@ -379,7 +313,6 @@ async def test_set_preset_mode(hass, fan_entity_id):
|
|||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.state == STATE_ON
|
||||
assert state.attributes[fan.ATTR_SPEED] == PRESET_MODE_AUTO
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] is None
|
||||
assert state.attributes[fan.ATTR_PRESET_MODE] == PRESET_MODE_AUTO
|
||||
|
||||
|
@ -422,7 +355,6 @@ async def test_set_percentage(hass, fan_entity_id):
|
|||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_LOW
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 33
|
||||
|
||||
|
||||
|
@ -440,7 +372,6 @@ async def test_increase_decrease_speed(hass, fan_entity_id):
|
|||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_LOW
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 33
|
||||
|
||||
await hass.services.async_call(
|
||||
|
@ -450,7 +381,6 @@ async def test_increase_decrease_speed(hass, fan_entity_id):
|
|||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_MEDIUM
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 66
|
||||
|
||||
await hass.services.async_call(
|
||||
|
@ -460,7 +390,6 @@ async def test_increase_decrease_speed(hass, fan_entity_id):
|
|||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_HIGH
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 100
|
||||
|
||||
await hass.services.async_call(
|
||||
|
@ -470,7 +399,6 @@ async def test_increase_decrease_speed(hass, fan_entity_id):
|
|||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_HIGH
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 100
|
||||
|
||||
await hass.services.async_call(
|
||||
|
@ -481,7 +409,6 @@ async def test_increase_decrease_speed(hass, fan_entity_id):
|
|||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 66
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_MEDIUM
|
||||
|
||||
await hass.services.async_call(
|
||||
fan.DOMAIN,
|
||||
|
@ -490,7 +417,6 @@ async def test_increase_decrease_speed(hass, fan_entity_id):
|
|||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_LOW
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 33
|
||||
|
||||
await hass.services.async_call(
|
||||
|
@ -500,7 +426,6 @@ async def test_increase_decrease_speed(hass, fan_entity_id):
|
|||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_OFF
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 0
|
||||
|
||||
await hass.services.async_call(
|
||||
|
@ -510,7 +435,6 @@ async def test_increase_decrease_speed(hass, fan_entity_id):
|
|||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_OFF
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 0
|
||||
|
||||
|
||||
|
@ -524,7 +448,6 @@ async def test_increase_decrease_speed_with_percentage_step(hass, fan_entity_id)
|
|||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_LOW
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 25
|
||||
|
||||
await hass.services.async_call(
|
||||
|
@ -534,7 +457,6 @@ async def test_increase_decrease_speed_with_percentage_step(hass, fan_entity_id)
|
|||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_MEDIUM
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 50
|
||||
|
||||
await hass.services.async_call(
|
||||
|
@ -544,7 +466,6 @@ async def test_increase_decrease_speed_with_percentage_step(hass, fan_entity_id)
|
|||
blocking=True,
|
||||
)
|
||||
state = hass.states.get(fan_entity_id)
|
||||
assert state.attributes[fan.ATTR_SPEED] == fan.SPEED_HIGH
|
||||
assert state.attributes[fan.ATTR_PERCENTAGE] == 75
|
||||
|
||||
|
||||
|
|
|
@ -1033,17 +1033,14 @@ async def test_put_light_state_fan(hass_hue, hue_client):
|
|||
|
||||
living_room_fan = hass_hue.states.get("fan.living_room_fan")
|
||||
assert living_room_fan.state == "on"
|
||||
assert living_room_fan.attributes[fan.ATTR_SPEED] == fan.SPEED_MEDIUM
|
||||
assert living_room_fan.attributes[fan.ATTR_PERCENTAGE] == 43
|
||||
|
||||
# Check setting the brightness of a fan to 0, 33%, 66% and 100% will respectively turn it off, low, medium or high
|
||||
# We also check non-cached GET value to exercise the code.
|
||||
await perform_put_light_state(
|
||||
hass_hue, hue_client, "fan.living_room_fan", True, brightness=0
|
||||
)
|
||||
assert (
|
||||
hass_hue.states.get("fan.living_room_fan").attributes[fan.ATTR_SPEED]
|
||||
== fan.SPEED_OFF
|
||||
)
|
||||
assert hass_hue.states.get("fan.living_room_fan").state == STATE_OFF
|
||||
await perform_put_light_state(
|
||||
hass_hue,
|
||||
hue_client,
|
||||
|
@ -1052,8 +1049,7 @@ async def test_put_light_state_fan(hass_hue, hue_client):
|
|||
brightness=round(33 * 254 / 100),
|
||||
)
|
||||
assert (
|
||||
hass_hue.states.get("fan.living_room_fan").attributes[fan.ATTR_SPEED]
|
||||
== fan.SPEED_LOW
|
||||
hass_hue.states.get("fan.living_room_fan").attributes[fan.ATTR_PERCENTAGE] == 33
|
||||
)
|
||||
with patch.object(hue_api, "STATE_CACHED_TIMEOUT", 0.000001):
|
||||
await asyncio.sleep(0.000001)
|
||||
|
@ -1070,8 +1066,7 @@ async def test_put_light_state_fan(hass_hue, hue_client):
|
|||
brightness=round(66 * 254 / 100),
|
||||
)
|
||||
assert (
|
||||
hass_hue.states.get("fan.living_room_fan").attributes[fan.ATTR_SPEED]
|
||||
== fan.SPEED_MEDIUM
|
||||
hass_hue.states.get("fan.living_room_fan").attributes[fan.ATTR_PERCENTAGE] == 66
|
||||
)
|
||||
with patch.object(hue_api, "STATE_CACHED_TIMEOUT", 0.000001):
|
||||
await asyncio.sleep(0.000001)
|
||||
|
@ -1079,7 +1074,7 @@ async def test_put_light_state_fan(hass_hue, hue_client):
|
|||
hue_client, "fan.living_room_fan", HTTPStatus.OK
|
||||
)
|
||||
assert (
|
||||
round(fan_json["state"][HUE_API_STATE_BRI] * 100 / 254) == 67
|
||||
round(fan_json["state"][HUE_API_STATE_BRI] * 100 / 254) == 66
|
||||
) # small rounding error in inverse operation
|
||||
|
||||
await perform_put_light_state(
|
||||
|
@ -1090,8 +1085,8 @@ async def test_put_light_state_fan(hass_hue, hue_client):
|
|||
brightness=round(100 * 254 / 100),
|
||||
)
|
||||
assert (
|
||||
hass_hue.states.get("fan.living_room_fan").attributes[fan.ATTR_SPEED]
|
||||
== fan.SPEED_HIGH
|
||||
hass_hue.states.get("fan.living_room_fan").attributes[fan.ATTR_PERCENTAGE]
|
||||
== 100
|
||||
)
|
||||
with patch.object(hue_api, "STATE_CACHED_TIMEOUT", 0.000001):
|
||||
await asyncio.sleep(0.000001)
|
||||
|
|
|
@ -9,9 +9,9 @@ from homeassistant.components.emulated_kasa.const import (
|
|||
DOMAIN,
|
||||
)
|
||||
from homeassistant.components.fan import (
|
||||
ATTR_SPEED,
|
||||
ATTR_PERCENTAGE,
|
||||
DOMAIN as FAN_DOMAIN,
|
||||
SERVICE_SET_SPEED,
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
)
|
||||
from homeassistant.components.light import DOMAIN as LIGHT_DOMAIN
|
||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||
|
@ -57,15 +57,15 @@ CONFIG = {
|
|||
ENTITY_FAN: {
|
||||
CONF_POWER: "{% if is_state_attr('"
|
||||
+ ENTITY_FAN
|
||||
+ "','speed', 'low') %} "
|
||||
+ "','percentage', 33) %} "
|
||||
+ str(ENTITY_FAN_SPEED_LOW)
|
||||
+ "{% elif is_state_attr('"
|
||||
+ ENTITY_FAN
|
||||
+ "','speed', 'medium') %} "
|
||||
+ "','percentage', 66) %} "
|
||||
+ str(ENTITY_FAN_SPEED_MED)
|
||||
+ "{% elif is_state_attr('"
|
||||
+ ENTITY_FAN
|
||||
+ "','speed', 'high') %} "
|
||||
+ "','percentage', 100) %} "
|
||||
+ str(ENTITY_FAN_SPEED_HIGH)
|
||||
+ "{% endif %}"
|
||||
},
|
||||
|
@ -109,15 +109,15 @@ CONFIG_FAN = {
|
|||
ENTITY_FAN: {
|
||||
CONF_POWER: "{% if is_state_attr('"
|
||||
+ ENTITY_FAN
|
||||
+ "','speed', 'low') %} "
|
||||
+ "','percentage', 33) %} "
|
||||
+ str(ENTITY_FAN_SPEED_LOW)
|
||||
+ "{% elif is_state_attr('"
|
||||
+ ENTITY_FAN
|
||||
+ "','speed', 'medium') %} "
|
||||
+ "','percentage', 66) %} "
|
||||
+ str(ENTITY_FAN_SPEED_MED)
|
||||
+ "{% elif is_state_attr('"
|
||||
+ ENTITY_FAN
|
||||
+ "','speed', 'high') %} "
|
||||
+ "','percentage', 100) %} "
|
||||
+ str(ENTITY_FAN_SPEED_HIGH)
|
||||
+ "{% endif %}"
|
||||
},
|
||||
|
@ -125,6 +125,7 @@ CONFIG_FAN = {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
CONFIG_SENSOR = {
|
||||
DOMAIN: {
|
||||
CONF_ENTITIES: {
|
||||
|
@ -281,8 +282,8 @@ async def test_template(hass):
|
|||
)
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_SET_SPEED,
|
||||
{ATTR_ENTITY_ID: ENTITY_FAN, ATTR_SPEED: "low"},
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
{ATTR_ENTITY_ID: ENTITY_FAN, ATTR_PERCENTAGE: 33},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
@ -299,8 +300,8 @@ async def test_template(hass):
|
|||
# Fan High:
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_SET_SPEED,
|
||||
{ATTR_ENTITY_ID: ENTITY_FAN, ATTR_SPEED: "high"},
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
{ATTR_ENTITY_ID: ENTITY_FAN, ATTR_PERCENTAGE: 100},
|
||||
blocking=True,
|
||||
)
|
||||
plug_it = emulated_kasa.get_plug_devices(hass, config)
|
||||
|
@ -462,8 +463,8 @@ async def test_multiple_devices(hass):
|
|||
)
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_SET_SPEED,
|
||||
{ATTR_ENTITY_ID: ENTITY_FAN, ATTR_SPEED: "medium"},
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
{ATTR_ENTITY_ID: ENTITY_FAN, ATTR_PERCENTAGE: 66},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ from homeassistant.components.fan import (
|
|||
ATTR_PERCENTAGE,
|
||||
ATTR_PERCENTAGE_STEP,
|
||||
ATTR_PRESET_MODE,
|
||||
ATTR_SPEED,
|
||||
DOMAIN,
|
||||
SERVICE_DECREASE_SPEED,
|
||||
SERVICE_INCREASE_SPEED,
|
||||
|
@ -17,7 +16,6 @@ from homeassistant.components.fan import (
|
|||
SERVICE_SET_DIRECTION,
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
SERVICE_SET_PRESET_MODE,
|
||||
SERVICE_SET_SPEED,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
|
@ -30,7 +28,6 @@ from homeassistant.const import (
|
|||
async def async_turn_on(
|
||||
hass,
|
||||
entity_id=ENTITY_MATCH_ALL,
|
||||
speed: str = None,
|
||||
percentage: int = None,
|
||||
preset_mode: str = None,
|
||||
) -> None:
|
||||
|
@ -39,7 +36,6 @@ async def async_turn_on(
|
|||
key: value
|
||||
for key, value in [
|
||||
(ATTR_ENTITY_ID, entity_id),
|
||||
(ATTR_SPEED, speed),
|
||||
(ATTR_PERCENTAGE, percentage),
|
||||
(ATTR_PRESET_MODE, preset_mode),
|
||||
]
|
||||
|
@ -72,17 +68,6 @@ async def async_oscillate(
|
|||
await hass.services.async_call(DOMAIN, SERVICE_OSCILLATE, data, blocking=True)
|
||||
|
||||
|
||||
async def async_set_speed(hass, entity_id=ENTITY_MATCH_ALL, speed: str = None) -> None:
|
||||
"""Set speed for all or specified fan."""
|
||||
data = {
|
||||
key: value
|
||||
for key, value in [(ATTR_ENTITY_ID, entity_id), (ATTR_SPEED, speed)]
|
||||
if value is not None
|
||||
}
|
||||
|
||||
await hass.services.async_call(DOMAIN, SERVICE_SET_SPEED, data, blocking=True)
|
||||
|
||||
|
||||
async def async_set_preset_mode(
|
||||
hass, entity_id=ENTITY_MATCH_ALL, preset_mode: str = None
|
||||
) -> None:
|
||||
|
|
|
@ -16,7 +16,6 @@ def test_fanentity():
|
|||
"""Test fan entity methods."""
|
||||
fan = BaseFan()
|
||||
assert fan.state == "off"
|
||||
assert len(fan.speed_list) == 4 # legacy compat off,low,medium,high
|
||||
assert fan.preset_modes is None
|
||||
assert fan.supported_features == 0
|
||||
assert fan.percentage_step == 1
|
||||
|
@ -25,7 +24,7 @@ def test_fanentity():
|
|||
# Test set_speed not required
|
||||
with pytest.raises(NotImplementedError):
|
||||
fan.oscillate(True)
|
||||
with pytest.raises(NotImplementedError):
|
||||
with pytest.raises(AttributeError):
|
||||
fan.set_speed("low")
|
||||
with pytest.raises(NotImplementedError):
|
||||
fan.set_percentage(0)
|
||||
|
@ -42,7 +41,6 @@ async def test_async_fanentity(hass):
|
|||
fan = BaseFan()
|
||||
fan.hass = hass
|
||||
assert fan.state == "off"
|
||||
assert len(fan.speed_list) == 4 # legacy compat off,low,medium,high
|
||||
assert fan.preset_modes is None
|
||||
assert fan.supported_features == 0
|
||||
assert fan.percentage_step == 1
|
||||
|
@ -51,7 +49,7 @@ async def test_async_fanentity(hass):
|
|||
# Test set_speed not required
|
||||
with pytest.raises(NotImplementedError):
|
||||
await fan.async_oscillate(True)
|
||||
with pytest.raises(NotImplementedError):
|
||||
with pytest.raises(AttributeError):
|
||||
await fan.async_set_speed("low")
|
||||
with pytest.raises(NotImplementedError):
|
||||
await fan.async_set_percentage(0)
|
||||
|
|
|
@ -8,7 +8,7 @@ async def test_reproducing_states(hass, caplog):
|
|||
"""Test reproducing Fan states."""
|
||||
hass.states.async_set("fan.entity_off", "off", {})
|
||||
hass.states.async_set("fan.entity_on", "on", {})
|
||||
hass.states.async_set("fan.entity_speed", "on", {"speed": "high"})
|
||||
hass.states.async_set("fan.entity_speed", "on", {"percentage": 100})
|
||||
hass.states.async_set("fan.entity_oscillating", "on", {"oscillating": True})
|
||||
hass.states.async_set("fan.entity_direction", "on", {"direction": "forward"})
|
||||
|
||||
|
@ -16,14 +16,14 @@ async def test_reproducing_states(hass, caplog):
|
|||
turn_off_calls = async_mock_service(hass, "fan", "turn_off")
|
||||
set_direction_calls = async_mock_service(hass, "fan", "set_direction")
|
||||
oscillate_calls = async_mock_service(hass, "fan", "oscillate")
|
||||
set_speed_calls = async_mock_service(hass, "fan", "set_speed")
|
||||
set_percentage_calls = async_mock_service(hass, "fan", "set_percentage")
|
||||
|
||||
# These calls should do nothing as entities already in desired state
|
||||
await hass.helpers.state.async_reproduce_state(
|
||||
[
|
||||
State("fan.entity_off", "off"),
|
||||
State("fan.entity_on", "on"),
|
||||
State("fan.entity_speed", "on", {"speed": "high"}),
|
||||
State("fan.entity_speed", "on", {"percentage": 100}),
|
||||
State("fan.entity_oscillating", "on", {"oscillating": True}),
|
||||
State("fan.entity_direction", "on", {"direction": "forward"}),
|
||||
],
|
||||
|
@ -33,7 +33,6 @@ async def test_reproducing_states(hass, caplog):
|
|||
assert len(turn_off_calls) == 0
|
||||
assert len(set_direction_calls) == 0
|
||||
assert len(oscillate_calls) == 0
|
||||
assert len(set_speed_calls) == 0
|
||||
|
||||
# Test invalid state is handled
|
||||
await hass.helpers.state.async_reproduce_state(
|
||||
|
@ -45,14 +44,14 @@ async def test_reproducing_states(hass, caplog):
|
|||
assert len(turn_off_calls) == 0
|
||||
assert len(set_direction_calls) == 0
|
||||
assert len(oscillate_calls) == 0
|
||||
assert len(set_speed_calls) == 0
|
||||
assert len(set_percentage_calls) == 0
|
||||
|
||||
# Make sure correct services are called
|
||||
await hass.helpers.state.async_reproduce_state(
|
||||
[
|
||||
State("fan.entity_on", "off"),
|
||||
State("fan.entity_off", "on"),
|
||||
State("fan.entity_speed", "on", {"speed": "low"}),
|
||||
State("fan.entity_speed", "on", {"percentage": 25}),
|
||||
State("fan.entity_oscillating", "on", {"oscillating": False}),
|
||||
State("fan.entity_direction", "on", {"direction": "reverse"}),
|
||||
# Should not raise
|
||||
|
@ -78,9 +77,12 @@ async def test_reproducing_states(hass, caplog):
|
|||
"oscillating": False,
|
||||
}
|
||||
|
||||
assert len(set_speed_calls) == 1
|
||||
assert set_speed_calls[0].domain == "fan"
|
||||
assert set_speed_calls[0].data == {"entity_id": "fan.entity_speed", "speed": "low"}
|
||||
assert len(set_percentage_calls) == 1
|
||||
assert set_percentage_calls[0].domain == "fan"
|
||||
assert set_percentage_calls[0].data == {
|
||||
"entity_id": "fan.entity_speed",
|
||||
"percentage": 25,
|
||||
}
|
||||
|
||||
assert len(turn_off_calls) == 1
|
||||
assert turn_off_calls[0].domain == "fan"
|
||||
|
|
|
@ -1589,7 +1589,7 @@ async def test_fan_speed(hass):
|
|||
hass,
|
||||
State(
|
||||
"fan.living_room_fan",
|
||||
fan.SPEED_HIGH,
|
||||
STATE_ON,
|
||||
attributes={
|
||||
"percentage": 33,
|
||||
"percentage_step": 1.0,
|
||||
|
@ -1633,7 +1633,7 @@ async def test_fan_reverse(hass, direction_state, direction_call):
|
|||
hass,
|
||||
State(
|
||||
"fan.living_room_fan",
|
||||
fan.SPEED_HIGH,
|
||||
STATE_ON,
|
||||
attributes={
|
||||
"percentage": 33,
|
||||
"percentage_step": 1.0,
|
||||
|
|
|
@ -59,7 +59,6 @@ async def test_haa_fan_setup(hass):
|
|||
supported_features=SUPPORT_SET_SPEED,
|
||||
capabilities={
|
||||
"preset_modes": None,
|
||||
"speed_list": ["off", "low", "medium", "high"],
|
||||
},
|
||||
),
|
||||
EntityTestInfo(
|
||||
|
|
|
@ -55,7 +55,6 @@ async def test_homeassistant_bridge_fan_setup(hass):
|
|||
),
|
||||
capabilities={
|
||||
"preset_modes": None,
|
||||
"speed_list": ["off", "low", "medium", "high"],
|
||||
},
|
||||
state="off",
|
||||
)
|
||||
|
|
|
@ -40,7 +40,6 @@ async def test_simpleconnect_fan_setup(hass):
|
|||
supported_features=SUPPORT_DIRECTION | SUPPORT_SET_SPEED,
|
||||
capabilities={
|
||||
"preset_modes": None,
|
||||
"speed_list": ["off", "low", "medium", "high"],
|
||||
},
|
||||
state="off",
|
||||
),
|
||||
|
|
|
@ -95,7 +95,7 @@ async def test_turn_on(hass, utcnow):
|
|||
await hass.services.async_call(
|
||||
"fan",
|
||||
"turn_on",
|
||||
{"entity_id": "fan.testdevice", "speed": "high"},
|
||||
{"entity_id": "fan.testdevice", "percentage": 100},
|
||||
blocking=True,
|
||||
)
|
||||
helper.async_assert_service_values(
|
||||
|
@ -109,7 +109,7 @@ async def test_turn_on(hass, utcnow):
|
|||
await hass.services.async_call(
|
||||
"fan",
|
||||
"turn_on",
|
||||
{"entity_id": "fan.testdevice", "speed": "medium"},
|
||||
{"entity_id": "fan.testdevice", "percentage": 66},
|
||||
blocking=True,
|
||||
)
|
||||
helper.async_assert_service_values(
|
||||
|
@ -123,7 +123,7 @@ async def test_turn_on(hass, utcnow):
|
|||
await hass.services.async_call(
|
||||
"fan",
|
||||
"turn_on",
|
||||
{"entity_id": "fan.testdevice", "speed": "low"},
|
||||
{"entity_id": "fan.testdevice", "percentage": 33},
|
||||
blocking=True,
|
||||
)
|
||||
helper.async_assert_service_values(
|
||||
|
@ -196,8 +196,8 @@ async def test_set_speed(hass, utcnow):
|
|||
|
||||
await hass.services.async_call(
|
||||
"fan",
|
||||
"set_speed",
|
||||
{"entity_id": "fan.testdevice", "speed": "high"},
|
||||
"set_percentage",
|
||||
{"entity_id": "fan.testdevice", "percentage": 100},
|
||||
blocking=True,
|
||||
)
|
||||
helper.async_assert_service_values(
|
||||
|
@ -209,8 +209,8 @@ async def test_set_speed(hass, utcnow):
|
|||
|
||||
await hass.services.async_call(
|
||||
"fan",
|
||||
"set_speed",
|
||||
{"entity_id": "fan.testdevice", "speed": "medium"},
|
||||
"set_percentage",
|
||||
{"entity_id": "fan.testdevice", "percentage": 66},
|
||||
blocking=True,
|
||||
)
|
||||
helper.async_assert_service_values(
|
||||
|
@ -222,8 +222,8 @@ async def test_set_speed(hass, utcnow):
|
|||
|
||||
await hass.services.async_call(
|
||||
"fan",
|
||||
"set_speed",
|
||||
{"entity_id": "fan.testdevice", "speed": "low"},
|
||||
"set_percentage",
|
||||
{"entity_id": "fan.testdevice", "percentage": 33},
|
||||
blocking=True,
|
||||
)
|
||||
helper.async_assert_service_values(
|
||||
|
@ -235,8 +235,8 @@ async def test_set_speed(hass, utcnow):
|
|||
|
||||
await hass.services.async_call(
|
||||
"fan",
|
||||
"set_speed",
|
||||
{"entity_id": "fan.testdevice", "speed": "off"},
|
||||
"set_percentage",
|
||||
{"entity_id": "fan.testdevice", "percentage": 0},
|
||||
blocking=True,
|
||||
)
|
||||
helper.async_assert_service_values(
|
||||
|
@ -291,7 +291,6 @@ async def test_speed_read(hass, utcnow):
|
|||
CharacteristicsTypes.ROTATION_SPEED: 100,
|
||||
},
|
||||
)
|
||||
assert state.attributes["speed"] == "high"
|
||||
assert state.attributes["percentage"] == 100
|
||||
assert state.attributes["percentage_step"] == 1.0
|
||||
|
||||
|
@ -301,7 +300,6 @@ async def test_speed_read(hass, utcnow):
|
|||
CharacteristicsTypes.ROTATION_SPEED: 50,
|
||||
},
|
||||
)
|
||||
assert state.attributes["speed"] == "medium"
|
||||
assert state.attributes["percentage"] == 50
|
||||
|
||||
state = await helper.async_update(
|
||||
|
@ -310,7 +308,6 @@ async def test_speed_read(hass, utcnow):
|
|||
CharacteristicsTypes.ROTATION_SPEED: 25,
|
||||
},
|
||||
)
|
||||
assert state.attributes["speed"] == "low"
|
||||
assert state.attributes["percentage"] == 25
|
||||
|
||||
state = await helper.async_update(
|
||||
|
@ -320,7 +317,6 @@ async def test_speed_read(hass, utcnow):
|
|||
CharacteristicsTypes.ROTATION_SPEED: 0,
|
||||
},
|
||||
)
|
||||
assert state.attributes["speed"] == "off"
|
||||
assert state.attributes["percentage"] == 0
|
||||
|
||||
|
||||
|
@ -392,7 +388,7 @@ async def test_v2_turn_on(hass, utcnow):
|
|||
await hass.services.async_call(
|
||||
"fan",
|
||||
"turn_on",
|
||||
{"entity_id": "fan.testdevice", "speed": "high"},
|
||||
{"entity_id": "fan.testdevice", "percentage": 100},
|
||||
blocking=True,
|
||||
)
|
||||
helper.async_assert_service_values(
|
||||
|
@ -406,7 +402,7 @@ async def test_v2_turn_on(hass, utcnow):
|
|||
await hass.services.async_call(
|
||||
"fan",
|
||||
"turn_on",
|
||||
{"entity_id": "fan.testdevice", "speed": "medium"},
|
||||
{"entity_id": "fan.testdevice", "percentage": 66},
|
||||
blocking=True,
|
||||
)
|
||||
helper.async_assert_service_values(
|
||||
|
@ -420,7 +416,7 @@ async def test_v2_turn_on(hass, utcnow):
|
|||
await hass.services.async_call(
|
||||
"fan",
|
||||
"turn_on",
|
||||
{"entity_id": "fan.testdevice", "speed": "low"},
|
||||
{"entity_id": "fan.testdevice", "percentage": 33},
|
||||
blocking=True,
|
||||
)
|
||||
helper.async_assert_service_values(
|
||||
|
@ -488,8 +484,8 @@ async def test_v2_set_speed(hass, utcnow):
|
|||
|
||||
await hass.services.async_call(
|
||||
"fan",
|
||||
"set_speed",
|
||||
{"entity_id": "fan.testdevice", "speed": "high"},
|
||||
"set_percentage",
|
||||
{"entity_id": "fan.testdevice", "percentage": 100},
|
||||
blocking=True,
|
||||
)
|
||||
helper.async_assert_service_values(
|
||||
|
@ -501,8 +497,8 @@ async def test_v2_set_speed(hass, utcnow):
|
|||
|
||||
await hass.services.async_call(
|
||||
"fan",
|
||||
"set_speed",
|
||||
{"entity_id": "fan.testdevice", "speed": "medium"},
|
||||
"set_percentage",
|
||||
{"entity_id": "fan.testdevice", "percentage": 66},
|
||||
blocking=True,
|
||||
)
|
||||
helper.async_assert_service_values(
|
||||
|
@ -514,8 +510,8 @@ async def test_v2_set_speed(hass, utcnow):
|
|||
|
||||
await hass.services.async_call(
|
||||
"fan",
|
||||
"set_speed",
|
||||
{"entity_id": "fan.testdevice", "speed": "low"},
|
||||
"set_percentage",
|
||||
{"entity_id": "fan.testdevice", "percentage": 33},
|
||||
blocking=True,
|
||||
)
|
||||
helper.async_assert_service_values(
|
||||
|
@ -527,8 +523,8 @@ async def test_v2_set_speed(hass, utcnow):
|
|||
|
||||
await hass.services.async_call(
|
||||
"fan",
|
||||
"set_speed",
|
||||
{"entity_id": "fan.testdevice", "speed": "off"},
|
||||
"set_percentage",
|
||||
{"entity_id": "fan.testdevice", "percentage": 0},
|
||||
blocking=True,
|
||||
)
|
||||
helper.async_assert_service_values(
|
||||
|
@ -616,7 +612,6 @@ async def test_v2_speed_read(hass, utcnow):
|
|||
CharacteristicsTypes.ROTATION_SPEED: 100,
|
||||
},
|
||||
)
|
||||
assert state.attributes["speed"] == "high"
|
||||
assert state.attributes["percentage"] == 100
|
||||
|
||||
state = await helper.async_update(
|
||||
|
@ -625,7 +620,6 @@ async def test_v2_speed_read(hass, utcnow):
|
|||
CharacteristicsTypes.ROTATION_SPEED: 50,
|
||||
},
|
||||
)
|
||||
assert state.attributes["speed"] == "medium"
|
||||
assert state.attributes["percentage"] == 50
|
||||
|
||||
state = await helper.async_update(
|
||||
|
@ -634,7 +628,6 @@ async def test_v2_speed_read(hass, utcnow):
|
|||
CharacteristicsTypes.ROTATION_SPEED: 25,
|
||||
},
|
||||
)
|
||||
assert state.attributes["speed"] == "low"
|
||||
assert state.attributes["percentage"] == 25
|
||||
|
||||
state = await helper.async_update(
|
||||
|
@ -644,7 +637,6 @@ async def test_v2_speed_read(hass, utcnow):
|
|||
CharacteristicsTypes.ROTATION_SPEED: 0,
|
||||
},
|
||||
)
|
||||
assert state.attributes["speed"] == "off"
|
||||
assert state.attributes["percentage"] == 0
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@ import json
|
|||
from unittest.mock import AsyncMock, Mock, patch
|
||||
|
||||
from homeassistant.components.climate.const import (
|
||||
FAN_HIGH,
|
||||
FAN_LOW,
|
||||
FAN_MEDIUM,
|
||||
HVAC_MODE_COOL,
|
||||
HVAC_MODE_DRY,
|
||||
HVAC_MODE_FAN_ONLY,
|
||||
|
@ -11,7 +14,6 @@ from homeassistant.components.climate.const import (
|
|||
SUPPORT_FAN_MODE,
|
||||
SUPPORT_TARGET_TEMPERATURE,
|
||||
)
|
||||
from homeassistant.components.fan import SPEED_HIGH, SPEED_LOW, SPEED_MEDIUM
|
||||
from homeassistant.components.melissa import DATA_MELISSA, climate as melissa
|
||||
from homeassistant.components.melissa.climate import MelissaClimate
|
||||
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
|
||||
|
@ -94,7 +96,7 @@ async def test_current_fan_mode(hass):
|
|||
device = (await api.async_fetch_devices())[_SERIAL]
|
||||
thermostat = MelissaClimate(api, _SERIAL, device)
|
||||
await thermostat.async_update()
|
||||
assert thermostat.fan_mode == SPEED_LOW
|
||||
assert thermostat.fan_mode == FAN_LOW
|
||||
|
||||
thermostat._cur_settings = None
|
||||
assert thermostat.fan_mode is None
|
||||
|
@ -162,7 +164,7 @@ async def test_fan_modes(hass):
|
|||
api = melissa_mock()
|
||||
device = (await api.async_fetch_devices())[_SERIAL]
|
||||
thermostat = MelissaClimate(api, _SERIAL, device)
|
||||
assert ["auto", SPEED_HIGH, SPEED_MEDIUM, SPEED_LOW] == thermostat.fan_modes
|
||||
assert ["auto", FAN_HIGH, FAN_MEDIUM, FAN_LOW] == thermostat.fan_modes
|
||||
|
||||
|
||||
async def test_target_temperature(hass):
|
||||
|
@ -247,9 +249,9 @@ async def test_fan_mode(hass):
|
|||
thermostat = MelissaClimate(api, _SERIAL, device)
|
||||
await thermostat.async_update()
|
||||
await hass.async_block_till_done()
|
||||
await thermostat.async_set_fan_mode(SPEED_HIGH)
|
||||
await thermostat.async_set_fan_mode(FAN_HIGH)
|
||||
await hass.async_block_till_done()
|
||||
assert thermostat.fan_mode == SPEED_HIGH
|
||||
assert thermostat.fan_mode == FAN_HIGH
|
||||
|
||||
|
||||
async def test_set_operation_mode(hass):
|
||||
|
@ -275,12 +277,12 @@ async def test_send(hass):
|
|||
await hass.async_block_till_done()
|
||||
await thermostat.async_send({"fan": api.FAN_MEDIUM})
|
||||
await hass.async_block_till_done()
|
||||
assert thermostat.fan_mode == SPEED_MEDIUM
|
||||
assert thermostat.fan_mode == FAN_MEDIUM
|
||||
api.async_send.return_value = AsyncMock(return_value=False)
|
||||
thermostat._cur_settings = None
|
||||
await thermostat.async_send({"fan": api.FAN_LOW})
|
||||
await hass.async_block_till_done()
|
||||
assert SPEED_LOW != thermostat.fan_mode
|
||||
assert FAN_LOW != thermostat.fan_mode
|
||||
assert thermostat._cur_settings is None
|
||||
|
||||
|
||||
|
@ -293,7 +295,7 @@ async def test_update(hass):
|
|||
device = (await api.async_fetch_devices())[_SERIAL]
|
||||
thermostat = MelissaClimate(api, _SERIAL, device)
|
||||
await thermostat.async_update()
|
||||
assert thermostat.fan_mode == SPEED_LOW
|
||||
assert thermostat.fan_mode == FAN_LOW
|
||||
assert thermostat.state == HVAC_MODE_HEAT
|
||||
api.async_status = AsyncMock(side_effect=KeyError("boom"))
|
||||
await thermostat.async_update()
|
||||
|
@ -322,9 +324,9 @@ async def test_melissa_fan_to_hass(hass):
|
|||
device = (await api.async_fetch_devices())[_SERIAL]
|
||||
thermostat = MelissaClimate(api, _SERIAL, device)
|
||||
assert thermostat.melissa_fan_to_hass(0) == "auto"
|
||||
assert thermostat.melissa_fan_to_hass(1) == SPEED_LOW
|
||||
assert thermostat.melissa_fan_to_hass(2) == SPEED_MEDIUM
|
||||
assert thermostat.melissa_fan_to_hass(3) == SPEED_HIGH
|
||||
assert thermostat.melissa_fan_to_hass(1) == FAN_LOW
|
||||
assert thermostat.melissa_fan_to_hass(2) == FAN_MEDIUM
|
||||
assert thermostat.melissa_fan_to_hass(3) == FAN_HIGH
|
||||
assert thermostat.melissa_fan_to_hass(4) is None
|
||||
|
||||
|
||||
|
@ -355,9 +357,9 @@ async def test_hass_fan_to_melissa(hass):
|
|||
device = (await api.async_fetch_devices())[_SERIAL]
|
||||
thermostat = MelissaClimate(api, _SERIAL, device)
|
||||
assert thermostat.hass_fan_to_melissa("auto") == 0
|
||||
assert thermostat.hass_fan_to_melissa(SPEED_LOW) == 1
|
||||
assert thermostat.hass_fan_to_melissa(SPEED_MEDIUM) == 2
|
||||
assert thermostat.hass_fan_to_melissa(SPEED_HIGH) == 3
|
||||
assert thermostat.hass_fan_to_melissa(FAN_LOW) == 1
|
||||
assert thermostat.hass_fan_to_melissa(FAN_MEDIUM) == 2
|
||||
assert thermostat.hass_fan_to_melissa(FAN_HIGH) == 3
|
||||
thermostat.hass_fan_to_melissa("test")
|
||||
mocked_warning.assert_called_once_with(
|
||||
"Melissa have no setting for %s fan mode", "test"
|
||||
|
|
|
@ -194,7 +194,6 @@ async def test_controlling_state_via_topic(hass, mqtt_mock, caplog):
|
|||
async_fire_mqtt_message(hass, "percentage-state-topic", "rEset_percentage")
|
||||
state = hass.states.get("fan.test")
|
||||
assert state.attributes.get(fan.ATTR_PERCENTAGE) is None
|
||||
assert state.attributes.get(fan.ATTR_SPEED) is None
|
||||
|
||||
async_fire_mqtt_message(hass, "state-topic", "None")
|
||||
state = hass.states.get("fan.test")
|
||||
|
@ -599,9 +598,8 @@ async def test_sending_mqtt_commands_and_optimistic(hass, mqtt_mock, caplog):
|
|||
assert state.attributes.get(fan.ATTR_PERCENTAGE) == 0
|
||||
assert state.attributes.get(ATTR_ASSUMED_STATE)
|
||||
|
||||
await common.async_set_preset_mode(hass, "fan.test", "low")
|
||||
assert "not a valid preset mode" in caplog.text
|
||||
caplog.clear()
|
||||
with pytest.raises(NotValidPresetModeError):
|
||||
await common.async_set_preset_mode(hass, "fan.test", "low")
|
||||
|
||||
await common.async_set_preset_mode(hass, "fan.test", "whoosh")
|
||||
mqtt_mock.async_publish.assert_called_once_with(
|
||||
|
@ -799,13 +797,11 @@ async def test_sending_mqtt_commands_and_optimistic_no_legacy(hass, mqtt_mock, c
|
|||
assert state.attributes.get(fan.ATTR_PERCENTAGE) == 0
|
||||
assert state.attributes.get(ATTR_ASSUMED_STATE)
|
||||
|
||||
await common.async_set_preset_mode(hass, "fan.test", "low")
|
||||
assert "not a valid preset mode" in caplog.text
|
||||
caplog.clear()
|
||||
with pytest.raises(NotValidPresetModeError):
|
||||
await common.async_set_preset_mode(hass, "fan.test", "low")
|
||||
|
||||
await common.async_set_preset_mode(hass, "fan.test", "auto")
|
||||
assert "not a valid preset mode" in caplog.text
|
||||
caplog.clear()
|
||||
with pytest.raises(NotValidPresetModeError):
|
||||
await common.async_set_preset_mode(hass, "fan.test", "auto")
|
||||
|
||||
await common.async_set_preset_mode(hass, "fan.test", "whoosh")
|
||||
mqtt_mock.async_publish.assert_called_once_with(
|
||||
|
@ -938,13 +934,11 @@ async def test_sending_mqtt_command_templates_(hass, mqtt_mock, caplog):
|
|||
assert state.attributes.get(fan.ATTR_PERCENTAGE) == 0
|
||||
assert state.attributes.get(ATTR_ASSUMED_STATE)
|
||||
|
||||
await common.async_set_preset_mode(hass, "fan.test", "low")
|
||||
assert "not a valid preset mode" in caplog.text
|
||||
caplog.clear()
|
||||
with pytest.raises(NotValidPresetModeError):
|
||||
await common.async_set_preset_mode(hass, "fan.test", "low")
|
||||
|
||||
await common.async_set_preset_mode(hass, "fan.test", "medium")
|
||||
assert "not a valid preset mode" in caplog.text
|
||||
caplog.clear()
|
||||
with pytest.raises(NotValidPresetModeError):
|
||||
await common.async_set_preset_mode(hass, "fan.test", "medium")
|
||||
|
||||
await common.async_set_preset_mode(hass, "fan.test", "whoosh")
|
||||
mqtt_mock.async_publish.assert_called_once_with(
|
||||
|
@ -1035,9 +1029,8 @@ async def test_sending_mqtt_commands_and_optimistic_no_percentage_topic(
|
|||
assert state.state == STATE_UNKNOWN
|
||||
assert state.attributes.get(ATTR_ASSUMED_STATE)
|
||||
|
||||
await common.async_set_preset_mode(hass, "fan.test", "medium")
|
||||
assert "not a valid preset mode" in caplog.text
|
||||
caplog.clear()
|
||||
with pytest.raises(NotValidPresetModeError):
|
||||
await common.async_set_preset_mode(hass, "fan.test", "medium")
|
||||
|
||||
await common.async_set_preset_mode(hass, "fan.test", "whoosh")
|
||||
mqtt_mock.async_publish.assert_called_once_with(
|
||||
|
@ -1131,6 +1124,10 @@ async def test_sending_mqtt_commands_and_explicit_optimistic(hass, mqtt_mock, ca
|
|||
|
||||
with pytest.raises(NotValidPresetModeError):
|
||||
await common.async_turn_on(hass, "fan.test", preset_mode="auto")
|
||||
assert mqtt_mock.async_publish.call_count == 1
|
||||
# We can turn on, but the invalid preset mode will raise
|
||||
mqtt_mock.async_publish.assert_any_call("command-topic", "ON", 0, False)
|
||||
mqtt_mock.async_publish.reset_mock()
|
||||
|
||||
await common.async_turn_on(hass, "fan.test", preset_mode="whoosh")
|
||||
assert mqtt_mock.async_publish.call_count == 2
|
||||
|
@ -1259,13 +1256,11 @@ async def test_sending_mqtt_commands_and_explicit_optimistic(hass, mqtt_mock, ca
|
|||
with pytest.raises(MultipleInvalid):
|
||||
await common.async_set_percentage(hass, "fan.test", 101)
|
||||
|
||||
await common.async_set_preset_mode(hass, "fan.test", "low")
|
||||
assert "not a valid preset mode" in caplog.text
|
||||
caplog.clear()
|
||||
with pytest.raises(NotValidPresetModeError):
|
||||
await common.async_set_preset_mode(hass, "fan.test", "low")
|
||||
|
||||
await common.async_set_preset_mode(hass, "fan.test", "medium")
|
||||
assert "not a valid preset mode" in caplog.text
|
||||
caplog.clear()
|
||||
with pytest.raises(NotValidPresetModeError):
|
||||
await common.async_set_preset_mode(hass, "fan.test", "medium")
|
||||
|
||||
await common.async_set_preset_mode(hass, "fan.test", "whoosh")
|
||||
mqtt_mock.async_publish.assert_called_once_with(
|
||||
|
@ -1285,9 +1280,8 @@ async def test_sending_mqtt_commands_and_explicit_optimistic(hass, mqtt_mock, ca
|
|||
assert state.state == STATE_OFF
|
||||
assert state.attributes.get(ATTR_ASSUMED_STATE)
|
||||
|
||||
await common.async_set_preset_mode(hass, "fan.test", "freaking-high")
|
||||
assert "not a valid preset mode" in caplog.text
|
||||
caplog.clear()
|
||||
with pytest.raises(NotValidPresetModeError):
|
||||
await common.async_set_preset_mode(hass, "fan.test", "freaking-high")
|
||||
|
||||
mqtt_mock.async_publish.reset_mock()
|
||||
state = hass.states.get("fan.test")
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
"""Test Z-Wave Fans."""
|
||||
import pytest
|
||||
|
||||
from .common import setup_ozw
|
||||
|
||||
|
@ -119,13 +118,3 @@ async def test_fan(hass, fan_data, fan_msg, sent_messages, caplog):
|
|||
state = hass.states.get("fan.in_wall_smart_fan_control_level")
|
||||
assert state is not None
|
||||
assert state.state == "off"
|
||||
|
||||
# Test invalid speed
|
||||
new_speed = "invalid"
|
||||
with pytest.raises(ValueError):
|
||||
await hass.services.async_call(
|
||||
"fan",
|
||||
"set_speed",
|
||||
{"entity_id": "fan.in_wall_smart_fan_control_level", "speed": new_speed},
|
||||
blocking=True,
|
||||
)
|
||||
|
|
|
@ -7,13 +7,8 @@ real HTTP calls are not initiated during testing.
|
|||
from pysmartthings import Attribute, Capability
|
||||
|
||||
from homeassistant.components.fan import (
|
||||
ATTR_SPEED,
|
||||
ATTR_SPEED_LIST,
|
||||
ATTR_PERCENTAGE,
|
||||
DOMAIN as FAN_DOMAIN,
|
||||
SPEED_HIGH,
|
||||
SPEED_LOW,
|
||||
SPEED_MEDIUM,
|
||||
SPEED_OFF,
|
||||
SUPPORT_SET_SPEED,
|
||||
)
|
||||
from homeassistant.components.smartthings.const import DOMAIN, SIGNAL_SMARTTHINGS_UPDATE
|
||||
|
@ -42,13 +37,7 @@ async def test_entity_state(hass, device_factory):
|
|||
state = hass.states.get("fan.fan_1")
|
||||
assert state.state == "on"
|
||||
assert state.attributes[ATTR_SUPPORTED_FEATURES] == SUPPORT_SET_SPEED
|
||||
assert state.attributes[ATTR_SPEED] == SPEED_MEDIUM
|
||||
assert state.attributes[ATTR_SPEED_LIST] == [
|
||||
SPEED_OFF,
|
||||
SPEED_LOW,
|
||||
SPEED_MEDIUM,
|
||||
SPEED_HIGH,
|
||||
]
|
||||
assert state.attributes[ATTR_PERCENTAGE] == 66
|
||||
|
||||
|
||||
async def test_entity_and_device_attributes(hass, device_factory):
|
||||
|
@ -128,17 +117,17 @@ async def test_turn_on_with_speed(hass, device_factory):
|
|||
await hass.services.async_call(
|
||||
"fan",
|
||||
"turn_on",
|
||||
{ATTR_ENTITY_ID: "fan.fan_1", ATTR_SPEED: SPEED_HIGH},
|
||||
{ATTR_ENTITY_ID: "fan.fan_1", ATTR_PERCENTAGE: 100},
|
||||
blocking=True,
|
||||
)
|
||||
# Assert
|
||||
state = hass.states.get("fan.fan_1")
|
||||
assert state is not None
|
||||
assert state.state == "on"
|
||||
assert state.attributes[ATTR_SPEED] == SPEED_HIGH
|
||||
assert state.attributes[ATTR_PERCENTAGE] == 100
|
||||
|
||||
|
||||
async def test_set_speed(hass, device_factory):
|
||||
async def test_set_percentage(hass, device_factory):
|
||||
"""Test setting to specific fan speed."""
|
||||
# Arrange
|
||||
device = device_factory(
|
||||
|
@ -150,15 +139,15 @@ async def test_set_speed(hass, device_factory):
|
|||
# Act
|
||||
await hass.services.async_call(
|
||||
"fan",
|
||||
"set_speed",
|
||||
{ATTR_ENTITY_ID: "fan.fan_1", ATTR_SPEED: SPEED_HIGH},
|
||||
"set_percentage",
|
||||
{ATTR_ENTITY_ID: "fan.fan_1", ATTR_PERCENTAGE: 100},
|
||||
blocking=True,
|
||||
)
|
||||
# Assert
|
||||
state = hass.states.get("fan.fan_1")
|
||||
assert state is not None
|
||||
assert state.state == "on"
|
||||
assert state.attributes[ATTR_SPEED] == SPEED_HIGH
|
||||
assert state.attributes[ATTR_PERCENTAGE] == 100
|
||||
|
||||
|
||||
async def test_update_from_signal(hass, device_factory):
|
||||
|
|
|
@ -8,17 +8,11 @@ from homeassistant.components.fan import (
|
|||
ATTR_OSCILLATING,
|
||||
ATTR_PERCENTAGE,
|
||||
ATTR_PRESET_MODE,
|
||||
ATTR_SPEED,
|
||||
DIRECTION_FORWARD,
|
||||
DIRECTION_REVERSE,
|
||||
DOMAIN,
|
||||
SPEED_HIGH,
|
||||
SPEED_LOW,
|
||||
SPEED_MEDIUM,
|
||||
SPEED_OFF,
|
||||
SUPPORT_PRESET_MODE,
|
||||
SUPPORT_SET_SPEED,
|
||||
NotValidSpeedError,
|
||||
)
|
||||
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNAVAILABLE
|
||||
|
||||
|
@ -60,7 +54,7 @@ _DIRECTION_INPUT_SELECT = "input_select.direction"
|
|||
)
|
||||
async def test_missing_optional_config(hass, start_ha):
|
||||
"""Test: missing optional template is ok."""
|
||||
_verify(hass, STATE_ON, None, None, None, None, None)
|
||||
_verify(hass, STATE_ON, None, None, None, None)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("count,domain", [(0, DOMAIN)])
|
||||
|
@ -165,26 +159,26 @@ async def test_wrong_template_config(hass, start_ha):
|
|||
)
|
||||
async def test_templates_with_entities(hass, start_ha):
|
||||
"""Test tempalates with values from other entities."""
|
||||
_verify(hass, STATE_OFF, None, 0, None, None, None)
|
||||
_verify(hass, STATE_OFF, 0, None, None, None)
|
||||
|
||||
hass.states.async_set(_STATE_INPUT_BOOLEAN, True)
|
||||
hass.states.async_set(_PERCENTAGE_INPUT_NUMBER, 66)
|
||||
hass.states.async_set(_OSC_INPUT, "True")
|
||||
|
||||
for set_state, set_value, speed, value in [
|
||||
(_DIRECTION_INPUT_SELECT, DIRECTION_FORWARD, SPEED_MEDIUM, 66),
|
||||
(_PERCENTAGE_INPUT_NUMBER, 33, SPEED_LOW, 33),
|
||||
(_PERCENTAGE_INPUT_NUMBER, 66, SPEED_MEDIUM, 66),
|
||||
(_PERCENTAGE_INPUT_NUMBER, 100, SPEED_HIGH, 100),
|
||||
(_PERCENTAGE_INPUT_NUMBER, "dog", None, 0),
|
||||
for set_state, set_value, value in [
|
||||
(_DIRECTION_INPUT_SELECT, DIRECTION_FORWARD, 66),
|
||||
(_PERCENTAGE_INPUT_NUMBER, 33, 33),
|
||||
(_PERCENTAGE_INPUT_NUMBER, 66, 66),
|
||||
(_PERCENTAGE_INPUT_NUMBER, 100, 100),
|
||||
(_PERCENTAGE_INPUT_NUMBER, "dog", 0),
|
||||
]:
|
||||
hass.states.async_set(set_state, set_value)
|
||||
await hass.async_block_till_done()
|
||||
_verify(hass, STATE_ON, speed, value, True, DIRECTION_FORWARD, None)
|
||||
_verify(hass, STATE_ON, value, True, DIRECTION_FORWARD, None)
|
||||
|
||||
hass.states.async_set(_STATE_INPUT_BOOLEAN, False)
|
||||
await hass.async_block_till_done()
|
||||
_verify(hass, STATE_OFF, None, 0, True, DIRECTION_FORWARD, None)
|
||||
_verify(hass, STATE_OFF, 0, True, DIRECTION_FORWARD, None)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("count,domain", [(1, DOMAIN)])
|
||||
|
@ -207,12 +201,12 @@ async def test_templates_with_entities(hass, start_ha):
|
|||
},
|
||||
"sensor.percentage",
|
||||
[
|
||||
("0", 0, SPEED_OFF, None),
|
||||
("33", 33, SPEED_LOW, None),
|
||||
("invalid", 0, None, None),
|
||||
("5000", 0, None, None),
|
||||
("100", 100, SPEED_HIGH, None),
|
||||
("0", 0, SPEED_OFF, None),
|
||||
("0", 0, None),
|
||||
("33", 33, None),
|
||||
("invalid", 0, None),
|
||||
("5000", 0, None),
|
||||
("100", 100, None),
|
||||
("0", 0, None),
|
||||
],
|
||||
),
|
||||
(
|
||||
|
@ -232,21 +226,21 @@ async def test_templates_with_entities(hass, start_ha):
|
|||
},
|
||||
"sensor.preset_mode",
|
||||
[
|
||||
("0", None, None, None),
|
||||
("invalid", None, None, None),
|
||||
("auto", None, None, "auto"),
|
||||
("smart", None, None, "smart"),
|
||||
("invalid", None, None, None),
|
||||
("0", None, None),
|
||||
("invalid", None, None),
|
||||
("auto", None, "auto"),
|
||||
("smart", None, "smart"),
|
||||
("invalid", None, None),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_templates_with_entities2(hass, entity, tests, start_ha):
|
||||
"""Test templates with values from other entities."""
|
||||
for set_percentage, test_percentage, speed, test_type in tests:
|
||||
for set_percentage, test_percentage, test_type in tests:
|
||||
hass.states.async_set(entity, set_percentage)
|
||||
await hass.async_block_till_done()
|
||||
_verify(hass, STATE_ON, speed, test_percentage, None, None, test_type)
|
||||
_verify(hass, STATE_ON, test_percentage, None, None, test_type)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("count,domain", [(1, DOMAIN)])
|
||||
|
@ -295,7 +289,7 @@ async def test_availability_template_with_entities(hass, start_ha):
|
|||
},
|
||||
}
|
||||
},
|
||||
[STATE_OFF, None, None, None, None],
|
||||
[STATE_OFF, None, None, None],
|
||||
),
|
||||
(
|
||||
{
|
||||
|
@ -313,7 +307,7 @@ async def test_availability_template_with_entities(hass, start_ha):
|
|||
},
|
||||
}
|
||||
},
|
||||
[STATE_ON, None, 0, None, None],
|
||||
[STATE_ON, 0, None, None],
|
||||
),
|
||||
(
|
||||
{
|
||||
|
@ -331,7 +325,7 @@ async def test_availability_template_with_entities(hass, start_ha):
|
|||
},
|
||||
}
|
||||
},
|
||||
[STATE_ON, SPEED_MEDIUM, 66, True, DIRECTION_FORWARD],
|
||||
[STATE_ON, 66, True, DIRECTION_FORWARD],
|
||||
),
|
||||
(
|
||||
{
|
||||
|
@ -349,13 +343,13 @@ async def test_availability_template_with_entities(hass, start_ha):
|
|||
},
|
||||
}
|
||||
},
|
||||
[STATE_OFF, None, 0, None, None],
|
||||
[STATE_OFF, 0, None, None],
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_template_with_unavailable_entities(hass, states, start_ha):
|
||||
"""Test unavailability with value_template."""
|
||||
_verify(hass, states[0], states[1], states[2], states[3], states[4], None)
|
||||
_verify(hass, states[0], states[1], states[2], states[3], None)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("count,domain", [(1, DOMAIN)])
|
||||
|
@ -399,42 +393,7 @@ async def test_on_off(hass):
|
|||
]:
|
||||
await func(hass, _TEST_FAN)
|
||||
assert hass.states.get(_STATE_INPUT_BOOLEAN).state == state
|
||||
_verify(hass, state, None, 0, None, None, None)
|
||||
|
||||
|
||||
async def test_set_speed(hass):
|
||||
"""Test set valid speed."""
|
||||
await _register_components(hass, preset_modes=["auto", "smart"])
|
||||
|
||||
await common.async_turn_on(hass, _TEST_FAN)
|
||||
for cmd, type, state, value in [
|
||||
(SPEED_HIGH, SPEED_HIGH, STATE_ON, 100),
|
||||
(SPEED_MEDIUM, SPEED_MEDIUM, STATE_ON, 66),
|
||||
(SPEED_OFF, SPEED_OFF, STATE_OFF, 0),
|
||||
(SPEED_MEDIUM, SPEED_MEDIUM, STATE_ON, 66),
|
||||
]:
|
||||
await common.async_set_speed(hass, _TEST_FAN, cmd)
|
||||
assert float(hass.states.get(_PERCENTAGE_INPUT_NUMBER).state) == value
|
||||
_verify(hass, state, type, value, None, None, None)
|
||||
|
||||
with pytest.raises(NotValidSpeedError):
|
||||
await common.async_set_speed(hass, _TEST_FAN, "invalid")
|
||||
|
||||
assert float(hass.states.get(_PERCENTAGE_INPUT_NUMBER).state) == 66
|
||||
_verify(hass, STATE_ON, SPEED_MEDIUM, 66, None, None, None)
|
||||
|
||||
|
||||
async def test_set_invalid_speed(hass):
|
||||
"""Test set invalid speed when fan has valid speed."""
|
||||
await _register_components(hass)
|
||||
|
||||
await common.async_turn_on(hass, _TEST_FAN)
|
||||
await common.async_set_speed(hass, _TEST_FAN, SPEED_HIGH)
|
||||
assert float(hass.states.get(_PERCENTAGE_INPUT_NUMBER).state) == 100
|
||||
_verify(hass, STATE_ON, SPEED_HIGH, 100, None, None, None)
|
||||
|
||||
with pytest.raises(NotValidSpeedError):
|
||||
await common.async_set_speed(hass, _TEST_FAN, "invalid")
|
||||
_verify(hass, state, 0, None, None, None)
|
||||
|
||||
|
||||
async def test_set_invalid_direction_from_initial_stage(hass, calls):
|
||||
|
@ -445,7 +404,7 @@ async def test_set_invalid_direction_from_initial_stage(hass, calls):
|
|||
|
||||
await common.async_set_direction(hass, _TEST_FAN, "invalid")
|
||||
assert hass.states.get(_DIRECTION_INPUT_SELECT).state == ""
|
||||
_verify(hass, STATE_ON, None, 0, None, None, None)
|
||||
_verify(hass, STATE_ON, 0, None, None, None)
|
||||
|
||||
|
||||
async def test_set_osc(hass):
|
||||
|
@ -456,7 +415,7 @@ async def test_set_osc(hass):
|
|||
for state in [True, False]:
|
||||
await common.async_oscillate(hass, _TEST_FAN, state)
|
||||
assert hass.states.get(_OSC_INPUT).state == str(state)
|
||||
_verify(hass, STATE_ON, None, 0, state, None, None)
|
||||
_verify(hass, STATE_ON, 0, state, None, None)
|
||||
|
||||
|
||||
async def test_set_direction(hass):
|
||||
|
@ -467,7 +426,7 @@ async def test_set_direction(hass):
|
|||
for cmd in [DIRECTION_FORWARD, DIRECTION_REVERSE]:
|
||||
await common.async_set_direction(hass, _TEST_FAN, cmd)
|
||||
assert hass.states.get(_DIRECTION_INPUT_SELECT).state == cmd
|
||||
_verify(hass, STATE_ON, None, 0, None, cmd, None)
|
||||
_verify(hass, STATE_ON, 0, None, cmd, None)
|
||||
|
||||
|
||||
async def test_set_invalid_direction(hass):
|
||||
|
@ -478,17 +437,7 @@ async def test_set_invalid_direction(hass):
|
|||
for cmd in [DIRECTION_FORWARD, "invalid"]:
|
||||
await common.async_set_direction(hass, _TEST_FAN, cmd)
|
||||
assert hass.states.get(_DIRECTION_INPUT_SELECT).state == DIRECTION_FORWARD
|
||||
_verify(hass, STATE_ON, None, 0, None, DIRECTION_FORWARD, None)
|
||||
|
||||
|
||||
async def test_on_with_speed(hass):
|
||||
"""Test turn on with speed."""
|
||||
await _register_components(hass)
|
||||
|
||||
await common.async_turn_on(hass, _TEST_FAN, SPEED_HIGH)
|
||||
assert hass.states.get(_STATE_INPUT_BOOLEAN).state == STATE_ON
|
||||
assert int(float(hass.states.get(_PERCENTAGE_INPUT_NUMBER).state)) == 100
|
||||
_verify(hass, STATE_ON, SPEED_HIGH, 100, None, None, None)
|
||||
_verify(hass, STATE_ON, 0, None, DIRECTION_FORWARD, None)
|
||||
|
||||
|
||||
async def test_preset_modes(hass):
|
||||
|
@ -515,18 +464,18 @@ async def test_set_percentage(hass):
|
|||
await _register_components(hass)
|
||||
|
||||
await common.async_turn_on(hass, _TEST_FAN)
|
||||
for type, state, value in [
|
||||
(SPEED_HIGH, STATE_ON, 100),
|
||||
(SPEED_MEDIUM, STATE_ON, 66),
|
||||
(SPEED_OFF, STATE_OFF, 0),
|
||||
for state, value in [
|
||||
(STATE_ON, 100),
|
||||
(STATE_ON, 66),
|
||||
(STATE_OFF, 0),
|
||||
]:
|
||||
await common.async_set_percentage(hass, _TEST_FAN, value)
|
||||
assert int(float(hass.states.get(_PERCENTAGE_INPUT_NUMBER).state)) == value
|
||||
_verify(hass, state, type, value, None, None, None)
|
||||
_verify(hass, state, value, None, None, None)
|
||||
|
||||
await common.async_turn_on(hass, _TEST_FAN, percentage=50)
|
||||
assert int(float(hass.states.get(_PERCENTAGE_INPUT_NUMBER).state)) == 50
|
||||
_verify(hass, STATE_ON, SPEED_MEDIUM, 50, None, None, None)
|
||||
_verify(hass, STATE_ON, 50, None, None, None)
|
||||
|
||||
|
||||
async def test_increase_decrease_speed(hass):
|
||||
|
@ -534,16 +483,16 @@ async def test_increase_decrease_speed(hass):
|
|||
await _register_components(hass, speed_count=3)
|
||||
|
||||
await common.async_turn_on(hass, _TEST_FAN)
|
||||
for func, extra, state, type, value in [
|
||||
(common.async_set_percentage, 100, STATE_ON, SPEED_HIGH, 100),
|
||||
(common.async_decrease_speed, None, STATE_ON, SPEED_MEDIUM, 66),
|
||||
(common.async_decrease_speed, None, STATE_ON, SPEED_LOW, 33),
|
||||
(common.async_decrease_speed, None, STATE_OFF, SPEED_OFF, 0),
|
||||
(common.async_increase_speed, None, STATE_ON, SPEED_LOW, 33),
|
||||
for func, extra, state, value in [
|
||||
(common.async_set_percentage, 100, STATE_ON, 100),
|
||||
(common.async_decrease_speed, None, STATE_ON, 66),
|
||||
(common.async_decrease_speed, None, STATE_ON, 33),
|
||||
(common.async_decrease_speed, None, STATE_OFF, 0),
|
||||
(common.async_increase_speed, None, STATE_ON, 33),
|
||||
]:
|
||||
await func(hass, _TEST_FAN, extra)
|
||||
assert int(float(hass.states.get(_PERCENTAGE_INPUT_NUMBER).state)) == value
|
||||
_verify(hass, state, type, value, None, None, None)
|
||||
_verify(hass, state, value, None, None, None)
|
||||
|
||||
|
||||
async def test_increase_decrease_speed_default_speed_count(hass):
|
||||
|
@ -551,16 +500,16 @@ async def test_increase_decrease_speed_default_speed_count(hass):
|
|||
await _register_components(hass)
|
||||
|
||||
await common.async_turn_on(hass, _TEST_FAN)
|
||||
for func, extra, state, type, value in [
|
||||
(common.async_set_percentage, 100, STATE_ON, SPEED_HIGH, 100),
|
||||
(common.async_decrease_speed, None, STATE_ON, SPEED_HIGH, 99),
|
||||
(common.async_decrease_speed, None, STATE_ON, SPEED_HIGH, 98),
|
||||
(common.async_decrease_speed, 31, STATE_ON, SPEED_HIGH, 67),
|
||||
(common.async_decrease_speed, None, STATE_ON, SPEED_MEDIUM, 66),
|
||||
for func, extra, state, value in [
|
||||
(common.async_set_percentage, 100, STATE_ON, 100),
|
||||
(common.async_decrease_speed, None, STATE_ON, 99),
|
||||
(common.async_decrease_speed, None, STATE_ON, 98),
|
||||
(common.async_decrease_speed, 31, STATE_ON, 67),
|
||||
(common.async_decrease_speed, None, STATE_ON, 66),
|
||||
]:
|
||||
await func(hass, _TEST_FAN, extra)
|
||||
assert int(float(hass.states.get(_PERCENTAGE_INPUT_NUMBER).state)) == value
|
||||
_verify(hass, state, type, value, None, None, None)
|
||||
_verify(hass, state, value, None, None, None)
|
||||
|
||||
|
||||
async def test_set_invalid_osc_from_initial_state(hass):
|
||||
|
@ -571,7 +520,7 @@ async def test_set_invalid_osc_from_initial_state(hass):
|
|||
with pytest.raises(vol.Invalid):
|
||||
await common.async_oscillate(hass, _TEST_FAN, "invalid")
|
||||
assert hass.states.get(_OSC_INPUT).state == ""
|
||||
_verify(hass, STATE_ON, None, 0, None, None, None)
|
||||
_verify(hass, STATE_ON, 0, None, None, None)
|
||||
|
||||
|
||||
async def test_set_invalid_osc(hass):
|
||||
|
@ -581,18 +530,17 @@ async def test_set_invalid_osc(hass):
|
|||
await common.async_turn_on(hass, _TEST_FAN)
|
||||
await common.async_oscillate(hass, _TEST_FAN, True)
|
||||
assert hass.states.get(_OSC_INPUT).state == "True"
|
||||
_verify(hass, STATE_ON, None, 0, True, None, None)
|
||||
_verify(hass, STATE_ON, 0, True, None, None)
|
||||
|
||||
with pytest.raises(vol.Invalid):
|
||||
await common.async_oscillate(hass, _TEST_FAN, None)
|
||||
assert hass.states.get(_OSC_INPUT).state == "True"
|
||||
_verify(hass, STATE_ON, None, 0, True, None, None)
|
||||
_verify(hass, STATE_ON, 0, True, None, None)
|
||||
|
||||
|
||||
def _verify(
|
||||
hass,
|
||||
expected_state,
|
||||
expected_speed,
|
||||
expected_percentage,
|
||||
expected_oscillating,
|
||||
expected_direction,
|
||||
|
@ -602,7 +550,6 @@ def _verify(
|
|||
state = hass.states.get(_TEST_FAN)
|
||||
attributes = state.attributes
|
||||
assert state.state == str(expected_state)
|
||||
assert attributes.get(ATTR_SPEED) == expected_speed or SPEED_OFF
|
||||
assert attributes.get(ATTR_PERCENTAGE) == expected_percentage
|
||||
assert attributes.get(ATTR_OSCILLATING) == expected_oscillating
|
||||
assert attributes.get(ATTR_DIRECTION) == expected_direction
|
||||
|
|
|
@ -8,19 +8,13 @@ import zigpy.zcl.clusters.general as general
|
|||
import zigpy.zcl.clusters.hvac as hvac
|
||||
import zigpy.zcl.foundation as zcl_f
|
||||
|
||||
from homeassistant.components import fan
|
||||
from homeassistant.components.fan import (
|
||||
ATTR_PERCENTAGE,
|
||||
ATTR_PERCENTAGE_STEP,
|
||||
ATTR_PRESET_MODE,
|
||||
ATTR_SPEED,
|
||||
DOMAIN as FAN_DOMAIN,
|
||||
SERVICE_SET_PERCENTAGE,
|
||||
SERVICE_SET_PRESET_MODE,
|
||||
SERVICE_SET_SPEED,
|
||||
SPEED_HIGH,
|
||||
SPEED_LOW,
|
||||
SPEED_MEDIUM,
|
||||
SPEED_OFF,
|
||||
NotValidPresetModeError,
|
||||
)
|
||||
from homeassistant.components.zha.core.discovery import GROUP_PROBE
|
||||
|
@ -187,7 +181,7 @@ async def test_fan(hass, zha_device_joined_restored, zigpy_device):
|
|||
|
||||
# change speed from HA
|
||||
cluster.write_attributes.reset_mock()
|
||||
await async_set_speed(hass, entity_id, speed=fan.SPEED_HIGH)
|
||||
await async_set_percentage(hass, entity_id, percentage=100)
|
||||
assert len(cluster.write_attributes.mock_calls) == 1
|
||||
assert cluster.write_attributes.call_args == call({"fan_mode": 3})
|
||||
|
||||
|
@ -209,11 +203,11 @@ async def test_fan(hass, zha_device_joined_restored, zigpy_device):
|
|||
await async_test_rejoin(hass, zigpy_device, [cluster], (1,))
|
||||
|
||||
|
||||
async def async_turn_on(hass, entity_id, speed=None):
|
||||
async def async_turn_on(hass, entity_id, percentage=None):
|
||||
"""Turn fan on."""
|
||||
data = {
|
||||
key: value
|
||||
for key, value in [(ATTR_ENTITY_ID, entity_id), (ATTR_SPEED, speed)]
|
||||
for key, value in [(ATTR_ENTITY_ID, entity_id), (ATTR_PERCENTAGE, percentage)]
|
||||
if value is not None
|
||||
}
|
||||
|
||||
|
@ -227,15 +221,17 @@ async def async_turn_off(hass, entity_id):
|
|||
await hass.services.async_call(Platform.FAN, SERVICE_TURN_OFF, data, blocking=True)
|
||||
|
||||
|
||||
async def async_set_speed(hass, entity_id, speed=None):
|
||||
"""Set speed for specified fan."""
|
||||
async def async_set_percentage(hass, entity_id, percentage=None):
|
||||
"""Set percentage for specified fan."""
|
||||
data = {
|
||||
key: value
|
||||
for key, value in [(ATTR_ENTITY_ID, entity_id), (ATTR_SPEED, speed)]
|
||||
for key, value in [(ATTR_ENTITY_ID, entity_id), (ATTR_PERCENTAGE, percentage)]
|
||||
if value is not None
|
||||
}
|
||||
|
||||
await hass.services.async_call(Platform.FAN, SERVICE_SET_SPEED, data, blocking=True)
|
||||
await hass.services.async_call(
|
||||
Platform.FAN, SERVICE_SET_PERCENTAGE, data, blocking=True
|
||||
)
|
||||
|
||||
|
||||
async def async_set_preset_mode(hass, entity_id, preset_mode=None):
|
||||
|
@ -321,7 +317,7 @@ async def test_zha_group_fan_entity(hass, device_fan_1, device_fan_2, coordinato
|
|||
|
||||
# change speed from HA
|
||||
group_fan_cluster.write_attributes.reset_mock()
|
||||
await async_set_speed(hass, entity_id, speed=fan.SPEED_HIGH)
|
||||
await async_set_percentage(hass, entity_id, percentage=100)
|
||||
assert len(group_fan_cluster.write_attributes.mock_calls) == 1
|
||||
assert group_fan_cluster.write_attributes.call_args[0][0] == {"fan_mode": 3}
|
||||
|
||||
|
@ -428,13 +424,13 @@ async def test_zha_group_fan_entity_failure_state(
|
|||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"plug_read, expected_state, expected_speed, expected_percentage",
|
||||
"plug_read, expected_state, expected_percentage",
|
||||
(
|
||||
(None, STATE_OFF, None, None),
|
||||
({"fan_mode": 0}, STATE_OFF, SPEED_OFF, 0),
|
||||
({"fan_mode": 1}, STATE_ON, SPEED_LOW, 33),
|
||||
({"fan_mode": 2}, STATE_ON, SPEED_MEDIUM, 66),
|
||||
({"fan_mode": 3}, STATE_ON, SPEED_HIGH, 100),
|
||||
(None, STATE_OFF, None),
|
||||
({"fan_mode": 0}, STATE_OFF, 0),
|
||||
({"fan_mode": 1}, STATE_ON, 33),
|
||||
({"fan_mode": 2}, STATE_ON, 66),
|
||||
({"fan_mode": 3}, STATE_ON, 100),
|
||||
),
|
||||
)
|
||||
async def test_fan_init(
|
||||
|
@ -443,7 +439,6 @@ async def test_fan_init(
|
|||
zigpy_device,
|
||||
plug_read,
|
||||
expected_state,
|
||||
expected_speed,
|
||||
expected_percentage,
|
||||
):
|
||||
"""Test zha fan platform."""
|
||||
|
@ -455,7 +450,6 @@ async def test_fan_init(
|
|||
entity_id = await find_entity_id(Platform.FAN, zha_device, hass)
|
||||
assert entity_id is not None
|
||||
assert hass.states.get(entity_id).state == expected_state
|
||||
assert hass.states.get(entity_id).attributes[ATTR_SPEED] == expected_speed
|
||||
assert hass.states.get(entity_id).attributes[ATTR_PERCENTAGE] == expected_percentage
|
||||
assert hass.states.get(entity_id).attributes[ATTR_PRESET_MODE] is None
|
||||
|
||||
|
@ -474,7 +468,6 @@ async def test_fan_update_entity(
|
|||
entity_id = await find_entity_id(Platform.FAN, zha_device, hass)
|
||||
assert entity_id is not None
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
assert hass.states.get(entity_id).attributes[ATTR_SPEED] == SPEED_OFF
|
||||
assert hass.states.get(entity_id).attributes[ATTR_PERCENTAGE] == 0
|
||||
assert hass.states.get(entity_id).attributes[ATTR_PRESET_MODE] is None
|
||||
assert hass.states.get(entity_id).attributes[ATTR_PERCENTAGE_STEP] == 100 / 3
|
||||
|
@ -487,7 +480,6 @@ async def test_fan_update_entity(
|
|||
"homeassistant", "update_entity", {"entity_id": entity_id}, blocking=True
|
||||
)
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
assert hass.states.get(entity_id).attributes[ATTR_SPEED] == SPEED_OFF
|
||||
assert cluster.read_attributes.await_count == 3
|
||||
|
||||
cluster.PLUGGED_ATTR_READS = {"fan_mode": 1}
|
||||
|
@ -496,7 +488,6 @@ async def test_fan_update_entity(
|
|||
)
|
||||
assert hass.states.get(entity_id).state == STATE_ON
|
||||
assert hass.states.get(entity_id).attributes[ATTR_PERCENTAGE] == 33
|
||||
assert hass.states.get(entity_id).attributes[ATTR_SPEED] == SPEED_LOW
|
||||
assert hass.states.get(entity_id).attributes[ATTR_PRESET_MODE] is None
|
||||
assert hass.states.get(entity_id).attributes[ATTR_PERCENTAGE_STEP] == 100 / 3
|
||||
assert cluster.read_attributes.await_count == 4
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
"""Test Z-Wave fans."""
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.fan import (
|
||||
SPEED_HIGH,
|
||||
SPEED_LOW,
|
||||
SPEED_MEDIUM,
|
||||
SPEED_OFF,
|
||||
SUPPORT_SET_SPEED,
|
||||
)
|
||||
from homeassistant.components.fan import SUPPORT_SET_SPEED
|
||||
from homeassistant.components.zwave import fan
|
||||
|
||||
from tests.mock.zwave import MockEntityValues, MockNode, MockValue, value_changed
|
||||
from tests.mock.zwave import MockEntityValues, MockNode, MockValue
|
||||
|
||||
# Integration is disabled
|
||||
pytest.skip("Integration has been disabled in the manifest", allow_module_level=True)
|
||||
|
@ -25,7 +19,6 @@ def test_get_device_detects_fan(mock_openzwave):
|
|||
device = fan.get_device(node=node, values=values, node_config={})
|
||||
assert isinstance(device, fan.ZwaveFan)
|
||||
assert device.supported_features == SUPPORT_SET_SPEED
|
||||
assert device.speed_list == [SPEED_OFF, SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH]
|
||||
|
||||
|
||||
def test_fan_turn_on(mock_openzwave):
|
||||
|
@ -96,31 +89,3 @@ def test_fan_turn_off(mock_openzwave):
|
|||
value_id, brightness = node.set_dimmer.mock_calls[0][1]
|
||||
assert value_id == value.value_id
|
||||
assert brightness == 0
|
||||
|
||||
|
||||
def test_fan_value_changed(mock_openzwave):
|
||||
"""Test value changed for zwave fan."""
|
||||
node = MockNode()
|
||||
value = MockValue(data=0, node=node)
|
||||
values = MockEntityValues(primary=value)
|
||||
device = fan.get_device(node=node, values=values, node_config={})
|
||||
|
||||
assert not device.is_on
|
||||
|
||||
value.data = 10
|
||||
value_changed(value)
|
||||
|
||||
assert device.is_on
|
||||
assert device.speed == SPEED_LOW
|
||||
|
||||
value.data = 50
|
||||
value_changed(value)
|
||||
|
||||
assert device.is_on
|
||||
assert device.speed == SPEED_MEDIUM
|
||||
|
||||
value.data = 90
|
||||
value_changed(value)
|
||||
|
||||
assert device.is_on
|
||||
assert device.speed == SPEED_HIGH
|
||||
|
|
|
@ -2,14 +2,10 @@
|
|||
import math
|
||||
|
||||
import pytest
|
||||
from voluptuous.error import MultipleInvalid
|
||||
from zwave_js_server.event import Event
|
||||
|
||||
from homeassistant.components.fan import (
|
||||
ATTR_PERCENTAGE,
|
||||
ATTR_PERCENTAGE_STEP,
|
||||
ATTR_SPEED,
|
||||
SPEED_MEDIUM,
|
||||
)
|
||||
from homeassistant.components.fan import ATTR_PERCENTAGE, ATTR_PERCENTAGE_STEP
|
||||
|
||||
|
||||
async def test_generic_fan(hass, client, fan_generic, integration):
|
||||
|
@ -25,7 +21,7 @@ async def test_generic_fan(hass, client, fan_generic, integration):
|
|||
await hass.services.async_call(
|
||||
"fan",
|
||||
"turn_on",
|
||||
{"entity_id": entity_id, "speed": SPEED_MEDIUM},
|
||||
{"entity_id": entity_id, "percentage": 66},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
@ -54,11 +50,11 @@ async def test_generic_fan(hass, client, fan_generic, integration):
|
|||
client.async_send_command.reset_mock()
|
||||
|
||||
# Test setting unknown speed
|
||||
with pytest.raises(ValueError):
|
||||
with pytest.raises(MultipleInvalid):
|
||||
await hass.services.async_call(
|
||||
"fan",
|
||||
"set_speed",
|
||||
{"entity_id": entity_id, "speed": 99},
|
||||
"set_percentage",
|
||||
{"entity_id": entity_id, "percentage": "bad"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
|
@ -150,7 +146,7 @@ async def test_generic_fan(hass, client, fan_generic, integration):
|
|||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == "on"
|
||||
assert state.attributes[ATTR_SPEED] == "high"
|
||||
assert state.attributes[ATTR_PERCENTAGE] == 100
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
|
||||
|
@ -175,7 +171,7 @@ async def test_generic_fan(hass, client, fan_generic, integration):
|
|||
|
||||
state = hass.states.get(entity_id)
|
||||
assert state.state == "off"
|
||||
assert state.attributes[ATTR_SPEED] == "off"
|
||||
assert state.attributes[ATTR_PERCENTAGE] == 0
|
||||
|
||||
|
||||
async def test_configurable_speeds_fan(hass, client, hs_fc200, integration):
|
||||
|
|
Loading…
Reference in New Issue