mirror of
https://github.com/home-assistant/core.git
synced 2025-07-08 13:57:10 +00:00
Enable more customization of the LIFX pulse and color loop effects (#81699)
This commit is contained in:
parent
2ff45e198d
commit
fe7ffe9519
@ -42,15 +42,17 @@ SERVICE_EFFECT_MOVE = "effect_move"
|
|||||||
SERVICE_EFFECT_PULSE = "effect_pulse"
|
SERVICE_EFFECT_PULSE = "effect_pulse"
|
||||||
SERVICE_EFFECT_STOP = "effect_stop"
|
SERVICE_EFFECT_STOP = "effect_stop"
|
||||||
|
|
||||||
|
ATTR_CHANGE = "change"
|
||||||
|
ATTR_CYCLES = "cycles"
|
||||||
|
ATTR_DIRECTION = "direction"
|
||||||
|
ATTR_PALETTE = "palette"
|
||||||
|
ATTR_PERIOD = "period"
|
||||||
ATTR_POWER_OFF = "power_off"
|
ATTR_POWER_OFF = "power_off"
|
||||||
ATTR_POWER_ON = "power_on"
|
ATTR_POWER_ON = "power_on"
|
||||||
ATTR_PERIOD = "period"
|
ATTR_SATURATION_MAX = "saturation_max"
|
||||||
ATTR_CYCLES = "cycles"
|
ATTR_SATURATION_MIN = "saturation_min"
|
||||||
ATTR_SPREAD = "spread"
|
|
||||||
ATTR_CHANGE = "change"
|
|
||||||
ATTR_DIRECTION = "direction"
|
|
||||||
ATTR_SPEED = "speed"
|
ATTR_SPEED = "speed"
|
||||||
ATTR_PALETTE = "palette"
|
ATTR_SPREAD = "spread"
|
||||||
|
|
||||||
EFFECT_FLAME = "FLAME"
|
EFFECT_FLAME = "FLAME"
|
||||||
EFFECT_MORPH = "MORPH"
|
EFFECT_MORPH = "MORPH"
|
||||||
@ -72,8 +74,8 @@ EFFECT_MOVE_DIRECTIONS = [EFFECT_MOVE_DIRECTION_LEFT, EFFECT_MOVE_DIRECTION_RIGH
|
|||||||
PULSE_MODE_BLINK = "blink"
|
PULSE_MODE_BLINK = "blink"
|
||||||
PULSE_MODE_BREATHE = "breathe"
|
PULSE_MODE_BREATHE = "breathe"
|
||||||
PULSE_MODE_PING = "ping"
|
PULSE_MODE_PING = "ping"
|
||||||
PULSE_MODE_STROBE = "strobe"
|
|
||||||
PULSE_MODE_SOLID = "solid"
|
PULSE_MODE_SOLID = "solid"
|
||||||
|
PULSE_MODE_STROBE = "strobe"
|
||||||
|
|
||||||
PULSE_MODES = [
|
PULSE_MODES = [
|
||||||
PULSE_MODE_BLINK,
|
PULSE_MODE_BLINK,
|
||||||
@ -90,8 +92,8 @@ LIFX_EFFECT_SCHEMA = {
|
|||||||
LIFX_EFFECT_PULSE_SCHEMA = cv.make_entity_service_schema(
|
LIFX_EFFECT_PULSE_SCHEMA = cv.make_entity_service_schema(
|
||||||
{
|
{
|
||||||
**LIFX_EFFECT_SCHEMA,
|
**LIFX_EFFECT_SCHEMA,
|
||||||
ATTR_BRIGHTNESS: VALID_BRIGHTNESS,
|
vol.Exclusive(ATTR_BRIGHTNESS, ATTR_BRIGHTNESS): VALID_BRIGHTNESS,
|
||||||
ATTR_BRIGHTNESS_PCT: VALID_BRIGHTNESS_PCT,
|
vol.Exclusive(ATTR_BRIGHTNESS_PCT, ATTR_BRIGHTNESS): VALID_BRIGHTNESS_PCT,
|
||||||
vol.Exclusive(ATTR_COLOR_NAME, COLOR_GROUP): cv.string,
|
vol.Exclusive(ATTR_COLOR_NAME, COLOR_GROUP): cv.string,
|
||||||
vol.Exclusive(ATTR_RGB_COLOR, COLOR_GROUP): vol.All(
|
vol.Exclusive(ATTR_RGB_COLOR, COLOR_GROUP): vol.All(
|
||||||
vol.Coerce(tuple), vol.ExactSequence((cv.byte, cv.byte, cv.byte))
|
vol.Coerce(tuple), vol.ExactSequence((cv.byte, cv.byte, cv.byte))
|
||||||
@ -121,8 +123,10 @@ LIFX_EFFECT_PULSE_SCHEMA = cv.make_entity_service_schema(
|
|||||||
LIFX_EFFECT_COLORLOOP_SCHEMA = cv.make_entity_service_schema(
|
LIFX_EFFECT_COLORLOOP_SCHEMA = cv.make_entity_service_schema(
|
||||||
{
|
{
|
||||||
**LIFX_EFFECT_SCHEMA,
|
**LIFX_EFFECT_SCHEMA,
|
||||||
ATTR_BRIGHTNESS: VALID_BRIGHTNESS,
|
vol.Exclusive(ATTR_BRIGHTNESS, ATTR_BRIGHTNESS): VALID_BRIGHTNESS,
|
||||||
ATTR_BRIGHTNESS_PCT: VALID_BRIGHTNESS_PCT,
|
vol.Exclusive(ATTR_BRIGHTNESS_PCT, ATTR_BRIGHTNESS): VALID_BRIGHTNESS_PCT,
|
||||||
|
ATTR_SATURATION_MAX: vol.All(vol.Coerce(int), vol.Clamp(min=0, max=100)),
|
||||||
|
ATTR_SATURATION_MIN: vol.All(vol.Coerce(int), vol.Clamp(min=0, max=100)),
|
||||||
ATTR_PERIOD: vol.All(vol.Coerce(float), vol.Clamp(min=0.05)),
|
ATTR_PERIOD: vol.All(vol.Coerce(float), vol.Clamp(min=0.05)),
|
||||||
ATTR_CHANGE: vol.All(vol.Coerce(float), vol.Clamp(min=0, max=360)),
|
ATTR_CHANGE: vol.All(vol.Coerce(float), vol.Clamp(min=0, max=360)),
|
||||||
ATTR_SPREAD: vol.All(vol.Coerce(float), vol.Clamp(min=0, max=360)),
|
ATTR_SPREAD: vol.All(vol.Coerce(float), vol.Clamp(min=0, max=360)),
|
||||||
@ -345,8 +349,21 @@ class LIFXManager:
|
|||||||
elif service == SERVICE_EFFECT_COLORLOOP:
|
elif service == SERVICE_EFFECT_COLORLOOP:
|
||||||
|
|
||||||
brightness = None
|
brightness = None
|
||||||
|
saturation_max = None
|
||||||
|
saturation_min = None
|
||||||
|
|
||||||
if ATTR_BRIGHTNESS in kwargs:
|
if ATTR_BRIGHTNESS in kwargs:
|
||||||
brightness = convert_8_to_16(kwargs[ATTR_BRIGHTNESS])
|
brightness = convert_8_to_16(kwargs[ATTR_BRIGHTNESS])
|
||||||
|
elif ATTR_BRIGHTNESS_PCT in kwargs:
|
||||||
|
brightness = convert_8_to_16(
|
||||||
|
round(255 * kwargs[ATTR_BRIGHTNESS_PCT] / 100)
|
||||||
|
)
|
||||||
|
|
||||||
|
if ATTR_SATURATION_MAX in kwargs:
|
||||||
|
saturation_max = int(kwargs[ATTR_SATURATION_MAX] / 100 * 65535)
|
||||||
|
|
||||||
|
if ATTR_SATURATION_MIN in kwargs:
|
||||||
|
saturation_min = int(kwargs[ATTR_SATURATION_MIN] / 100 * 65535)
|
||||||
|
|
||||||
effect = aiolifx_effects.EffectColorloop(
|
effect = aiolifx_effects.EffectColorloop(
|
||||||
power_on=kwargs.get(ATTR_POWER_ON),
|
power_on=kwargs.get(ATTR_POWER_ON),
|
||||||
@ -355,6 +372,8 @@ class LIFXManager:
|
|||||||
spread=kwargs.get(ATTR_SPREAD),
|
spread=kwargs.get(ATTR_SPREAD),
|
||||||
transition=kwargs.get(ATTR_TRANSITION),
|
transition=kwargs.get(ATTR_TRANSITION),
|
||||||
brightness=brightness,
|
brightness=brightness,
|
||||||
|
saturation_max=saturation_max,
|
||||||
|
saturation_min=saturation_min,
|
||||||
)
|
)
|
||||||
await self.effects_conductor.start(effect, bulbs)
|
await self.effects_conductor.start(effect, bulbs)
|
||||||
|
|
||||||
|
@ -79,12 +79,20 @@ effect_pulse:
|
|||||||
- "strobe"
|
- "strobe"
|
||||||
- "solid"
|
- "solid"
|
||||||
brightness:
|
brightness:
|
||||||
name: Brightness
|
name: Brightness value
|
||||||
description: Number indicating brightness of the temporary color.
|
description: Number indicating brightness of the temporary color, where 1 is the minimum brightness and 255 is the maximum brightness supported by the light.
|
||||||
selector:
|
selector:
|
||||||
number:
|
number:
|
||||||
min: 0
|
min: 1
|
||||||
max: 255
|
max: 255
|
||||||
|
brightness_pct:
|
||||||
|
name: Brightness
|
||||||
|
description: Percentage indicating the brightness of the temporary color, where 1 is the minimum brightness and 100 is the maximum brightness supported by the light.
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 100
|
||||||
|
unit_of_measurement: "%"
|
||||||
color_name:
|
color_name:
|
||||||
name: Color name
|
name: Color name
|
||||||
description: A human readable color name.
|
description: A human readable color name.
|
||||||
@ -131,12 +139,38 @@ effect_colorloop:
|
|||||||
domain: light
|
domain: light
|
||||||
fields:
|
fields:
|
||||||
brightness:
|
brightness:
|
||||||
name: Brightness
|
name: Brightness value
|
||||||
description: Number indicating brightness of the effect. Leave this out to maintain the current brightness of each participating light.
|
description: Number indicating brightness of the color loop, where 1 is the minimum brightness and 255 is the maximum brightness supported by the light.
|
||||||
selector:
|
selector:
|
||||||
number:
|
number:
|
||||||
min: 0
|
min: 0
|
||||||
max: 255
|
max: 255
|
||||||
|
brightness_pct:
|
||||||
|
name: Brightness
|
||||||
|
description: Percentage indicating the brightness of the color loop, where 1 is the minimum brightness and 100 is the maximum brightness supported by the light.
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 0
|
||||||
|
max: 100
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
saturation_min:
|
||||||
|
name: Minimum saturation
|
||||||
|
description: Percentage indicating the minimum saturation of the colors in the loop.
|
||||||
|
default: 80
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 100
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
saturation_max:
|
||||||
|
name: Maximum saturation
|
||||||
|
description: Percentage indicating the maximum saturation of the colors in the loop.
|
||||||
|
default: 100
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 100
|
||||||
|
unit_of_measurement: "%"
|
||||||
period:
|
period:
|
||||||
name: Period
|
name: Period
|
||||||
description: Duration between color changes.
|
description: Duration between color changes.
|
||||||
|
@ -13,6 +13,8 @@ from homeassistant.components.lifx.light import ATTR_INFRARED, ATTR_ZONES
|
|||||||
from homeassistant.components.lifx.manager import (
|
from homeassistant.components.lifx.manager import (
|
||||||
ATTR_DIRECTION,
|
ATTR_DIRECTION,
|
||||||
ATTR_PALETTE,
|
ATTR_PALETTE,
|
||||||
|
ATTR_SATURATION_MAX,
|
||||||
|
ATTR_SATURATION_MIN,
|
||||||
ATTR_SPEED,
|
ATTR_SPEED,
|
||||||
ATTR_THEME,
|
ATTR_THEME,
|
||||||
SERVICE_EFFECT_COLORLOOP,
|
SERVICE_EFFECT_COLORLOOP,
|
||||||
@ -1009,7 +1011,20 @@ async def test_color_light_with_temp(
|
|||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
SERVICE_EFFECT_COLORLOOP,
|
SERVICE_EFFECT_COLORLOOP,
|
||||||
{ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS: 128},
|
{ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS_PCT: 50, ATTR_SATURATION_MAX: 90},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
start_call = mock_effect_conductor.start.mock_calls
|
||||||
|
first_call = start_call[0][1]
|
||||||
|
assert isinstance(first_call[0], aiolifx_effects.EffectColorloop)
|
||||||
|
assert first_call[1][0] == bulb
|
||||||
|
mock_effect_conductor.start.reset_mock()
|
||||||
|
mock_effect_conductor.stop.reset_mock()
|
||||||
|
|
||||||
|
await hass.services.async_call(
|
||||||
|
DOMAIN,
|
||||||
|
SERVICE_EFFECT_COLORLOOP,
|
||||||
|
{ATTR_ENTITY_ID: entity_id, ATTR_BRIGHTNESS: 128, ATTR_SATURATION_MIN: 90},
|
||||||
blocking=True,
|
blocking=True,
|
||||||
)
|
)
|
||||||
start_call = mock_effect_conductor.start.mock_calls
|
start_call = mock_effect_conductor.start.mock_calls
|
||||||
|
Loading…
x
Reference in New Issue
Block a user