mirror of
https://github.com/esphome/esphome.git
synced 2026-10-07 11:26:39 +00:00
[light][lvgl] Add color names for light states (#19712)
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
"""Tests for the light `color` option."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
|
||||
from esphome import config_validation as cv
|
||||
from esphome.components.light.automation import (
|
||||
LIGHT_CONTROL_ACTION_SCHEMA,
|
||||
LIGHT_STATE_SCHEMA,
|
||||
)
|
||||
from esphome.const import (
|
||||
CONF_BLUE,
|
||||
CONF_COLOR_BRIGHTNESS,
|
||||
CONF_GREEN,
|
||||
CONF_ID,
|
||||
CONF_RED,
|
||||
)
|
||||
|
||||
LOGGER_NAME: str = "esphome.components.light.automation"
|
||||
|
||||
|
||||
def test_color_name_sets_rgb() -> None:
|
||||
result = LIGHT_STATE_SCHEMA({"color": "Tomato"})
|
||||
assert "color" not in result
|
||||
assert result[CONF_RED] == 1.0
|
||||
assert result[CONF_GREEN] == pytest.approx(0x63 / 0xFF)
|
||||
assert result[CONF_BLUE] == pytest.approx(0x47 / 0xFF)
|
||||
assert result[CONF_COLOR_BRIGHTNESS] == 1.0
|
||||
|
||||
|
||||
def test_color_name_in_control_action() -> None:
|
||||
result = LIGHT_CONTROL_ACTION_SCHEMA({CONF_ID: "test_light", "color": "blue"})
|
||||
assert (result[CONF_RED], result[CONF_GREEN], result[CONF_BLUE]) == (0, 0, 1.0)
|
||||
|
||||
|
||||
def test_unknown_color_name() -> None:
|
||||
with pytest.raises(cv.Invalid, match="notacolor"):
|
||||
LIGHT_STATE_SCHEMA({"color": "notacolor"})
|
||||
|
||||
|
||||
def test_color_name_conflicts_with_rgb() -> None:
|
||||
with pytest.raises(cv.Invalid, match="cannot be used with"):
|
||||
LIGHT_STATE_SCHEMA({"color": "red", CONF_GREEN: 0.5})
|
||||
|
||||
|
||||
def test_dark_color_sets_color_brightness() -> None:
|
||||
result = LIGHT_STATE_SCHEMA({"color": "darkred"})
|
||||
assert result[CONF_RED] == 1.0
|
||||
assert result[CONF_GREEN] == 0.0
|
||||
assert result[CONF_BLUE] == 0.0
|
||||
assert result[CONF_COLOR_BRIGHTNESS] == pytest.approx(0x8B / 0xFF)
|
||||
|
||||
|
||||
def test_black_sets_zero_color_brightness() -> None:
|
||||
result = LIGHT_STATE_SCHEMA({"color": "black"})
|
||||
assert result[CONF_COLOR_BRIGHTNESS] == 0.0
|
||||
assert (result[CONF_RED], result[CONF_GREEN], result[CONF_BLUE]) == (0, 0, 0)
|
||||
|
||||
|
||||
def test_explicit_color_brightness_wins(caplog: pytest.LogCaptureFixture) -> None:
|
||||
with caplog.at_level(logging.WARNING, logger=LOGGER_NAME):
|
||||
result = LIGHT_STATE_SCHEMA({"color": "darkred", CONF_COLOR_BRIGHTNESS: 0.25})
|
||||
assert result[CONF_COLOR_BRIGHTNESS] == 0.25
|
||||
assert "overrides the brightness of color 'darkred'" in caplog.text
|
||||
|
||||
|
||||
def test_explicit_color_brightness_full_color(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
with caplog.at_level(logging.WARNING, logger=LOGGER_NAME):
|
||||
result = LIGHT_STATE_SCHEMA({"color": "red", CONF_COLOR_BRIGHTNESS: 0.25})
|
||||
assert result[CONF_COLOR_BRIGHTNESS] == 0.25
|
||||
assert not [r for r in caplog.records if r.name == LOGGER_NAME]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", [0x223344, "0x223344", "0X223344"])
|
||||
def test_hex_color(value: int | str) -> None:
|
||||
result = LIGHT_STATE_SCHEMA({"color": value})
|
||||
assert "color" not in result
|
||||
assert result[CONF_COLOR_BRIGHTNESS] == pytest.approx(0x44 / 0xFF)
|
||||
assert result[CONF_BLUE] == 1.0
|
||||
assert result[CONF_RED] == pytest.approx(0x22 / 0x44)
|
||||
assert result[CONF_GREEN] == pytest.approx(0x33 / 0x44)
|
||||
|
||||
|
||||
def test_hex_color_full_level() -> None:
|
||||
result = LIGHT_STATE_SCHEMA({"color": 0xFF8000})
|
||||
assert result[CONF_COLOR_BRIGHTNESS] == 1.0
|
||||
assert result[CONF_RED] == 1.0
|
||||
assert result[CONF_GREEN] == pytest.approx(0x80 / 0xFF)
|
||||
assert result[CONF_BLUE] == 0.0
|
||||
|
||||
|
||||
def test_hex_color_black() -> None:
|
||||
result = LIGHT_STATE_SCHEMA({"color": 0})
|
||||
assert result[CONF_COLOR_BRIGHTNESS] == 0.0
|
||||
assert (result[CONF_RED], result[CONF_GREEN], result[CONF_BLUE]) == (0, 0, 0)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("value", [0x1000000, -1, "0xGG", "0x1000000"])
|
||||
def test_hex_color_invalid(value: int | str) -> None:
|
||||
with pytest.raises(cv.Invalid):
|
||||
LIGHT_STATE_SCHEMA({"color": value})
|
||||
|
||||
|
||||
def test_hex_color_conflicts_with_rgb() -> None:
|
||||
with pytest.raises(cv.Invalid, match="cannot be used with"):
|
||||
LIGHT_STATE_SCHEMA({"color": 0x223344, CONF_RED: 0.5})
|
||||
|
||||
|
||||
def test_explicit_color_brightness_warning_names_hex_color(
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
with caplog.at_level(logging.WARNING, logger=LOGGER_NAME):
|
||||
LIGHT_STATE_SCHEMA({"color": 0x223344, CONF_COLOR_BRIGHTNESS: 0.25})
|
||||
assert "overrides the brightness of color '0x223344'" in caplog.text
|
||||
@@ -85,6 +85,12 @@ esphome:
|
||||
red: 100%
|
||||
green: 100%
|
||||
blue: 1.0
|
||||
- light.turn_on:
|
||||
id: test_rgb_light
|
||||
color: Tomato
|
||||
- light.turn_on:
|
||||
id: test_rgb_light
|
||||
color: 0x223344
|
||||
- light.control:
|
||||
id: test_monochromatic_light
|
||||
state: on
|
||||
@@ -157,6 +163,17 @@ esphome:
|
||||
green: 100%
|
||||
blue: 0%
|
||||
transition_length: 1s
|
||||
- light.addressable_set:
|
||||
id: test_addressable_transition
|
||||
range_from: 0
|
||||
range_to: 4
|
||||
color: darkred
|
||||
- light.addressable_set:
|
||||
id: test_addressable_transition
|
||||
color: tomato
|
||||
- light.addressable_set:
|
||||
id: test_addressable_transition
|
||||
color: 0x223344
|
||||
|
||||
# Exercise light actions inside a trigger with non-empty Ts (number on_value
|
||||
# passes float).
|
||||
@@ -336,6 +353,15 @@ light:
|
||||
red: 100%
|
||||
green: 50%
|
||||
blue: 50%
|
||||
# Test initial_state: with a color name (a dark color also sets color_brightness)
|
||||
- platform: rgb
|
||||
id: test_rgb_light_initial_state_color
|
||||
name: RGB Light Initial State Color
|
||||
red: test_ledc_1
|
||||
green: test_ledc_2
|
||||
blue: test_ledc_3
|
||||
initial_state:
|
||||
color: darkred
|
||||
# Test initial_state: with every templatable field set via !lambda (color_mode is
|
||||
# the only field that isn't templatable, so it's the only one left as a literal)
|
||||
- platform: rgbww
|
||||
|
||||
Reference in New Issue
Block a user