mirror of https://github.com/home-assistant/core
311 lines
7.9 KiB
Python
311 lines
7.9 KiB
Python
"""Tradfri lights platform tests."""
|
|
|
|
from typing import Any
|
|
|
|
import pytest
|
|
from pytradfri.const import ATTR_DEVICE_STATE, ATTR_LIGHT_CONTROL, ATTR_REACHABLE_STATE
|
|
from pytradfri.device import Device
|
|
|
|
from homeassistant.components.light import (
|
|
ATTR_BRIGHTNESS,
|
|
ATTR_COLOR_MODE,
|
|
ATTR_COLOR_TEMP,
|
|
ATTR_HS_COLOR,
|
|
ATTR_MAX_MIREDS,
|
|
ATTR_MIN_MIREDS,
|
|
ATTR_SUPPORTED_COLOR_MODES,
|
|
DOMAIN as LIGHT_DOMAIN,
|
|
ColorMode,
|
|
)
|
|
from homeassistant.components.tradfri.const import DOMAIN
|
|
from homeassistant.const import (
|
|
SERVICE_TURN_OFF,
|
|
SERVICE_TURN_ON,
|
|
STATE_OFF,
|
|
STATE_ON,
|
|
STATE_UNAVAILABLE,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
|
|
from .common import CommandStore, setup_integration
|
|
|
|
from tests.common import load_fixture
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def bulb_w() -> str:
|
|
"""Return a bulb W response."""
|
|
return load_fixture("bulb_w.json", DOMAIN)
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def bulb_ws() -> str:
|
|
"""Return a bulb WS response."""
|
|
return load_fixture("bulb_ws.json", DOMAIN)
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def bulb_cws() -> str:
|
|
"""Return a bulb CWS response."""
|
|
return load_fixture("bulb_cws.json", DOMAIN)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("device", "entity_id", "state_attributes"),
|
|
[
|
|
(
|
|
"bulb_w",
|
|
"light.test_w",
|
|
{
|
|
ATTR_BRIGHTNESS: 250,
|
|
ATTR_SUPPORTED_COLOR_MODES: [ColorMode.BRIGHTNESS],
|
|
ATTR_COLOR_MODE: ColorMode.BRIGHTNESS,
|
|
},
|
|
),
|
|
(
|
|
"bulb_ws",
|
|
"light.test_ws",
|
|
{
|
|
ATTR_BRIGHTNESS: 250,
|
|
ATTR_COLOR_TEMP: 400,
|
|
ATTR_MIN_MIREDS: 250,
|
|
ATTR_MAX_MIREDS: 454,
|
|
ATTR_SUPPORTED_COLOR_MODES: [ColorMode.COLOR_TEMP],
|
|
ATTR_COLOR_MODE: ColorMode.COLOR_TEMP,
|
|
},
|
|
),
|
|
(
|
|
"bulb_cws",
|
|
"light.test_cws",
|
|
{
|
|
ATTR_BRIGHTNESS: 250,
|
|
ATTR_HS_COLOR: (29.812, 65.252),
|
|
ATTR_SUPPORTED_COLOR_MODES: [ColorMode.HS],
|
|
ATTR_COLOR_MODE: ColorMode.HS,
|
|
},
|
|
),
|
|
],
|
|
indirect=["device"],
|
|
)
|
|
async def test_light_state(
|
|
hass: HomeAssistant,
|
|
device: Device,
|
|
entity_id: str,
|
|
state_attributes: dict[str, Any],
|
|
) -> None:
|
|
"""Test light state."""
|
|
await setup_integration(hass)
|
|
|
|
state = hass.states.get(entity_id)
|
|
assert state
|
|
assert state.state == STATE_ON
|
|
for key, value in state_attributes.items():
|
|
assert state.attributes[key] == value
|
|
|
|
|
|
@pytest.mark.parametrize("device", ["bulb_w"], indirect=True)
|
|
async def test_light_available(
|
|
hass: HomeAssistant,
|
|
command_store: CommandStore,
|
|
device: Device,
|
|
) -> None:
|
|
"""Test light available property."""
|
|
entity_id = "light.test_w"
|
|
await setup_integration(hass)
|
|
|
|
state = hass.states.get(entity_id)
|
|
assert state
|
|
assert state.state == STATE_ON
|
|
|
|
await command_store.trigger_observe_callback(
|
|
hass, device, {ATTR_REACHABLE_STATE: 0}
|
|
)
|
|
|
|
state = hass.states.get(entity_id)
|
|
assert state
|
|
assert state.state == STATE_UNAVAILABLE
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"transition",
|
|
[{}, {"transition": 0}, {"transition": 1}],
|
|
ids=["transition_none", "transition_0", "transition_1"],
|
|
)
|
|
@pytest.mark.parametrize(
|
|
("device", "entity_id", "service_data", "state_attributes"),
|
|
[
|
|
# turn_on
|
|
(
|
|
"bulb_w",
|
|
"light.test_w",
|
|
{},
|
|
{},
|
|
),
|
|
# brightness > 0
|
|
(
|
|
"bulb_w",
|
|
"light.test_w",
|
|
{"brightness": 100},
|
|
{"brightness": 100},
|
|
),
|
|
# brightness == 1
|
|
(
|
|
"bulb_w",
|
|
"light.test_w",
|
|
{"brightness": 1},
|
|
{"brightness": 1},
|
|
),
|
|
# brightness > 254
|
|
(
|
|
"bulb_w",
|
|
"light.test_w",
|
|
{"brightness": 1000},
|
|
{"brightness": 254},
|
|
),
|
|
# color_temp
|
|
(
|
|
"bulb_ws",
|
|
"light.test_ws",
|
|
{"color_temp": 250},
|
|
{"color_temp": 250},
|
|
),
|
|
# color_temp < 250
|
|
(
|
|
"bulb_ws",
|
|
"light.test_ws",
|
|
{"color_temp": 1},
|
|
{"color_temp": 250},
|
|
),
|
|
# color_temp > 454
|
|
(
|
|
"bulb_ws",
|
|
"light.test_ws",
|
|
{"color_temp": 1000},
|
|
{"color_temp": 454},
|
|
),
|
|
# hs_color
|
|
(
|
|
"bulb_cws",
|
|
"light.test_cws",
|
|
{"hs_color": [300, 100]},
|
|
{"hs_color": [300, 100]},
|
|
),
|
|
# ct + brightness
|
|
(
|
|
"bulb_ws",
|
|
"light.test_ws",
|
|
{"color_temp": 250, "brightness": 200},
|
|
{"color_temp": 250, "brightness": 200},
|
|
),
|
|
# ct + brightness (no temp support)
|
|
(
|
|
"bulb_cws",
|
|
"light.test_cws",
|
|
{"color_temp": 250, "brightness": 200},
|
|
{"hs_color": [26.807, 34.869], "brightness": 200},
|
|
),
|
|
# ct + brightness (no temp or color support)
|
|
(
|
|
"bulb_w",
|
|
"light.test_w",
|
|
{"color_temp": 250, "brightness": 200},
|
|
{"brightness": 200},
|
|
),
|
|
# hs + brightness
|
|
(
|
|
"bulb_cws",
|
|
"light.test_cws",
|
|
{"hs_color": [300, 100], "brightness": 200},
|
|
{"hs_color": [300, 100], "brightness": 200},
|
|
),
|
|
],
|
|
indirect=["device"],
|
|
ids=[
|
|
"turn_on",
|
|
"brightness > 0",
|
|
"brightness == 1",
|
|
"brightness > 254",
|
|
"color_temp",
|
|
"color_temp < 250",
|
|
"color_temp > 454",
|
|
"hs_color",
|
|
"ct + brightness",
|
|
"ct + brightness (no temp support)",
|
|
"ct + brightness (no temp or color support)",
|
|
"hs + brightness",
|
|
],
|
|
)
|
|
async def test_turn_on(
|
|
hass: HomeAssistant,
|
|
command_store: CommandStore,
|
|
device: Device,
|
|
entity_id: str,
|
|
service_data: dict[str, Any],
|
|
transition: dict[str, int],
|
|
state_attributes: dict[str, Any],
|
|
) -> None:
|
|
"""Test turning on a light."""
|
|
# Make sure the light is off.
|
|
device.raw[ATTR_LIGHT_CONTROL][0][ATTR_DEVICE_STATE] = 0
|
|
await setup_integration(hass)
|
|
|
|
await hass.services.async_call(
|
|
LIGHT_DOMAIN,
|
|
SERVICE_TURN_ON,
|
|
{"entity_id": entity_id, **service_data, **transition},
|
|
blocking=True,
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
await command_store.trigger_observe_callback(
|
|
hass, device, {ATTR_LIGHT_CONTROL: [{ATTR_DEVICE_STATE: 1}]}
|
|
)
|
|
|
|
state = hass.states.get(entity_id)
|
|
assert state
|
|
assert state.state == STATE_ON
|
|
for key, value in state_attributes.items():
|
|
# Allow some rounding error in color conversions.
|
|
assert state.attributes[key] == pytest.approx(value, abs=0.01)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"transition",
|
|
[{}, {"transition": 0}, {"transition": 1}],
|
|
ids=["transition_none", "transition_0", "transition_1"],
|
|
)
|
|
@pytest.mark.parametrize(
|
|
("device", "entity_id"),
|
|
[
|
|
("bulb_w", "light.test_w"),
|
|
("bulb_ws", "light.test_ws"),
|
|
("bulb_cws", "light.test_cws"),
|
|
],
|
|
indirect=["device"],
|
|
)
|
|
async def test_turn_off(
|
|
hass: HomeAssistant,
|
|
command_store: CommandStore,
|
|
device: Device,
|
|
entity_id: str,
|
|
transition: dict[str, int],
|
|
) -> None:
|
|
"""Test turning off a light."""
|
|
await setup_integration(hass)
|
|
|
|
await hass.services.async_call(
|
|
LIGHT_DOMAIN,
|
|
SERVICE_TURN_OFF,
|
|
{"entity_id": entity_id, **transition},
|
|
blocking=True,
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
await command_store.trigger_observe_callback(
|
|
hass, device, {ATTR_LIGHT_CONTROL: [{ATTR_DEVICE_STATE: 0}]}
|
|
)
|
|
|
|
state = hass.states.get(entity_id)
|
|
assert state
|
|
assert state.state == STATE_OFF
|