diff --git a/README.md b/README.md index 2d3b9c57..19b10db1 100644 --- a/README.md +++ b/README.md @@ -256,7 +256,7 @@ Provide a switch in `entity_id`, a list of `lights`, or both. -Call it with a `response_variable`. For each light, the response lists the calls in order, each with its `service_data` and the `delay` in seconds before it (only nonzero between split calls, see `separate_turn_on_commands`). Only the lights and light groups in a switch's `lights` can be passed; without `entity_id`, each uses the switch it's in (of several, the one that's on). A light group is replaced by its members if the switch expands light groups. Options you leave out follow the switch, with its `initial_transition`, and in sleep mode the calls are for the sleep settings, whatever the time. With `skip_redundant_commands`, what a light already has is left out, as when Adaptive Lighting adapts it. Manual control doesn't change the calls. In YAML files, quote the time (`"22:00:00"`), since `22:00:00` is read as a number. +Call it with a `response_variable`. For each light, the response lists the calls in order, each with its `service_data` and the `delay` in seconds before it (only nonzero between split calls, see `separate_turn_on_commands`). Only the lights and light groups in a switch's `lights` can be passed; without `entity_id`, each uses the switch it's in (of several, the one that's on). A light group is replaced by its members if the switch expands light groups. Options you leave out follow the switch, with its `initial_transition`, and in sleep mode the calls are for the sleep settings, whatever the time. With `skip_redundant_commands`, what a light already has is left out, as when Adaptive Lighting adapts it; that compares with the light's state when you call the service, so make the calls right away. Manual control doesn't change the calls. In YAML files, quote the time (`"22:00:00"`), since `22:00:00` is read as a number. Making the calls is a manual change for Adaptive Lighting: with `take_over_control`, it stops adapting those lights until manual control is reset. A light that's off is adapted to the current settings as it turns on (unless `take_over_control` and `adapt_only_on_bare_turn_on` are enabled), so this example only changes lights that are on: diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index 7619babe..1bb800d4 100644 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -1503,7 +1503,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): For each light (all of the switch's if `lights` is `None`), the calls in order, each with its service data and the time to wait before it, adapting now or at the `time` of day today (lights without a state are left out). With - `skip_redundant_commands`, what a light already has is left out. + `skip_redundant_commands`, what a light already has (now) is left out. Omitted options default to the switch's settings (unlike for `apply`), and `transition` to its `initial_transition` (like for `apply`). Manual control doesn't change the calls, and nothing is sent. diff --git a/docs/services.md b/docs/services.md index 47d4156d..fcf30b4a 100644 --- a/docs/services.md +++ b/docs/services.md @@ -87,7 +87,7 @@ Provide a switch in `entity_id`, a list of `lights`, or both. -Call it with a `response_variable`. For each light, the response lists the calls in order, each with its `service_data` and the `delay` in seconds before it (only nonzero between split calls, see `separate_turn_on_commands`). Only the lights and light groups in a switch's `lights` can be passed; without `entity_id`, each uses the switch it's in (of several, the one that's on). A light group is replaced by its members if the switch expands light groups. Options you leave out follow the switch, with its `initial_transition`, and in sleep mode the calls are for the sleep settings, whatever the time. With `skip_redundant_commands`, what a light already has is left out, as when Adaptive Lighting adapts it. Manual control doesn't change the calls. In YAML files, quote the time (`"22:00:00"`), since `22:00:00` is read as a number. +Call it with a `response_variable`. For each light, the response lists the calls in order, each with its `service_data` and the `delay` in seconds before it (only nonzero between split calls, see `separate_turn_on_commands`). Only the lights and light groups in a switch's `lights` can be passed; without `entity_id`, each uses the switch it's in (of several, the one that's on). A light group is replaced by its members if the switch expands light groups. Options you leave out follow the switch, with its `initial_transition`, and in sleep mode the calls are for the sleep settings, whatever the time. With `skip_redundant_commands`, what a light already has is left out, as when Adaptive Lighting adapts it; that compares with the light's state when you call the service, so make the calls right away. Manual control doesn't change the calls. In YAML files, quote the time (`"22:00:00"`), since `22:00:00` is read as a number. Making the calls is a manual change for Adaptive Lighting: with `take_over_control`, it stops adapting those lights until manual control is reset. A light that's off is adapted to the current settings as it turns on (unless `take_over_control` and `adapt_only_on_bare_turn_on` are enabled), so this example only changes lights that are on: diff --git a/tests/test_get_commands.py b/tests/test_get_commands.py index 87322996..e4a0bd77 100644 --- a/tests/test_get_commands.py +++ b/tests/test_get_commands.py @@ -775,7 +775,8 @@ async def test_get_commands_skip_redundant(hass, skip_redundant): assert nothing == {ENTITY_LIGHT_1: []} -async def test_get_commands_skip_redundant_split(hass): +@pytest.mark.parametrize("already_has", ["brightness", "color"]) +async def test_get_commands_skip_redundant_split(hass, already_has): """A split call with nothing left is dropped, and the rest isn't delayed.""" switch, _ = await setup_lights_and_switch( hass, @@ -788,20 +789,26 @@ async def test_get_commands_skip_redundant_split(hass): with patch(UTCNOW, return_value=_noon()): full = await _get_commands(hass, switch, lights=[ENTITY_LIGHT_1]) brightness_call, color_call = full[ENTITY_LIGHT_1] + brightness = brightness_call["service_data"][ATTR_BRIGHTNESS] + color_temp = color_call["service_data"][ATTR_COLOR_TEMP_KELVIN] await hass.services.async_call( "light", SERVICE_TURN_ON, { - **brightness_call["service_data"], + ATTR_ENTITY_ID: ENTITY_LIGHT_1, + ATTR_BRIGHTNESS: ( + brightness if already_has == "brightness" else brightness - 50 + ), ATTR_COLOR_TEMP_KELVIN: ( - color_call["service_data"][ATTR_COLOR_TEMP_KELVIN] - 1000 + color_temp if already_has == "color" else color_temp - 1000 ), }, blocking=True, ) commands = await _get_commands(hass, switch, lights=[ENTITY_LIGHT_1]) + remaining = color_call if already_has == "brightness" else brightness_call assert commands == { - ENTITY_LIGHT_1: [{"service_data": color_call["service_data"], "delay": 0}], + ENTITY_LIGHT_1: [{"service_data": remaining["service_data"], "delay": 0}], }