Fix light toggle service attributes (#35483)
parent
823a44cd23
commit
5d8e6d5432
|
@ -167,12 +167,19 @@ def preprocess_turn_on_alternatives(params):
|
|||
if rgb_color is not None:
|
||||
params[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
|
||||
|
||||
return params
|
||||
|
||||
|
||||
def filter_turn_off_params(params):
|
||||
"""Filter out params not used in turn off."""
|
||||
return {k: v for k, v in params.items() if k in (ATTR_TRANSITION, ATTR_FLASH)}
|
||||
|
||||
|
||||
def preprocess_turn_off(params):
|
||||
"""Process data for turning light off if brightness is 0."""
|
||||
if ATTR_BRIGHTNESS in params and params[ATTR_BRIGHTNESS] == 0:
|
||||
# Zero brightness: Light will be turned off
|
||||
params = {k: v for k, v in params.items() if k in (ATTR_TRANSITION, ATTR_FLASH)}
|
||||
params = filter_turn_off_params(params)
|
||||
return (True, params) # Light should be turned off
|
||||
|
||||
return (False, None) # Light should be turned on
|
||||
|
@ -198,13 +205,7 @@ async def async_setup(hass, config):
|
|||
if entity_field in data
|
||||
}
|
||||
|
||||
preprocess_turn_on_alternatives(data)
|
||||
turn_lights_off, off_params = preprocess_turn_off(data)
|
||||
|
||||
base["params"] = data
|
||||
base["turn_lights_off"] = turn_lights_off
|
||||
base["off_params"] = off_params
|
||||
|
||||
base["params"] = preprocess_turn_on_alternatives(data)
|
||||
return base
|
||||
|
||||
async def async_handle_light_on_service(light, call):
|
||||
|
@ -213,8 +214,6 @@ async def async_setup(hass, config):
|
|||
If brightness is set to 0, this service will turn the light off.
|
||||
"""
|
||||
params = call.data["params"]
|
||||
turn_light_off = call.data["turn_lights_off"]
|
||||
off_params = call.data["off_params"]
|
||||
|
||||
if not params:
|
||||
default_profile = Profiles.get_default(light.entity_id)
|
||||
|
@ -222,7 +221,6 @@ async def async_setup(hass, config):
|
|||
if default_profile is not None:
|
||||
params = {ATTR_PROFILE: default_profile}
|
||||
preprocess_turn_on_alternatives(params)
|
||||
turn_light_off, off_params = preprocess_turn_off(params)
|
||||
|
||||
elif ATTR_BRIGHTNESS_STEP in params or ATTR_BRIGHTNESS_STEP_PCT in params:
|
||||
brightness = light.brightness if light.is_on else 0
|
||||
|
@ -236,13 +234,24 @@ async def async_setup(hass, config):
|
|||
brightness += round(params.pop(ATTR_BRIGHTNESS_STEP_PCT) / 100 * 255)
|
||||
|
||||
params[ATTR_BRIGHTNESS] = max(0, min(255, brightness))
|
||||
turn_light_off, off_params = preprocess_turn_off(params)
|
||||
|
||||
turn_light_off, off_params = preprocess_turn_off(params)
|
||||
if turn_light_off:
|
||||
await light.async_turn_off(**off_params)
|
||||
else:
|
||||
await light.async_turn_on(**params)
|
||||
|
||||
async def async_handle_toggle_service(light, call):
|
||||
"""Handle toggling a light.
|
||||
|
||||
If brightness is set to 0, this service will turn the light off.
|
||||
"""
|
||||
if light.is_on:
|
||||
off_params = filter_turn_off_params(call.data["params"])
|
||||
await light.async_turn_off(**off_params)
|
||||
else:
|
||||
await async_handle_light_on_service(light, call)
|
||||
|
||||
# Listen for light on and light off service calls.
|
||||
|
||||
component.async_register_entity_service(
|
||||
|
@ -258,7 +267,9 @@ async def async_setup(hass, config):
|
|||
)
|
||||
|
||||
component.async_register_entity_service(
|
||||
SERVICE_TOGGLE, LIGHT_TURN_ON_SCHEMA, "async_toggle"
|
||||
SERVICE_TOGGLE,
|
||||
vol.All(cv.make_entity_service_schema(LIGHT_TURN_ON_SCHEMA), preprocess_data),
|
||||
async_handle_toggle_service,
|
||||
)
|
||||
|
||||
return True
|
||||
|
|
|
@ -128,16 +128,80 @@ async def async_turn_off(hass, entity_id=ENTITY_MATCH_ALL, transition=None):
|
|||
|
||||
|
||||
@bind_hass
|
||||
def toggle(hass, entity_id=ENTITY_MATCH_ALL, transition=None):
|
||||
def toggle(
|
||||
hass,
|
||||
entity_id=ENTITY_MATCH_ALL,
|
||||
transition=None,
|
||||
brightness=None,
|
||||
brightness_pct=None,
|
||||
rgb_color=None,
|
||||
xy_color=None,
|
||||
hs_color=None,
|
||||
color_temp=None,
|
||||
kelvin=None,
|
||||
white_value=None,
|
||||
profile=None,
|
||||
flash=None,
|
||||
effect=None,
|
||||
color_name=None,
|
||||
):
|
||||
"""Toggle all or specified light."""
|
||||
hass.add_job(async_toggle, hass, entity_id, transition)
|
||||
hass.add_job(
|
||||
async_toggle,
|
||||
hass,
|
||||
entity_id,
|
||||
transition,
|
||||
brightness,
|
||||
brightness_pct,
|
||||
rgb_color,
|
||||
xy_color,
|
||||
hs_color,
|
||||
color_temp,
|
||||
kelvin,
|
||||
white_value,
|
||||
profile,
|
||||
flash,
|
||||
effect,
|
||||
color_name,
|
||||
)
|
||||
|
||||
|
||||
async def async_toggle(hass, entity_id=ENTITY_MATCH_ALL, transition=None):
|
||||
"""Toggle all or specified light."""
|
||||
async def async_toggle(
|
||||
hass,
|
||||
entity_id=ENTITY_MATCH_ALL,
|
||||
transition=None,
|
||||
brightness=None,
|
||||
brightness_pct=None,
|
||||
rgb_color=None,
|
||||
xy_color=None,
|
||||
hs_color=None,
|
||||
color_temp=None,
|
||||
kelvin=None,
|
||||
white_value=None,
|
||||
profile=None,
|
||||
flash=None,
|
||||
effect=None,
|
||||
color_name=None,
|
||||
):
|
||||
"""Turn all or specified light on."""
|
||||
data = {
|
||||
key: value
|
||||
for key, value in [(ATTR_ENTITY_ID, entity_id), (ATTR_TRANSITION, transition)]
|
||||
for key, value in [
|
||||
(ATTR_ENTITY_ID, entity_id),
|
||||
(ATTR_PROFILE, profile),
|
||||
(ATTR_TRANSITION, transition),
|
||||
(ATTR_BRIGHTNESS, brightness),
|
||||
(ATTR_BRIGHTNESS_PCT, brightness_pct),
|
||||
(ATTR_RGB_COLOR, rgb_color),
|
||||
(ATTR_XY_COLOR, xy_color),
|
||||
(ATTR_HS_COLOR, hs_color),
|
||||
(ATTR_COLOR_TEMP, color_temp),
|
||||
(ATTR_KELVIN, kelvin),
|
||||
(ATTR_WHITE_VALUE, white_value),
|
||||
(ATTR_FLASH, flash),
|
||||
(ATTR_EFFECT, effect),
|
||||
(ATTR_COLOR_NAME, color_name),
|
||||
]
|
||||
if value is not None
|
||||
}
|
||||
|
||||
|
|
|
@ -263,6 +263,15 @@ class TestLight(unittest.TestCase):
|
|||
light.ATTR_HS_COLOR: (prof_h, prof_s),
|
||||
} == data
|
||||
|
||||
# Test toggle with parameters
|
||||
common.toggle(self.hass, ent3.entity_id, profile=prof_name, brightness_pct=100)
|
||||
self.hass.block_till_done()
|
||||
_, data = ent3.last_call("turn_on")
|
||||
assert {
|
||||
light.ATTR_BRIGHTNESS: 255,
|
||||
light.ATTR_HS_COLOR: (prof_h, prof_s),
|
||||
} == data
|
||||
|
||||
# Test bad data
|
||||
common.turn_on(self.hass)
|
||||
common.turn_on(self.hass, ent1.entity_id, profile="nonexisting")
|
||||
|
|
Loading…
Reference in New Issue