core/tests/components/matter/test_cover.py

500 lines
15 KiB
Python
Raw Normal View History

"""Test Matter covers."""
from math import floor
from unittest.mock import MagicMock, call
from chip.clusters import Objects as clusters
import pytest
from homeassistant.components.cover import (
STATE_CLOSED,
STATE_CLOSING,
STATE_OPEN,
STATE_OPENING,
CoverEntityFeature,
)
from homeassistant.core import HomeAssistant
from .common import (
set_node_attribute,
setup_integration_with_node_fixture,
trigger_subscription_callback,
)
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize(
("fixture", "entity_id"),
[
("window-covering_lift", "cover.mock_lift_window_covering"),
("window-covering_pa-lift", "cover.longan_link_wncv_da01"),
("window-covering_tilt", "cover.mock_tilt_window_covering"),
("window-covering_pa-tilt", "cover.mock_pa_tilt_window_covering"),
("window-covering_full", "cover.mock_full_window_covering"),
],
)
async def test_cover(
hass: HomeAssistant,
matter_client: MagicMock,
fixture: str,
entity_id: str,
) -> None:
"""Test window covering commands that always are implemented."""
window_covering = await setup_integration_with_node_fixture(
hass,
fixture,
matter_client,
)
await hass.services.async_call(
"cover",
"close_cover",
{
"entity_id": entity_id,
},
blocking=True,
)
assert matter_client.send_device_command.call_count == 1
assert matter_client.send_device_command.call_args == call(
node_id=window_covering.node_id,
endpoint_id=1,
command=clusters.WindowCovering.Commands.DownOrClose(),
)
matter_client.send_device_command.reset_mock()
await hass.services.async_call(
"cover",
"stop_cover",
{
"entity_id": entity_id,
},
blocking=True,
)
assert matter_client.send_device_command.call_count == 1
assert matter_client.send_device_command.call_args == call(
node_id=window_covering.node_id,
endpoint_id=1,
command=clusters.WindowCovering.Commands.StopMotion(),
)
matter_client.send_device_command.reset_mock()
await hass.services.async_call(
"cover",
"open_cover",
{
"entity_id": entity_id,
},
blocking=True,
)
assert matter_client.send_device_command.call_count == 1
assert matter_client.send_device_command.call_args == call(
node_id=window_covering.node_id,
endpoint_id=1,
command=clusters.WindowCovering.Commands.UpOrOpen(),
)
matter_client.send_device_command.reset_mock()
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize(
("fixture", "entity_id"),
[
("window-covering_lift", "cover.mock_lift_window_covering"),
("window-covering_pa-lift", "cover.longan_link_wncv_da01"),
("window-covering_full", "cover.mock_full_window_covering"),
],
)
async def test_cover_lift(
hass: HomeAssistant,
matter_client: MagicMock,
fixture: str,
entity_id: str,
) -> None:
"""Test window covering devices with lift and position aware lift features."""
window_covering = await setup_integration_with_node_fixture(
hass,
fixture,
matter_client,
)
await hass.services.async_call(
"cover",
"set_cover_position",
{
"entity_id": entity_id,
"position": 50,
},
blocking=True,
)
assert matter_client.send_device_command.call_count == 1
assert matter_client.send_device_command.call_args == call(
node_id=window_covering.node_id,
endpoint_id=1,
command=clusters.WindowCovering.Commands.GoToLiftPercentage(5000),
)
matter_client.send_device_command.reset_mock()
set_node_attribute(window_covering, 1, 258, 10, 0b001010)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_CLOSING
set_node_attribute(window_covering, 1, 258, 10, 0b000101)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_OPENING
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize(
("fixture", "entity_id"),
[
("window-covering_lift", "cover.mock_lift_window_covering"),
],
)
async def test_cover_lift_only(
hass: HomeAssistant,
matter_client: MagicMock,
fixture: str,
entity_id: str,
) -> None:
"""Test window covering devices with lift feature and without position aware lift feature."""
window_covering = await setup_integration_with_node_fixture(
hass,
fixture,
matter_client,
)
set_node_attribute(window_covering, 1, 258, 14, None)
set_node_attribute(window_covering, 1, 258, 10, 0b000000)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.state == "unknown"
set_node_attribute(window_covering, 1, 258, 65529, [0, 1, 2])
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.attributes["supported_features"] & CoverEntityFeature.SET_POSITION == 0
set_node_attribute(window_covering, 1, 258, 65529, [0, 1, 2, 5])
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.attributes["supported_features"] & CoverEntityFeature.SET_POSITION != 0
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize(
("fixture", "entity_id"),
[
("window-covering_pa-lift", "cover.longan_link_wncv_da01"),
],
)
async def test_cover_position_aware_lift(
hass: HomeAssistant,
matter_client: MagicMock,
fixture: str,
entity_id: str,
) -> None:
"""Test window covering devices with position aware lift features."""
window_covering = await setup_integration_with_node_fixture(
hass,
fixture,
matter_client,
)
state = hass.states.get(entity_id)
assert state
mask = (
CoverEntityFeature.OPEN
| CoverEntityFeature.CLOSE
| CoverEntityFeature.STOP
| CoverEntityFeature.SET_POSITION
)
assert state.attributes["supported_features"] & mask == mask
for position in (0, 9999):
set_node_attribute(window_covering, 1, 258, 14, position)
set_node_attribute(window_covering, 1, 258, 10, 0b000000)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.attributes["current_position"] == 100 - floor(position / 100)
assert state.state == STATE_OPEN
set_node_attribute(window_covering, 1, 258, 14, 10000)
set_node_attribute(window_covering, 1, 258, 10, 0b000000)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.attributes["current_position"] == 0
assert state.state == STATE_CLOSED
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize(
("fixture", "entity_id"),
[
("window-covering_tilt", "cover.mock_tilt_window_covering"),
("window-covering_pa-tilt", "cover.mock_pa_tilt_window_covering"),
("window-covering_full", "cover.mock_full_window_covering"),
],
)
async def test_cover_tilt(
hass: HomeAssistant,
matter_client: MagicMock,
fixture: str,
entity_id: str,
) -> None:
"""Test window covering devices with tilt and position aware tilt features."""
window_covering = await setup_integration_with_node_fixture(
hass,
fixture,
matter_client,
)
await hass.services.async_call(
"cover",
"set_cover_tilt_position",
{
"entity_id": entity_id,
"tilt_position": 50,
},
blocking=True,
)
assert matter_client.send_device_command.call_count == 1
assert matter_client.send_device_command.call_args == call(
node_id=window_covering.node_id,
endpoint_id=1,
command=clusters.WindowCovering.Commands.GoToTiltPercentage(5000),
)
matter_client.send_device_command.reset_mock()
await trigger_subscription_callback(hass, matter_client)
set_node_attribute(window_covering, 1, 258, 10, 0b100010)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_CLOSING
set_node_attribute(window_covering, 1, 258, 10, 0b010001)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_OPENING
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize(
("fixture", "entity_id"),
[
("window-covering_tilt", "cover.mock_tilt_window_covering"),
],
)
async def test_cover_tilt_only(
hass: HomeAssistant,
matter_client: MagicMock,
fixture: str,
entity_id: str,
) -> None:
"""Test window covering devices with tilt feature and without position aware tilt feature."""
window_covering = await setup_integration_with_node_fixture(
hass,
fixture,
matter_client,
)
set_node_attribute(window_covering, 1, 258, 65529, [0, 1, 2])
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert (
state.attributes["supported_features"] & CoverEntityFeature.SET_TILT_POSITION
== 0
)
set_node_attribute(window_covering, 1, 258, 65529, [0, 1, 2, 8])
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert (
state.attributes["supported_features"] & CoverEntityFeature.SET_TILT_POSITION
!= 0
)
# This tests needs to be adjusted to remove lingering tasks
@pytest.mark.parametrize("expected_lingering_tasks", [True])
@pytest.mark.parametrize(
("fixture", "entity_id"),
[
("window-covering_pa-tilt", "cover.mock_pa_tilt_window_covering"),
],
)
async def test_cover_position_aware_tilt(
hass: HomeAssistant,
matter_client: MagicMock,
fixture: str,
entity_id: str,
) -> None:
"""Test window covering devices with position aware tilt feature."""
window_covering = await setup_integration_with_node_fixture(
hass,
fixture,
matter_client,
)
state = hass.states.get(entity_id)
assert state
mask = (
CoverEntityFeature.OPEN
| CoverEntityFeature.CLOSE
| CoverEntityFeature.STOP
| CoverEntityFeature.SET_TILT_POSITION
)
assert state.attributes["supported_features"] & mask == mask
for tilt_position in (0, 9999, 10000):
set_node_attribute(window_covering, 1, 258, 15, tilt_position)
set_node_attribute(window_covering, 1, 258, 10, 0b000000)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.attributes["current_tilt_position"] == 100 - floor(
tilt_position / 100
)
async def test_cover_full_features(
hass: HomeAssistant,
matter_client: MagicMock,
) -> None:
"""Test window covering devices with all the features."""
window_covering = await setup_integration_with_node_fixture(
hass,
"window-covering_full",
matter_client,
)
entity_id = "cover.mock_full_window_covering"
state = hass.states.get(entity_id)
assert state
mask = (
CoverEntityFeature.OPEN
| CoverEntityFeature.CLOSE
| CoverEntityFeature.STOP
| CoverEntityFeature.SET_POSITION
| CoverEntityFeature.SET_TILT_POSITION
)
assert state.attributes["supported_features"] & mask == mask
set_node_attribute(window_covering, 1, 258, 14, 10000)
set_node_attribute(window_covering, 1, 258, 15, 10000)
set_node_attribute(window_covering, 1, 258, 10, 0b000000)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_CLOSED
set_node_attribute(window_covering, 1, 258, 14, 5000)
set_node_attribute(window_covering, 1, 258, 15, 10000)
set_node_attribute(window_covering, 1, 258, 10, 0b000000)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_OPEN
set_node_attribute(window_covering, 1, 258, 14, 10000)
set_node_attribute(window_covering, 1, 258, 15, 5000)
set_node_attribute(window_covering, 1, 258, 10, 0b000000)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_CLOSED
set_node_attribute(window_covering, 1, 258, 14, 5000)
set_node_attribute(window_covering, 1, 258, 15, 5000)
set_node_attribute(window_covering, 1, 258, 10, 0b000000)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_OPEN
set_node_attribute(window_covering, 1, 258, 14, 5000)
set_node_attribute(window_covering, 1, 258, 15, None)
set_node_attribute(window_covering, 1, 258, 10, 0b000000)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_OPEN
set_node_attribute(window_covering, 1, 258, 14, None)
set_node_attribute(window_covering, 1, 258, 15, 5000)
set_node_attribute(window_covering, 1, 258, 10, 0b000000)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.state == "unknown"
set_node_attribute(window_covering, 1, 258, 14, 10000)
set_node_attribute(window_covering, 1, 258, 15, None)
set_node_attribute(window_covering, 1, 258, 10, 0b000000)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.state == STATE_CLOSED
set_node_attribute(window_covering, 1, 258, 14, None)
set_node_attribute(window_covering, 1, 258, 15, 10000)
set_node_attribute(window_covering, 1, 258, 10, 0b000000)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.state == "unknown"
set_node_attribute(window_covering, 1, 258, 14, None)
set_node_attribute(window_covering, 1, 258, 15, None)
set_node_attribute(window_covering, 1, 258, 10, 0b000000)
await trigger_subscription_callback(hass, matter_client)
state = hass.states.get(entity_id)
assert state
assert state.state == "unknown"