Fix turn on without speed in homekit controller (#47597)

This commit is contained in:
J. Nick Koston 2021-03-08 08:43:22 -10:00 committed by GitHub
parent 32476a3fed
commit b315fcab11
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 112 additions and 1 deletions

View file

@ -80,6 +80,13 @@ class BaseHomeKitFan(HomeKitEntity, FanEntity):
return features return features
@property
def speed_count(self):
"""Speed count for the fan."""
return round(
100 / max(1, self.service[CharacteristicsTypes.ROTATION_SPEED].minStep or 0)
)
async def async_set_direction(self, direction): async def async_set_direction(self, direction):
"""Set the direction of the fan.""" """Set the direction of the fan."""
await self.async_put_characteristics( await self.async_put_characteristics(
@ -110,7 +117,7 @@ class BaseHomeKitFan(HomeKitEntity, FanEntity):
if not self.is_on: if not self.is_on:
characteristics[self.on_characteristic] = True characteristics[self.on_characteristic] = True
if self.supported_features & SUPPORT_SET_SPEED: if percentage is not None and self.supported_features & SUPPORT_SET_SPEED:
characteristics[CharacteristicsTypes.ROTATION_SPEED] = percentage characteristics[CharacteristicsTypes.ROTATION_SPEED] = percentage
if characteristics: if characteristics:

View file

@ -11,6 +11,13 @@ import homeassistant.util.dt as dt_util
from tests.components.light.conftest import mock_light_profiles # noqa: F401 from tests.components.light.conftest import mock_light_profiles # noqa: F401
@pytest.fixture(autouse=True)
def mock_zeroconf():
"""Mock zeroconf."""
with mock.patch("homeassistant.components.zeroconf.HaZeroconf") as mock_zc:
yield mock_zc.return_value
@pytest.fixture @pytest.fixture
def utcnow(request): def utcnow(request):
"""Freeze time at a known point.""" """Freeze time at a known point."""

View file

@ -50,6 +50,38 @@ def create_fanv2_service(accessory):
swing_mode.value = 0 swing_mode.value = 0
def create_fanv2_service_with_min_step(accessory):
"""Define fan v2 characteristics as per HAP spec."""
service = accessory.add_service(ServicesTypes.FAN_V2)
cur_state = service.add_char(CharacteristicsTypes.ACTIVE)
cur_state.value = 0
direction = service.add_char(CharacteristicsTypes.ROTATION_DIRECTION)
direction.value = 0
speed = service.add_char(CharacteristicsTypes.ROTATION_SPEED)
speed.value = 0
speed.minStep = 25
swing_mode = service.add_char(CharacteristicsTypes.SWING_MODE)
swing_mode.value = 0
def create_fanv2_service_without_rotation_speed(accessory):
"""Define fan v2 characteristics as per HAP spec."""
service = accessory.add_service(ServicesTypes.FAN_V2)
cur_state = service.add_char(CharacteristicsTypes.ACTIVE)
cur_state.value = 0
direction = service.add_char(CharacteristicsTypes.ROTATION_DIRECTION)
direction.value = 0
swing_mode = service.add_char(CharacteristicsTypes.SWING_MODE)
swing_mode.value = 0
async def test_fan_read_state(hass, utcnow): async def test_fan_read_state(hass, utcnow):
"""Test that we can read the state of a HomeKit fan accessory.""" """Test that we can read the state of a HomeKit fan accessory."""
helper = await setup_test_component(hass, create_fan_service) helper = await setup_test_component(hass, create_fan_service)
@ -95,6 +127,29 @@ async def test_turn_on(hass, utcnow):
assert helper.characteristics[V1_ROTATION_SPEED].value == 33.0 assert helper.characteristics[V1_ROTATION_SPEED].value == 33.0
async def test_turn_on_off_without_rotation_speed(hass, utcnow):
"""Test that we can turn a fan on."""
helper = await setup_test_component(
hass, create_fanv2_service_without_rotation_speed
)
await hass.services.async_call(
"fan",
"turn_on",
{"entity_id": "fan.testdevice"},
blocking=True,
)
assert helper.characteristics[V2_ACTIVE].value == 1
await hass.services.async_call(
"fan",
"turn_off",
{"entity_id": "fan.testdevice"},
blocking=True,
)
assert helper.characteristics[V2_ACTIVE].value == 0
async def test_turn_off(hass, utcnow): async def test_turn_off(hass, utcnow):
"""Test that we can turn a fan off.""" """Test that we can turn a fan off."""
helper = await setup_test_component(hass, create_fan_service) helper = await setup_test_component(hass, create_fan_service)
@ -181,6 +236,7 @@ async def test_speed_read(hass, utcnow):
state = await helper.poll_and_get_state() state = await helper.poll_and_get_state()
assert state.attributes["speed"] == "high" assert state.attributes["speed"] == "high"
assert state.attributes["percentage"] == 100 assert state.attributes["percentage"] == 100
assert state.attributes["percentage_step"] == 1.0
helper.characteristics[V1_ROTATION_SPEED].value = 50 helper.characteristics[V1_ROTATION_SPEED].value = 50
state = await helper.poll_and_get_state() state = await helper.poll_and_get_state()
@ -277,6 +333,24 @@ async def test_v2_turn_on(hass, utcnow):
assert helper.characteristics[V2_ACTIVE].value == 1 assert helper.characteristics[V2_ACTIVE].value == 1
assert helper.characteristics[V2_ROTATION_SPEED].value == 33.0 assert helper.characteristics[V2_ROTATION_SPEED].value == 33.0
await hass.services.async_call(
"fan",
"turn_off",
{"entity_id": "fan.testdevice"},
blocking=True,
)
assert helper.characteristics[V2_ACTIVE].value == 0
assert helper.characteristics[V2_ROTATION_SPEED].value == 33.0
await hass.services.async_call(
"fan",
"turn_on",
{"entity_id": "fan.testdevice"},
blocking=True,
)
assert helper.characteristics[V2_ACTIVE].value == 1
assert helper.characteristics[V2_ROTATION_SPEED].value == 33.0
async def test_v2_turn_off(hass, utcnow): async def test_v2_turn_off(hass, utcnow):
"""Test that we can turn a fan off.""" """Test that we can turn a fan off."""
@ -355,6 +429,29 @@ async def test_v2_set_percentage(hass, utcnow):
assert helper.characteristics[V2_ACTIVE].value == 0 assert helper.characteristics[V2_ACTIVE].value == 0
async def test_v2_set_percentage_with_min_step(hass, utcnow):
"""Test that we set fan speed by percentage."""
helper = await setup_test_component(hass, create_fanv2_service_with_min_step)
helper.characteristics[V2_ACTIVE].value = 1
await hass.services.async_call(
"fan",
"set_percentage",
{"entity_id": "fan.testdevice", "percentage": 66},
blocking=True,
)
assert helper.characteristics[V2_ROTATION_SPEED].value == 75
await hass.services.async_call(
"fan",
"set_percentage",
{"entity_id": "fan.testdevice", "percentage": 0},
blocking=True,
)
assert helper.characteristics[V2_ACTIVE].value == 0
async def test_v2_speed_read(hass, utcnow): async def test_v2_speed_read(hass, utcnow):
"""Test that we can read a fans oscillation.""" """Test that we can read a fans oscillation."""
helper = await setup_test_component(hass, create_fanv2_service) helper = await setup_test_component(hass, create_fanv2_service)