Update bond to use new fan entity model (#45534)
This commit is contained in:
parent
0693d8a064
commit
85e463d507
2 changed files with 87 additions and 45 deletions
|
@ -1,17 +1,13 @@
|
|||
"""Support for Bond fans."""
|
||||
import logging
|
||||
import math
|
||||
from typing import Any, Callable, List, Optional
|
||||
from typing import Any, Callable, List, Optional, Tuple
|
||||
|
||||
from bond_api import Action, DeviceType, Direction
|
||||
|
||||
from homeassistant.components.fan import (
|
||||
DIRECTION_FORWARD,
|
||||
DIRECTION_REVERSE,
|
||||
SPEED_HIGH,
|
||||
SPEED_LOW,
|
||||
SPEED_MEDIUM,
|
||||
SPEED_OFF,
|
||||
SUPPORT_DIRECTION,
|
||||
SUPPORT_SET_SPEED,
|
||||
FanEntity,
|
||||
|
@ -19,6 +15,10 @@ from homeassistant.components.fan import (
|
|||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.util.percentage import (
|
||||
percentage_to_ranged_value,
|
||||
ranged_value_to_percentage,
|
||||
)
|
||||
|
||||
from .const import DOMAIN
|
||||
from .entity import BondEntity
|
||||
|
@ -70,22 +70,16 @@ class BondFan(BondEntity, FanEntity):
|
|||
return features
|
||||
|
||||
@property
|
||||
def speed(self) -> Optional[str]:
|
||||
"""Return the current speed."""
|
||||
if self._power == 0:
|
||||
return SPEED_OFF
|
||||
if not self._power or not self._speed:
|
||||
return None
|
||||
|
||||
# map 1..max_speed Bond speed to 1..3 HA speed
|
||||
max_speed = max(self._device.props.get("max_speed", 3), self._speed)
|
||||
ha_speed = math.ceil(self._speed * (len(self.speed_list) - 1) / max_speed)
|
||||
return self.speed_list[ha_speed]
|
||||
def _speed_range(self) -> Tuple[int, int]:
|
||||
"""Return the range of speeds."""
|
||||
return (1, self._device.props.get("max_speed", 3))
|
||||
|
||||
@property
|
||||
def speed_list(self) -> list:
|
||||
"""Get the list of available speeds."""
|
||||
return [SPEED_OFF, SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH]
|
||||
def percentage(self) -> Optional[str]:
|
||||
"""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)
|
||||
|
||||
@property
|
||||
def current_direction(self) -> Optional[str]:
|
||||
|
@ -98,33 +92,27 @@ class BondFan(BondEntity, FanEntity):
|
|||
|
||||
return direction
|
||||
|
||||
async def async_set_speed(self, speed: str) -> None:
|
||||
async def async_set_percentage(self, percentage: int) -> None:
|
||||
"""Set the desired speed for the fan."""
|
||||
_LOGGER.debug("async_set_speed called with speed %s", speed)
|
||||
_LOGGER.debug("async_set_percentage called with percentage %s", percentage)
|
||||
|
||||
if speed == SPEED_OFF:
|
||||
if percentage == 0:
|
||||
await self.async_turn_off()
|
||||
return
|
||||
|
||||
max_speed = self._device.props.get("max_speed", 3)
|
||||
if speed == SPEED_LOW:
|
||||
bond_speed = 1
|
||||
elif speed == SPEED_HIGH:
|
||||
bond_speed = max_speed
|
||||
else:
|
||||
bond_speed = math.ceil(max_speed / 2)
|
||||
bond_speed = math.ceil(
|
||||
percentage_to_ranged_value(self._speed_range, percentage)
|
||||
)
|
||||
_LOGGER.debug(
|
||||
"async_set_percentage converted percentage %s to bond speed %s",
|
||||
percentage,
|
||||
bond_speed,
|
||||
)
|
||||
|
||||
await self._hub.bond.action(
|
||||
self._device.device_id, Action.set_speed(bond_speed)
|
||||
)
|
||||
|
||||
#
|
||||
# The fan entity model has changed to use percentages and preset_modes
|
||||
# instead of speeds.
|
||||
#
|
||||
# Please review
|
||||
# https://developers.home-assistant.io/docs/core/entity/fan/
|
||||
#
|
||||
async def async_turn_on(
|
||||
self,
|
||||
speed: Optional[str] = None,
|
||||
|
@ -133,13 +121,10 @@ class BondFan(BondEntity, FanEntity):
|
|||
**kwargs,
|
||||
) -> None:
|
||||
"""Turn on the fan."""
|
||||
_LOGGER.debug("Fan async_turn_on called with speed %s", speed)
|
||||
_LOGGER.debug("Fan async_turn_on called with percentage %s", percentage)
|
||||
|
||||
if speed is not None:
|
||||
if speed == SPEED_OFF:
|
||||
await self.async_turn_off()
|
||||
else:
|
||||
await self.async_set_speed(speed)
|
||||
if percentage is not None:
|
||||
await self.async_set_percentage(percentage)
|
||||
else:
|
||||
await self._hub.bond.action(self._device.device_id, Action.turn_on())
|
||||
|
||||
|
|
|
@ -41,12 +41,17 @@ def ceiling_fan(name: str):
|
|||
|
||||
|
||||
async def turn_fan_on(
|
||||
hass: core.HomeAssistant, fan_id: str, speed: Optional[str] = None
|
||||
hass: core.HomeAssistant,
|
||||
fan_id: str,
|
||||
speed: Optional[str] = None,
|
||||
percentage: Optional[int] = None,
|
||||
) -> None:
|
||||
"""Turn the fan on at the specified speed."""
|
||||
service_data = {ATTR_ENTITY_ID: fan_id}
|
||||
if speed:
|
||||
service_data[fan.ATTR_SPEED] = speed
|
||||
if percentage:
|
||||
service_data[fan.ATTR_PERCENTAGE] = percentage
|
||||
await hass.services.async_call(
|
||||
FAN_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
|
@ -93,13 +98,13 @@ async def test_non_standard_speed_list(hass: core.HomeAssistant):
|
|||
with patch_bond_action() as mock_set_speed_low:
|
||||
await turn_fan_on(hass, "fan.name_1", fan.SPEED_LOW)
|
||||
mock_set_speed_low.assert_called_once_with(
|
||||
"test-device-id", Action.set_speed(1)
|
||||
"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)
|
||||
mock_set_speed_medium.assert_called_once_with(
|
||||
"test-device-id", Action.set_speed(3)
|
||||
"test-device-id", Action.set_speed(4)
|
||||
)
|
||||
|
||||
with patch_bond_action() as mock_set_speed_high:
|
||||
|
@ -135,6 +140,58 @@ async def test_turn_on_fan_with_speed(hass: core.HomeAssistant):
|
|||
mock_set_speed.assert_called_with("test-device-id", Action.set_speed(1))
|
||||
|
||||
|
||||
async def test_turn_on_fan_with_percentage_3_speeds(hass: core.HomeAssistant):
|
||||
"""Tests that turn on command delegates to set speed API."""
|
||||
await setup_platform(
|
||||
hass, FAN_DOMAIN, ceiling_fan("name-1"), bond_device_id="test-device-id"
|
||||
)
|
||||
|
||||
with patch_bond_action() as mock_set_speed, patch_bond_device_state():
|
||||
await turn_fan_on(hass, "fan.name_1", percentage=10)
|
||||
|
||||
mock_set_speed.assert_called_with("test-device-id", Action.set_speed(1))
|
||||
|
||||
mock_set_speed.reset_mock()
|
||||
with patch_bond_action() as mock_set_speed, patch_bond_device_state():
|
||||
await turn_fan_on(hass, "fan.name_1", percentage=50)
|
||||
|
||||
mock_set_speed.assert_called_with("test-device-id", Action.set_speed(2))
|
||||
|
||||
mock_set_speed.reset_mock()
|
||||
with patch_bond_action() as mock_set_speed, patch_bond_device_state():
|
||||
await turn_fan_on(hass, "fan.name_1", percentage=100)
|
||||
|
||||
mock_set_speed.assert_called_with("test-device-id", Action.set_speed(3))
|
||||
|
||||
|
||||
async def test_turn_on_fan_with_percentage_6_speeds(hass: core.HomeAssistant):
|
||||
"""Tests that turn on command delegates to set speed API."""
|
||||
await setup_platform(
|
||||
hass,
|
||||
FAN_DOMAIN,
|
||||
ceiling_fan("name-1"),
|
||||
bond_device_id="test-device-id",
|
||||
props={"max_speed": 6},
|
||||
)
|
||||
|
||||
with patch_bond_action() as mock_set_speed, patch_bond_device_state():
|
||||
await turn_fan_on(hass, "fan.name_1", percentage=10)
|
||||
|
||||
mock_set_speed.assert_called_with("test-device-id", Action.set_speed(1))
|
||||
|
||||
mock_set_speed.reset_mock()
|
||||
with patch_bond_action() as mock_set_speed, patch_bond_device_state():
|
||||
await turn_fan_on(hass, "fan.name_1", percentage=50)
|
||||
|
||||
mock_set_speed.assert_called_with("test-device-id", Action.set_speed(3))
|
||||
|
||||
mock_set_speed.reset_mock()
|
||||
with patch_bond_action() as mock_set_speed, patch_bond_device_state():
|
||||
await turn_fan_on(hass, "fan.name_1", percentage=100)
|
||||
|
||||
mock_set_speed.assert_called_with("test-device-id", Action.set_speed(6))
|
||||
|
||||
|
||||
async def test_turn_on_fan_without_speed(hass: core.HomeAssistant):
|
||||
"""Tests that turn on command delegates to turn on API."""
|
||||
await setup_platform(
|
||||
|
|
Loading…
Add table
Reference in a new issue