mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Fix light toggle service attributes (#35483)
This commit is contained in:
parent
823a44cd23
commit
5d8e6d5432
@ -167,12 +167,19 @@ def preprocess_turn_on_alternatives(params):
|
|||||||
if rgb_color is not None:
|
if rgb_color is not None:
|
||||||
params[ATTR_HS_COLOR] = color_util.color_RGB_to_hs(*rgb_color)
|
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):
|
def preprocess_turn_off(params):
|
||||||
"""Process data for turning light off if brightness is 0."""
|
"""Process data for turning light off if brightness is 0."""
|
||||||
if ATTR_BRIGHTNESS in params and params[ATTR_BRIGHTNESS] == 0:
|
if ATTR_BRIGHTNESS in params and params[ATTR_BRIGHTNESS] == 0:
|
||||||
# Zero brightness: Light will be turned off
|
# 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 (True, params) # Light should be turned off
|
||||||
|
|
||||||
return (False, None) # Light should be turned on
|
return (False, None) # Light should be turned on
|
||||||
@ -198,13 +205,7 @@ async def async_setup(hass, config):
|
|||||||
if entity_field in data
|
if entity_field in data
|
||||||
}
|
}
|
||||||
|
|
||||||
preprocess_turn_on_alternatives(data)
|
base["params"] = 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
|
|
||||||
|
|
||||||
return base
|
return base
|
||||||
|
|
||||||
async def async_handle_light_on_service(light, call):
|
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.
|
If brightness is set to 0, this service will turn the light off.
|
||||||
"""
|
"""
|
||||||
params = call.data["params"]
|
params = call.data["params"]
|
||||||
turn_light_off = call.data["turn_lights_off"]
|
|
||||||
off_params = call.data["off_params"]
|
|
||||||
|
|
||||||
if not params:
|
if not params:
|
||||||
default_profile = Profiles.get_default(light.entity_id)
|
default_profile = Profiles.get_default(light.entity_id)
|
||||||
@ -222,7 +221,6 @@ async def async_setup(hass, config):
|
|||||||
if default_profile is not None:
|
if default_profile is not None:
|
||||||
params = {ATTR_PROFILE: default_profile}
|
params = {ATTR_PROFILE: default_profile}
|
||||||
preprocess_turn_on_alternatives(params)
|
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:
|
elif ATTR_BRIGHTNESS_STEP in params or ATTR_BRIGHTNESS_STEP_PCT in params:
|
||||||
brightness = light.brightness if light.is_on else 0
|
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)
|
brightness += round(params.pop(ATTR_BRIGHTNESS_STEP_PCT) / 100 * 255)
|
||||||
|
|
||||||
params[ATTR_BRIGHTNESS] = max(0, min(255, brightness))
|
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:
|
if turn_light_off:
|
||||||
await light.async_turn_off(**off_params)
|
await light.async_turn_off(**off_params)
|
||||||
else:
|
else:
|
||||||
await light.async_turn_on(**params)
|
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.
|
# Listen for light on and light off service calls.
|
||||||
|
|
||||||
component.async_register_entity_service(
|
component.async_register_entity_service(
|
||||||
@ -258,7 +267,9 @@ async def async_setup(hass, config):
|
|||||||
)
|
)
|
||||||
|
|
||||||
component.async_register_entity_service(
|
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
|
return True
|
||||||
|
@ -128,16 +128,80 @@ async def async_turn_off(hass, entity_id=ENTITY_MATCH_ALL, transition=None):
|
|||||||
|
|
||||||
|
|
||||||
@bind_hass
|
@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."""
|
"""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):
|
async def async_toggle(
|
||||||
"""Toggle all or specified light."""
|
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 = {
|
data = {
|
||||||
key: value
|
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
|
if value is not None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,6 +263,15 @@ class TestLight(unittest.TestCase):
|
|||||||
light.ATTR_HS_COLOR: (prof_h, prof_s),
|
light.ATTR_HS_COLOR: (prof_h, prof_s),
|
||||||
} == data
|
} == 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
|
# Test bad data
|
||||||
common.turn_on(self.hass)
|
common.turn_on(self.hass)
|
||||||
common.turn_on(self.hass, ent1.entity_id, profile="nonexisting")
|
common.turn_on(self.hass, ent1.entity_id, profile="nonexisting")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user