Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion homeassistant/components/lifx/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@

from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_BRIGHTNESS_PCT,
ATTR_COLOR_NAME,
ATTR_COLOR_TEMP_KELVIN,
ATTR_HS_COLOR,
ATTR_KELVIN,
ATTR_RGB_COLOR,
ATTR_XY_COLOR,
)
Expand All @@ -24,7 +27,7 @@
from homeassistant.helpers import device_registry as dr
import homeassistant.util.color as color_util

from .const import DOMAIN, INFRARED_BRIGHTNESS_VALUES_MAP, OVERALL_TIMEOUT
from .const import _LOGGER, DOMAIN, INFRARED_BRIGHTNESS_VALUES_MAP, OVERALL_TIMEOUT

FIX_MAC_FW = AwesomeVersion("3.70")

Expand Down Expand Up @@ -80,6 +83,17 @@ def find_hsbk(hass: HomeAssistant, **kwargs: Any) -> list[float | int | None] |
"""
hue, saturation, brightness, kelvin = [None] * 4

if (color_name := kwargs.get(ATTR_COLOR_NAME)) is not None:
try:
hue, saturation = color_util.color_RGB_to_hs(
*color_util.color_name_to_rgb(color_name)
)
except ValueError:
Comment thread
Djelibeybi marked this conversation as resolved.
_LOGGER.warning(
"Got unknown color %s, falling back to neutral white", color_name
)
hue, saturation = (0, 0)

if ATTR_HS_COLOR in kwargs:
hue, saturation = kwargs[ATTR_HS_COLOR]
elif ATTR_RGB_COLOR in kwargs:
Expand All @@ -93,13 +107,23 @@ def find_hsbk(hass: HomeAssistant, **kwargs: Any) -> list[float | int | None] |
saturation = int(saturation / 100 * 65535)
kelvin = 3500

if ATTR_KELVIN in kwargs:
_LOGGER.warning(
"The 'kelvin' parameter is deprecated. Please use 'color_temp_kelvin' for all service calls"
)
kelvin = kwargs.pop(ATTR_KELVIN)
saturation = 0

if ATTR_COLOR_TEMP_KELVIN in kwargs:
kelvin = kwargs.pop(ATTR_COLOR_TEMP_KELVIN)
saturation = 0

if ATTR_BRIGHTNESS in kwargs:
brightness = convert_8_to_16(kwargs[ATTR_BRIGHTNESS])

if ATTR_BRIGHTNESS_PCT in kwargs:
brightness = convert_8_to_16(round(255 * kwargs[ATTR_BRIGHTNESS_PCT] / 100))

hsbk = [hue, saturation, brightness, kelvin]
return None if hsbk == [None] * 4 else hsbk

Expand Down
128 changes: 128 additions & 0 deletions tests/components/lifx/test_light.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@
)
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_BRIGHTNESS_PCT,
ATTR_COLOR_MODE,
ATTR_COLOR_NAME,
ATTR_COLOR_TEMP,
ATTR_COLOR_TEMP_KELVIN,
ATTR_EFFECT,
ATTR_HS_COLOR,
ATTR_KELVIN,
ATTR_RGB_COLOR,
ATTR_SUPPORTED_COLOR_MODES,
ATTR_TRANSITION,
Expand Down Expand Up @@ -1397,6 +1400,131 @@ async def test_transitions_color_bulb(hass: HomeAssistant) -> None:
bulb.set_color.reset_mock()


async def test_lifx_set_state_color(hass: HomeAssistant) -> None:
"""Test lifx.set_state works with color names and RGB."""
config_entry = MockConfigEntry(
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=SERIAL
)
config_entry.add_to_hass(hass)
bulb = _mocked_bulb_new_firmware()
bulb.power_level = 65535
bulb.color = [32000, None, 32000, 2700]
with _patch_discovery(device=bulb), _patch_config_flow_try_connect(
device=bulb
), _patch_device(device=bulb):
await async_setup_component(hass, lifx.DOMAIN, {lifx.DOMAIN: {}})
await hass.async_block_till_done()

entity_id = "light.my_bulb"

# brightness should convert from 8 to 16 bits
await hass.services.async_call(
DOMAIN,
"set_state",
{ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS: 255},
blocking=True,
)
assert bulb.set_color.calls[0][0][0] == [32000, None, 65535, 2700]
bulb.set_color.reset_mock()

# brightness_pct should convert into 16 bit
await hass.services.async_call(
DOMAIN,
"set_state",
{ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS_PCT: 90},
blocking=True,
)
assert bulb.set_color.calls[0][0][0] == [32000, None, 59110, 2700]
bulb.set_color.reset_mock()

# color name should turn into hue, saturation
await hass.services.async_call(
DOMAIN,
"set_state",
{ATTR_ENTITY_ID: entity_id, ATTR_COLOR_NAME: "red", ATTR_BRIGHTNESS_PCT: 100},
blocking=True,
)
assert bulb.set_color.calls[0][0][0] == [0, 65535, 65535, 3500]
bulb.set_color.reset_mock()

# unknown color name should reset back to neutral white, i.e. 3500K
await hass.services.async_call(
DOMAIN,
"set_state",
{ATTR_ENTITY_ID: entity_id, ATTR_COLOR_NAME: "deepblack"},
blocking=True,
)
assert bulb.set_color.calls[0][0][0] == [0, 0, 32000, 3500]
bulb.set_color.reset_mock()

# RGB should convert to hue, saturation
await hass.services.async_call(
DOMAIN,
"set_state",
{ATTR_ENTITY_ID: entity_id, ATTR_RGB_COLOR: (0, 255, 0)},
blocking=True,
)
assert bulb.set_color.calls[0][0][0] == [21845, 65535, 32000, 3500]
bulb.set_color.reset_mock()

# XY should convert to hue, saturation
await hass.services.async_call(
DOMAIN,
"set_state",
{ATTR_ENTITY_ID: entity_id, ATTR_XY_COLOR: (0.34, 0.339)},
blocking=True,
)
assert bulb.set_color.calls[0][0][0] == [5461, 5139, 32000, 3500]
bulb.set_color.reset_mock()


async def test_lifx_set_state_kelvin(hass: HomeAssistant) -> None:
"""Test set_state works with old and new kelvin parameter names."""
already_migrated_config_entry = MockConfigEntry(
domain=DOMAIN, data={CONF_HOST: "127.0.0.1"}, unique_id=SERIAL
)
already_migrated_config_entry.add_to_hass(hass)
bulb = _mocked_bulb_new_firmware()
bulb.power_level = 65535
bulb.color = [32000, None, 32000, 6000]
with _patch_discovery(device=bulb), _patch_config_flow_try_connect(
device=bulb
), _patch_device(device=bulb):
await async_setup_component(hass, lifx.DOMAIN, {lifx.DOMAIN: {}})
await hass.async_block_till_done()

entity_id = "light.my_bulb"

state = hass.states.get(entity_id)
assert state.state == "on"
attributes = state.attributes
assert attributes[ATTR_BRIGHTNESS] == 125
assert attributes[ATTR_COLOR_MODE] == ColorMode.COLOR_TEMP
await hass.services.async_call(
LIGHT_DOMAIN, "turn_off", {ATTR_ENTITY_ID: entity_id}, blocking=True
)
assert bulb.set_power.calls[0][0][0] is False
bulb.set_power.reset_mock()

await hass.services.async_call(
DOMAIN,
"set_state",
{ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS: 255, ATTR_KELVIN: 3500},
blocking=True,
)
assert bulb.set_color.calls[0][0][0] == [32000, 0, 65535, 3500]
bulb.set_color.reset_mock()

await hass.services.async_call(
DOMAIN,
"set_state",
{ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS: 100, ATTR_COLOR_TEMP_KELVIN: 2700},
blocking=True,
)
assert bulb.set_color.calls[0][0][0] == [32000, 0, 25700, 2700]
bulb.set_color.reset_mock()


async def test_infrared_color_bulb(hass: HomeAssistant) -> None:
"""Test setting infrared with a color bulb."""
already_migrated_config_entry = MockConfigEntry(
Expand Down