mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 04:07:08 +00:00
Update bond to use new fan entity model (#45534)
This commit is contained in:
parent
0693d8a064
commit
85e463d507
@ -1,17 +1,13 @@
|
|||||||
"""Support for Bond fans."""
|
"""Support for Bond fans."""
|
||||||
import logging
|
import logging
|
||||||
import math
|
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 bond_api import Action, DeviceType, Direction
|
||||||
|
|
||||||
from homeassistant.components.fan import (
|
from homeassistant.components.fan import (
|
||||||
DIRECTION_FORWARD,
|
DIRECTION_FORWARD,
|
||||||
DIRECTION_REVERSE,
|
DIRECTION_REVERSE,
|
||||||
SPEED_HIGH,
|
|
||||||
SPEED_LOW,
|
|
||||||
SPEED_MEDIUM,
|
|
||||||
SPEED_OFF,
|
|
||||||
SUPPORT_DIRECTION,
|
SUPPORT_DIRECTION,
|
||||||
SUPPORT_SET_SPEED,
|
SUPPORT_SET_SPEED,
|
||||||
FanEntity,
|
FanEntity,
|
||||||
@ -19,6 +15,10 @@ from homeassistant.components.fan import (
|
|||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
from homeassistant.util.percentage import (
|
||||||
|
percentage_to_ranged_value,
|
||||||
|
ranged_value_to_percentage,
|
||||||
|
)
|
||||||
|
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .entity import BondEntity
|
from .entity import BondEntity
|
||||||
@ -70,22 +70,16 @@ class BondFan(BondEntity, FanEntity):
|
|||||||
return features
|
return features
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def speed(self) -> Optional[str]:
|
def _speed_range(self) -> Tuple[int, int]:
|
||||||
"""Return the current speed."""
|
"""Return the range of speeds."""
|
||||||
if self._power == 0:
|
return (1, self._device.props.get("max_speed", 3))
|
||||||
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]
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def speed_list(self) -> list:
|
def percentage(self) -> Optional[str]:
|
||||||
"""Get the list of available speeds."""
|
"""Return the current speed percentage for the fan."""
|
||||||
return [SPEED_OFF, SPEED_LOW, SPEED_MEDIUM, SPEED_HIGH]
|
if not self._speed or not self._power:
|
||||||
|
return 0
|
||||||
|
return ranged_value_to_percentage(self._speed_range, self._speed)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def current_direction(self) -> Optional[str]:
|
def current_direction(self) -> Optional[str]:
|
||||||
@ -98,33 +92,27 @@ class BondFan(BondEntity, FanEntity):
|
|||||||
|
|
||||||
return direction
|
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."""
|
"""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()
|
await self.async_turn_off()
|
||||||
return
|
return
|
||||||
|
|
||||||
max_speed = self._device.props.get("max_speed", 3)
|
bond_speed = math.ceil(
|
||||||
if speed == SPEED_LOW:
|
percentage_to_ranged_value(self._speed_range, percentage)
|
||||||
bond_speed = 1
|
)
|
||||||
elif speed == SPEED_HIGH:
|
_LOGGER.debug(
|
||||||
bond_speed = max_speed
|
"async_set_percentage converted percentage %s to bond speed %s",
|
||||||
else:
|
percentage,
|
||||||
bond_speed = math.ceil(max_speed / 2)
|
bond_speed,
|
||||||
|
)
|
||||||
|
|
||||||
await self._hub.bond.action(
|
await self._hub.bond.action(
|
||||||
self._device.device_id, Action.set_speed(bond_speed)
|
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(
|
async def async_turn_on(
|
||||||
self,
|
self,
|
||||||
speed: Optional[str] = None,
|
speed: Optional[str] = None,
|
||||||
@ -133,13 +121,10 @@ class BondFan(BondEntity, FanEntity):
|
|||||||
**kwargs,
|
**kwargs,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Turn on the fan."""
|
"""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 percentage is not None:
|
||||||
if speed == SPEED_OFF:
|
await self.async_set_percentage(percentage)
|
||||||
await self.async_turn_off()
|
|
||||||
else:
|
|
||||||
await self.async_set_speed(speed)
|
|
||||||
else:
|
else:
|
||||||
await self._hub.bond.action(self._device.device_id, Action.turn_on())
|
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(
|
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:
|
) -> None:
|
||||||
"""Turn the fan on at the specified speed."""
|
"""Turn the fan on at the specified speed."""
|
||||||
service_data = {ATTR_ENTITY_ID: fan_id}
|
service_data = {ATTR_ENTITY_ID: fan_id}
|
||||||
if speed:
|
if speed:
|
||||||
service_data[fan.ATTR_SPEED] = speed
|
service_data[fan.ATTR_SPEED] = speed
|
||||||
|
if percentage:
|
||||||
|
service_data[fan.ATTR_PERCENTAGE] = percentage
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
FAN_DOMAIN,
|
FAN_DOMAIN,
|
||||||
SERVICE_TURN_ON,
|
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:
|
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", fan.SPEED_LOW)
|
||||||
mock_set_speed_low.assert_called_once_with(
|
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:
|
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", fan.SPEED_MEDIUM)
|
||||||
mock_set_speed_medium.assert_called_once_with(
|
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:
|
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))
|
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):
|
async def test_turn_on_fan_without_speed(hass: core.HomeAssistant):
|
||||||
"""Tests that turn on command delegates to turn on API."""
|
"""Tests that turn on command delegates to turn on API."""
|
||||||
await setup_platform(
|
await setup_platform(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user