314 lines
8.6 KiB
Python
314 lines
8.6 KiB
Python
"""Test Matter lights."""
|
|
from unittest.mock import MagicMock, call
|
|
|
|
from chip.clusters import Objects as clusters
|
|
import pytest
|
|
|
|
from homeassistant.components.light import ColorMode
|
|
from homeassistant.core import HomeAssistant
|
|
|
|
from .common import (
|
|
set_node_attribute,
|
|
setup_integration_with_node_fixture,
|
|
trigger_subscription_callback,
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("fixture", "entity_id"),
|
|
[
|
|
("extended-color-light", "light.mock_extended_color_light"),
|
|
("color-temperature-light", "light.mock_color_temperature_light"),
|
|
("dimmable-light", "light.mock_dimmable_light"),
|
|
("onoff-light", "light.mock_onoff_light"),
|
|
],
|
|
)
|
|
async def test_on_off_light(
|
|
hass: HomeAssistant,
|
|
matter_client: MagicMock,
|
|
fixture: str,
|
|
entity_id: str,
|
|
) -> None:
|
|
"""Test an on/off light."""
|
|
|
|
light_node = await setup_integration_with_node_fixture(
|
|
hass,
|
|
fixture,
|
|
matter_client,
|
|
)
|
|
|
|
# Test that the light is off
|
|
set_node_attribute(light_node, 1, 6, 0, False)
|
|
await trigger_subscription_callback(hass, matter_client)
|
|
|
|
state = hass.states.get(entity_id)
|
|
assert state is not None
|
|
assert state.state == "off"
|
|
|
|
# Test that the light is on
|
|
set_node_attribute(light_node, 1, 6, 0, True)
|
|
await trigger_subscription_callback(hass, matter_client)
|
|
|
|
state = hass.states.get(entity_id)
|
|
assert state is not None
|
|
assert state.state == "on"
|
|
|
|
# Turn the light off
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_off",
|
|
{
|
|
"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=light_node.node_id,
|
|
endpoint=1,
|
|
command=clusters.OnOff.Commands.Off(),
|
|
)
|
|
matter_client.send_device_command.reset_mock()
|
|
|
|
# Turn the light on
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{
|
|
"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=light_node.node_id,
|
|
endpoint=1,
|
|
command=clusters.OnOff.Commands.On(),
|
|
)
|
|
matter_client.send_device_command.reset_mock()
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("fixture", "entity_id"),
|
|
[
|
|
("extended-color-light", "light.mock_extended_color_light"),
|
|
("color-temperature-light", "light.mock_color_temperature_light"),
|
|
("dimmable-light", "light.mock_dimmable_light"),
|
|
],
|
|
)
|
|
async def test_dimmable_light(
|
|
hass: HomeAssistant,
|
|
matter_client: MagicMock,
|
|
fixture: str,
|
|
entity_id: str,
|
|
) -> None:
|
|
"""Test a dimmable light."""
|
|
|
|
light_node = await setup_integration_with_node_fixture(
|
|
hass,
|
|
fixture,
|
|
matter_client,
|
|
)
|
|
|
|
# Test that the light brightness is 50 (out of 254)
|
|
set_node_attribute(light_node, 1, 8, 0, 50)
|
|
await trigger_subscription_callback(hass, matter_client)
|
|
|
|
state = hass.states.get(entity_id)
|
|
assert state is not None
|
|
assert state.state == "on"
|
|
assert state.attributes["brightness"] == 49
|
|
|
|
# Change brightness
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{
|
|
"entity_id": entity_id,
|
|
"brightness": 128,
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
assert matter_client.send_device_command.call_count == 1
|
|
assert matter_client.send_device_command.call_args == call(
|
|
node_id=light_node.node_id,
|
|
endpoint=1,
|
|
command=clusters.LevelControl.Commands.MoveToLevelWithOnOff(
|
|
level=128,
|
|
transitionTime=0,
|
|
),
|
|
)
|
|
matter_client.send_device_command.reset_mock()
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("fixture", "entity_id"),
|
|
[
|
|
("extended-color-light", "light.mock_extended_color_light"),
|
|
("color-temperature-light", "light.mock_color_temperature_light"),
|
|
],
|
|
)
|
|
async def test_color_temperature_light(
|
|
hass: HomeAssistant,
|
|
matter_client: MagicMock,
|
|
fixture: str,
|
|
entity_id: str,
|
|
) -> None:
|
|
"""Test a color temperature light."""
|
|
|
|
light_node = await setup_integration_with_node_fixture(
|
|
hass,
|
|
fixture,
|
|
matter_client,
|
|
)
|
|
|
|
# Test that the light color temperature is 3000 (out of 50000)
|
|
set_node_attribute(light_node, 1, 768, 8, 2)
|
|
set_node_attribute(light_node, 1, 768, 7, 3000)
|
|
await trigger_subscription_callback(hass, matter_client)
|
|
|
|
state = hass.states.get(entity_id)
|
|
assert state is not None
|
|
assert state.state == "on"
|
|
assert state.attributes["color_mode"] == ColorMode.COLOR_TEMP
|
|
assert state.attributes["color_temp"] == 3003
|
|
|
|
# Change color temperature
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{
|
|
"entity_id": entity_id,
|
|
"color_temp": 3000,
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
assert matter_client.send_device_command.call_count == 2
|
|
matter_client.send_device_command.assert_has_calls(
|
|
[
|
|
call(
|
|
node_id=light_node.node_id,
|
|
endpoint=1,
|
|
command=clusters.ColorControl.Commands.MoveToColorTemperature(
|
|
colorTemperature=3003,
|
|
transitionTime=0,
|
|
),
|
|
),
|
|
call(
|
|
node_id=light_node.node_id,
|
|
endpoint=1,
|
|
command=clusters.OnOff.Commands.On(),
|
|
),
|
|
]
|
|
)
|
|
matter_client.send_device_command.reset_mock()
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("fixture", "entity_id"),
|
|
[
|
|
("extended-color-light", "light.mock_extended_color_light"),
|
|
],
|
|
)
|
|
async def test_extended_color_light(
|
|
hass: HomeAssistant,
|
|
matter_client: MagicMock,
|
|
fixture: str,
|
|
entity_id: str,
|
|
) -> None:
|
|
"""Test an extended color light."""
|
|
|
|
light_node = await setup_integration_with_node_fixture(
|
|
hass,
|
|
fixture,
|
|
matter_client,
|
|
)
|
|
|
|
# Test that the XY color changes
|
|
set_node_attribute(light_node, 1, 768, 8, 1)
|
|
set_node_attribute(light_node, 1, 768, 3, 50)
|
|
set_node_attribute(light_node, 1, 768, 4, 100)
|
|
await trigger_subscription_callback(hass, matter_client)
|
|
|
|
state = hass.states.get(entity_id)
|
|
assert state is not None
|
|
assert state.state == "on"
|
|
assert state.attributes["color_mode"] == ColorMode.XY
|
|
assert state.attributes["xy_color"] == (0.0007630, 0.001526)
|
|
|
|
# Test that the HS color changes
|
|
set_node_attribute(light_node, 1, 768, 8, 0)
|
|
set_node_attribute(light_node, 1, 768, 1, 50)
|
|
set_node_attribute(light_node, 1, 768, 0, 100)
|
|
await trigger_subscription_callback(hass, matter_client)
|
|
|
|
state = hass.states.get(entity_id)
|
|
assert state is not None
|
|
assert state.state == "on"
|
|
assert state.attributes["color_mode"] == ColorMode.HS
|
|
assert state.attributes["hs_color"] == (141.732, 19.685)
|
|
|
|
# Turn the light on with XY color
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{
|
|
"entity_id": entity_id,
|
|
"xy_color": (0.5, 0.5),
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
assert matter_client.send_device_command.call_count == 2
|
|
matter_client.send_device_command.assert_has_calls(
|
|
[
|
|
call(
|
|
node_id=light_node.node_id,
|
|
endpoint=1,
|
|
command=clusters.ColorControl.Commands.MoveToColor(
|
|
colorX=0.5 * 65536, colorY=0.5 * 65536, transitionTime=0
|
|
),
|
|
),
|
|
call(
|
|
node_id=light_node.node_id,
|
|
endpoint=1,
|
|
command=clusters.OnOff.Commands.On(),
|
|
),
|
|
]
|
|
)
|
|
matter_client.send_device_command.reset_mock()
|
|
|
|
# Turn the light on with HS color
|
|
await hass.services.async_call(
|
|
"light",
|
|
"turn_on",
|
|
{
|
|
"entity_id": entity_id,
|
|
"hs_color": (0, 0),
|
|
},
|
|
blocking=True,
|
|
)
|
|
|
|
assert matter_client.send_device_command.call_count == 2
|
|
matter_client.send_device_command.assert_has_calls(
|
|
[
|
|
call(
|
|
node_id=light_node.node_id,
|
|
endpoint=1,
|
|
command=clusters.ColorControl.Commands.MoveToHueAndSaturation(
|
|
hue=0, saturation=0, transitionTime=0
|
|
),
|
|
),
|
|
call(
|
|
node_id=light_node.node_id,
|
|
endpoint=1,
|
|
command=clusters.OnOff.Commands.On(),
|
|
),
|
|
]
|
|
)
|
|
matter_client.send_device_command.reset_mock()
|