mirror of
https://github.com/home-assistant/core.git
synced 2025-07-09 22:37:11 +00:00
Fix matter color temperature light (#87677)
* Adds tests for each matter light type and fixes small issue with color temperature lights not being detected properly * Removes commented out code * Changed matter light tests to pytest.mark.parametrize to reduce duplicate code
This commit is contained in:
parent
1a7c99382c
commit
1c02f19d9a
@ -421,6 +421,7 @@ DEVICE_ENTITY: dict[
|
||||
subscribe_attributes=(
|
||||
clusters.OnOff.Attributes.OnOff,
|
||||
clusters.LevelControl.Attributes.CurrentLevel,
|
||||
clusters.ColorControl.Attributes.ColorMode,
|
||||
clusters.ColorControl.Attributes.ColorTemperatureMireds,
|
||||
),
|
||||
),
|
||||
|
2110
tests/components/matter/fixtures/nodes/color-temperature-light.json
Normal file
2110
tests/components/matter/fixtures/nodes/color-temperature-light.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,9 +2,9 @@
|
||||
from unittest.mock import MagicMock, call
|
||||
|
||||
from chip.clusters import Objects as clusters
|
||||
from matter_server.common.models.node import MatterNode
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.light import ColorMode
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .common import (
|
||||
@ -14,29 +14,69 @@ from .common import (
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(name="light_node")
|
||||
async def light_node_fixture(
|
||||
hass: HomeAssistant, matter_client: MagicMock
|
||||
) -> MatterNode:
|
||||
"""Fixture for a light node."""
|
||||
return await setup_integration_with_node_fixture(
|
||||
hass, "extended-color-light", matter_client
|
||||
)
|
||||
|
||||
|
||||
async def test_turn_on(
|
||||
@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,
|
||||
light_node: MatterNode,
|
||||
fixture: str,
|
||||
entity_id: str,
|
||||
) -> None:
|
||||
"""Test turning on a light."""
|
||||
"""Test an on/off light."""
|
||||
|
||||
# OnOff test
|
||||
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": "light.mock_extended_color_light",
|
||||
"entity_id": entity_id,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
@ -49,12 +89,44 @@ async def test_turn_on(
|
||||
)
|
||||
matter_client.send_device_command.reset_mock()
|
||||
|
||||
# Brightness test
|
||||
|
||||
@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": "light.mock_extended_color_light",
|
||||
"entity_id": entity_id,
|
||||
"brightness": 128,
|
||||
},
|
||||
blocking=True,
|
||||
@ -71,77 +143,46 @@ async def test_turn_on(
|
||||
)
|
||||
matter_client.send_device_command.reset_mock()
|
||||
|
||||
# HS Color test
|
||||
|
||||
@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": "light.mock_extended_color_light",
|
||||
"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()
|
||||
|
||||
# XY Color test
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{
|
||||
"entity_id": "light.mock_extended_color_light",
|
||||
"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()
|
||||
|
||||
# Color Temperature test
|
||||
await hass.services.async_call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{
|
||||
"entity_id": "light.mock_extended_color_light",
|
||||
"color_temp": 300,
|
||||
"entity_id": entity_id,
|
||||
"color_temp": 3000,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
@ -153,7 +194,7 @@ async def test_turn_on(
|
||||
node_id=light_node.node_id,
|
||||
endpoint=1,
|
||||
command=clusters.ColorControl.Commands.MoveToColorTemperature(
|
||||
colorTemperature=300,
|
||||
colorTemperature=3003,
|
||||
transitionTime=0,
|
||||
),
|
||||
),
|
||||
@ -166,81 +207,107 @@ async def test_turn_on(
|
||||
)
|
||||
matter_client.send_device_command.reset_mock()
|
||||
|
||||
state = hass.states.get("light.mock_extended_color_light")
|
||||
assert state
|
||||
assert state.state == "on"
|
||||
|
||||
# HS Color Test
|
||||
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)
|
||||
@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."""
|
||||
|
||||
state = hass.states.get("light.mock_extended_color_light")
|
||||
assert state
|
||||
assert state.attributes["color_mode"] == "hs"
|
||||
assert state.attributes["hs_color"] == (141.732, 19.685)
|
||||
light_node = await setup_integration_with_node_fixture(
|
||||
hass,
|
||||
fixture,
|
||||
matter_client,
|
||||
)
|
||||
|
||||
# XY Color Test
|
||||
# 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("light.mock_extended_color_light")
|
||||
assert state
|
||||
assert state.attributes["color_mode"] == "xy"
|
||||
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)
|
||||
|
||||
# Color Temperature Test
|
||||
set_node_attribute(light_node, 1, 768, 8, 2)
|
||||
set_node_attribute(light_node, 1, 768, 7, 100)
|
||||
# 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("light.mock_extended_color_light")
|
||||
assert state
|
||||
assert state.attributes["color_mode"] == "color_temp"
|
||||
assert state.attributes["color_temp"] == 100
|
||||
|
||||
# Brightness state test
|
||||
set_node_attribute(light_node, 1, 8, 0, 50)
|
||||
await trigger_subscription_callback(hass, matter_client)
|
||||
|
||||
state = hass.states.get("light.mock_extended_color_light")
|
||||
assert state
|
||||
assert state.attributes["brightness"] == 49
|
||||
|
||||
# Off state test
|
||||
set_node_attribute(light_node, 1, 6, 0, False)
|
||||
await trigger_subscription_callback(hass, matter_client)
|
||||
|
||||
state = hass.states.get("light.mock_extended_color_light")
|
||||
assert state
|
||||
assert state.state == "off"
|
||||
|
||||
|
||||
async def test_turn_off(
|
||||
hass: HomeAssistant,
|
||||
matter_client: MagicMock,
|
||||
light_node: MatterNode,
|
||||
) -> None:
|
||||
"""Test turning off a light."""
|
||||
state = hass.states.get("light.mock_extended_color_light")
|
||||
assert state
|
||||
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_off",
|
||||
"turn_on",
|
||||
{
|
||||
"entity_id": "light.mock_extended_color_light",
|
||||
"entity_id": entity_id,
|
||||
"xy_color": (0.5, 0.5),
|
||||
},
|
||||
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(),
|
||||
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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user