Add dim-only brightness adaptation

This commit is contained in:
Bas Nijholt 2026-09-06 09:29:32 -07:00
commit 3c10d827c2
11 changed files with 378 additions and 93 deletions

View file

@ -56,6 +56,10 @@ The Adaptive Lighting switch exposes these read-only attributes for its lights:
These lists report manual-control flags. Actual adaptation also depends on `take_over_control_mode` and the brightness/color adaptation switches. For example, under the default `pause_all` mode, manually changing only brightness leaves `manual_control_color` empty while pausing both brightness and color adaptation. Under `pause_changed`, color can continue adapting.
The `skip_brightness_increases` option provides a dim-only policy for automatic adaptation. Adaptive Lighting can lower brightness and continue adapting color, but it will not raise brightness above the light's reported numeric value. To keep adapting after direct or physical brightness changes, use `take_over_control: false` and `detect_non_ha_changes: false`; otherwise the existing `pause_all` or `pause_changed` manual-control policy can pause adaptation before this brightness ceiling is applied.
This option does not store a brightness to restore later. A retained brightness reported while a light is off remains the ceiling on a bare turn-on, and leaving sleep mode does not necessarily restore the normal brighter target. Send a direct brightness request or disable `skip_brightness_increases` when you want to brighten the light. If the light reports no numeric brightness, Adaptive Lighting uses its calculated target.
The attributes are absent when the Adaptive Lighting switch is off. Use a fallback when checking them in templates:
```jinja
@ -123,48 +127,49 @@ The YAML and frontend configuration methods support all of the options listed be
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
| Variable name | Description | Default | Type |
|:--------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------|:----------------------------------------|
| `lights` | List of light entity_ids to be controlled (may be empty). 🌟 | `[]` | list of `entity_id`s |
| `interval` | Frequency to adapt the lights, in seconds. 🔄 | `90` | `int > 0` |
| `transition` | Duration of transition when lights change, in seconds. 🕑 | `45` | `float` 0-6553 |
| `initial_transition` | Duration of the first transition when lights turn from `off` to `on` in seconds. ⏲️ | `1` | `float` 0-6553 |
| `min_brightness` | Minimum brightness percentage. 💡 | `1` | `int` 1-100 |
| `max_brightness` | Maximum brightness percentage. 💡 | `100` | `int` 1-100 |
| `min_color_temp` | Warmest color temperature in Kelvin. 🔥 | `2000` | `int` 1000-10000 |
| `max_color_temp` | Coldest color temperature in Kelvin. ❄️ | `5500` | `int` 1000-10000 |
| `prefer_rgb_color` | Whether to prefer RGB color adjustment over light color temperature when possible. 🌈 | `False` | `bool` |
| `sleep_brightness` | Brightness percentage of lights in sleep mode. 😴 | `1` | `int` 1-100 |
| `sleep_rgb_or_color_temp` | Use either `"rgb_color"` or `"color_temp"` in sleep mode. 🌙 | `color_temp` | one of `['color_temp', 'rgb_color']` |
| `sleep_color_temp` | Color temperature in sleep mode (used when `sleep_rgb_or_color_temp` is `color_temp`) in Kelvin. 😴 | `1000` | `int` 1000-10000 |
| `sleep_rgb_color` | RGB color in sleep mode (used when `sleep_rgb_or_color_temp` is "rgb_color"). 🌈 | `[255, 56, 0]` | RGB color |
| `sleep_transition` | Duration of transition when "sleep mode" is toggled in seconds. 😴 | `1` | `float` 0-6553 |
| `transition_until_sleep` | When enabled, Adaptive Lighting will treat sleep settings as the minimum, transitioning to these values after sunset. 🌙 | `False` | `bool` |
| `sunrise_time` | Set a fixed time (HH:MM:SS) for sunrise. 🌅 | `None` | `str` |
| `min_sunrise_time` | Set the earliest virtual sunrise time (HH:MM:SS), allowing for later sunrises. 🌅 | `None` | `str` |
| `max_sunrise_time` | Set the latest virtual sunrise time (HH:MM:SS), allowing for earlier sunrises. 🌅 | `None` | `str` |
| `sunrise_offset` | Adjust sunrise time with a positive or negative offset in seconds. ⏰ | `0` | `int` |
| `sunset_time` | Set a fixed time (HH:MM:SS) for sunset. 🌇 | `None` | `str` |
| `min_sunset_time` | Set the earliest virtual sunset time (HH:MM:SS), allowing for later sunsets. 🌇 | `None` | `str` |
| `max_sunset_time` | Set the latest virtual sunset time (HH:MM:SS), allowing for earlier sunsets. 🌇 | `None` | `str` |
| `sunset_offset` | Adjust sunset time with a positive or negative offset in seconds. ⏰ | `0` | `int` |
| `brightness_mode` | Brightness mode to use. Possible values are `default`, `linear`, and `tanh` (uses `brightness_mode_time_dark` and `brightness_mode_time_light`). 📈 | `default` | one of `['default', 'linear', 'tanh']` |
| `brightness_mode_time_dark` | (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness before/after sunrise/sunset. 📈📉 | `900` | `int` |
| `brightness_mode_time_light` | (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness after/before sunrise/sunset. 📈📉. | `3600` | `int` |
| `take_over_control` | Pause adaptation of individual lights and hand over (manual) control to other sources that issue `light.turn_on` calls for lights that are on. 🔒 | `True` | `bool` |
| `take_over_control_mode` | The adaptation pausing mode when other sources change brightness and/or color of lights. `pause_all` always pauses both brightness and color adaptation. `pause_changed` pauses the adaptation of only the changed attributes and continues adapting unchanged attributes, e.g., continues color adaptation when only brightness was changed. | `pause_all` | one of `['pause_all', 'pause_changed']` |
| `detect_non_ha_changes` | Detects and halts adaptations for non-`light.turn_on` state changes. Needs `take_over_control` enabled. 🕵️ Caution: ⚠️ Some lights might falsely indicate an 'on' state, which could result in lights turning on unexpectedly. Note that this calls `homeassistant.update_entity` every `interval`! Disable this feature if you encounter such issues. | `False` | `bool` |
| `autoreset_control_seconds` | Automatically reset the manual control after a number of seconds. Set to 0 to disable. ⏲️ | `0` | `int` 0-31536000 |
| `only_once` | Adapt lights only when they are turned on (`true`) or keep adapting them (`false`). 🔄 | `False` | `bool` |
| `adapt_only_on_bare_turn_on` | When turning lights on initially. If set to `true`, AL adapts only if `light.turn_on` is invoked without specifying color or brightness. ❌🌈 This e.g., prevents adaptation when activating a scene and marks the light as manually controlled. If `false`, AL adapts regardless of the presence of color or brightness in the initial `service_data`. Needs `take_over_control` enabled. 🕵️ | `False` | `bool` |
| `reset_manual_control_on_sleep_mode_change` | Reset manual control when the sleep mode switch is toggled. Set to `false` to preserve manual control across sleep mode changes. 😴 | `True` | `bool` |
| `separate_turn_on_commands` | Use separate `light.turn_on` calls for color and brightness, needed for some light types. 🔀 | `False` | `bool` |
| `send_split_delay` | Delay (ms) between `separate_turn_on_commands` for lights that don't support simultaneous brightness and color setting. ⏲️ | `0` | `int` 0-10000 |
| `adapt_delay` | Wait time (seconds) between light turn on and Adaptive Lighting applying changes. Might help to avoid flickering. ⏲️ | `0` | `float > 0` |
| `skip_redundant_commands` | Skip sending adaptation commands whose target state already equals the light's known state. Minimizes network traffic and improves the adaptation responsivity in some situations. 📉Disable if physical light states get out of sync with HA's recorded state. | `False` | `bool` |
| `intercept` | Intercept and adapt `light.turn_on` calls to enabling instantaneous color and brightness adaptation. 🏎️ Disable for lights that do not support `light.turn_on` with color and brightness. | `True` | `bool` |
| `multi_light_intercept` | Intercept and adapt `light.turn_on` calls that target multiple lights. ➗⚠️ This might result in splitting up a single `light.turn_on` call into multiple calls, e.g., when lights are in different switches. Requires `intercept` to be enabled. | `True` | `bool` |
| `include_config_in_attributes` | Show all options as attributes on the switch in Home Assistant when set to `true`. 📝 | `False` | `bool` |
| Variable name | Description | Default | Type |
|:--------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------|:----------------------------------------|
| `lights` | List of light entity_ids to be controlled (may be empty). 🌟 | `[]` | list of `entity_id`s |
| `interval` | Frequency to adapt the lights, in seconds. 🔄 | `90` | `int > 0` |
| `transition` | Duration of transition when lights change, in seconds. 🕑 | `45` | `float` 0-6553 |
| `initial_transition` | Duration of the first transition when lights turn from `off` to `on` in seconds. ⏲️ | `1` | `float` 0-6553 |
| `min_brightness` | Minimum brightness percentage. 💡 | `1` | `int` 1-100 |
| `max_brightness` | Maximum brightness percentage. 💡 | `100` | `int` 1-100 |
| `min_color_temp` | Warmest color temperature in Kelvin. 🔥 | `2000` | `int` 1000-10000 |
| `max_color_temp` | Coldest color temperature in Kelvin. ❄️ | `5500` | `int` 1000-10000 |
| `prefer_rgb_color` | Whether to prefer RGB color adjustment over light color temperature when possible. 🌈 | `False` | `bool` |
| `sleep_brightness` | Brightness percentage of lights in sleep mode. 😴 | `1` | `int` 1-100 |
| `sleep_rgb_or_color_temp` | Use either `"rgb_color"` or `"color_temp"` in sleep mode. 🌙 | `color_temp` | one of `['color_temp', 'rgb_color']` |
| `sleep_color_temp` | Color temperature in sleep mode (used when `sleep_rgb_or_color_temp` is `color_temp`) in Kelvin. 😴 | `1000` | `int` 1000-10000 |
| `sleep_rgb_color` | RGB color in sleep mode (used when `sleep_rgb_or_color_temp` is "rgb_color"). 🌈 | `[255, 56, 0]` | RGB color |
| `sleep_transition` | Duration of transition when "sleep mode" is toggled in seconds. 😴 | `1` | `float` 0-6553 |
| `transition_until_sleep` | When enabled, Adaptive Lighting will treat sleep settings as the minimum, transitioning to these values after sunset. 🌙 | `False` | `bool` |
| `sunrise_time` | Set a fixed time (HH:MM:SS) for sunrise. 🌅 | `None` | `str` |
| `min_sunrise_time` | Set the earliest virtual sunrise time (HH:MM:SS), allowing for later sunrises. 🌅 | `None` | `str` |
| `max_sunrise_time` | Set the latest virtual sunrise time (HH:MM:SS), allowing for earlier sunrises. 🌅 | `None` | `str` |
| `sunrise_offset` | Adjust sunrise time with a positive or negative offset in seconds. ⏰ | `0` | `int` |
| `sunset_time` | Set a fixed time (HH:MM:SS) for sunset. 🌇 | `None` | `str` |
| `min_sunset_time` | Set the earliest virtual sunset time (HH:MM:SS), allowing for later sunsets. 🌇 | `None` | `str` |
| `max_sunset_time` | Set the latest virtual sunset time (HH:MM:SS), allowing for earlier sunsets. 🌇 | `None` | `str` |
| `sunset_offset` | Adjust sunset time with a positive or negative offset in seconds. ⏰ | `0` | `int` |
| `brightness_mode` | Brightness mode to use. Possible values are `default`, `linear`, and `tanh` (uses `brightness_mode_time_dark` and `brightness_mode_time_light`). 📈 | `default` | one of `['default', 'linear', 'tanh']` |
| `brightness_mode_time_dark` | (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness before/after sunrise/sunset. 📈📉 | `900` | `int` |
| `brightness_mode_time_light` | (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness after/before sunrise/sunset. 📈📉. | `3600` | `int` |
| `take_over_control` | Pause adaptation of individual lights and hand over (manual) control to other sources that issue `light.turn_on` calls for lights that are on. 🔒 | `True` | `bool` |
| `take_over_control_mode` | The adaptation pausing mode when other sources change brightness and/or color of lights. `pause_all` always pauses both brightness and color adaptation. `pause_changed` pauses the adaptation of only the changed attributes and continues adapting unchanged attributes, e.g., continues color adaptation when only brightness was changed. | `pause_all` | one of `['pause_all', 'pause_changed']` |
| `detect_non_ha_changes` | Detects and halts adaptations for non-`light.turn_on` state changes. Needs `take_over_control` enabled. 🕵️ Caution: ⚠️ Some lights might falsely indicate an 'on' state, which could result in lights turning on unexpectedly. Note that this calls `homeassistant.update_entity` every `interval`! Disable this feature if you encounter such issues. | `False` | `bool` |
| `autoreset_control_seconds` | Automatically reset the manual control after a number of seconds. Set to 0 to disable. ⏲️ | `0` | `int` 0-31536000 |
| `only_once` | Adapt lights only when they are turned on (`true`) or keep adapting them (`false`). 🔄 | `False` | `bool` |
| `adapt_only_on_bare_turn_on` | When turning lights on initially. If set to `true`, AL adapts only if `light.turn_on` is invoked without specifying color or brightness. ❌🌈 This e.g., prevents adaptation when activating a scene and marks the light as manually controlled. If `false`, AL adapts regardless of the presence of color or brightness in the initial `service_data`. Needs `take_over_control` enabled. 🕵️ | `False` | `bool` |
| `reset_manual_control_on_sleep_mode_change` | Reset manual control when the sleep mode switch is toggled. Set to `false` to preserve manual control across sleep mode changes. 😴 | `True` | `bool` |
| `separate_turn_on_commands` | Use separate `light.turn_on` calls for color and brightness, needed for some light types. 🔀 | `False` | `bool` |
| `send_split_delay` | Delay (ms) between `separate_turn_on_commands` for lights that don't support simultaneous brightness and color setting. ⏲️ | `0` | `int` 0-10000 |
| `adapt_delay` | Wait time (seconds) between light turn on and Adaptive Lighting applying changes. Might help to avoid flickering. ⏲️ | `0` | `float > 0` |
| `skip_redundant_commands` | Skip sending adaptation commands whose target state already equals the light's known state. Minimizes network traffic and improves the adaptation responsivity in some situations. 📉Disable if physical light states get out of sync with HA's recorded state. | `False` | `bool` |
| `skip_brightness_increases` | Prevent automatic adaptation from increasing brightness above the light's reported numeric brightness, while still adapting to lower brightness targets and adapting color. A retained brightness on an off light is also used as the ceiling. If brightness is missing or non-numeric, the calculated target is used. Bare turn-on and leaving sleep mode may therefore keep a light dim until you request a brighter level directly or disable this option. This option does not override manual-control pauses. | `False` | `bool` |
| `intercept` | Intercept and adapt `light.turn_on` calls to enabling instantaneous color and brightness adaptation. 🏎️ Disable for lights that do not support `light.turn_on` with color and brightness. | `True` | `bool` |
| `multi_light_intercept` | Intercept and adapt `light.turn_on` calls that target multiple lights. ➗⚠️ This might result in splitting up a single `light.turn_on` call into multiple calls, e.g., when lights are in different switches. Requires `intercept` to be enabled. | `True` | `bool` |
| `include_config_in_attributes` | Show all options as attributes on the switch in Home Assistant when set to `true`. 📝 | `False` | `bool` |
<!-- OUTPUT:END -->

View file

@ -169,11 +169,21 @@ def _remove_brightness_increases(
service_data: ServiceData,
state: State,
) -> ServiceData:
"""Filter service data by removing brightness increases."""
"""Filter brightness targets above the light's reported numeric value."""
current_brightness = state.attributes.get(ATTR_BRIGHTNESS)
if not isinstance(current_brightness, (int, float)) or isinstance(
current_brightness,
bool,
):
return dict(service_data)
return {
k: v
for k, v in service_data.items()
if k != ATTR_BRIGHTNESS or k not in state.attributes or v <= state.attributes[k]
if k != ATTR_BRIGHTNESS
or not isinstance(v, (int, float))
or isinstance(v, bool)
or v <= current_brightness
}
@ -192,7 +202,7 @@ async def _create_service_call_data_iterator(
hass: HomeAssistant,
service_datas: list[ServiceData],
filter_by_state: bool,
skip_brightness_increases: bool,
skip_brightness_increases: bool = False,
) -> AsyncGenerator[ServiceData]:
"""Enumerates and filters a list of service datas on the fly.
@ -296,7 +306,7 @@ def prepare_adaptation_data(
split: bool,
filter_by_state: bool,
force: bool,
skip_brightness_increases: bool,
skip_brightness_increases: bool = False,
already_applied: LightControlAttributes = LightControlAttributes.NONE,
) -> AdaptationData:
"""Prepares a data object carrying all data required to execute an adaptation."""

View file

@ -268,10 +268,13 @@ CONF_SKIP_BRIGHTNESS_INCREASES, DEFAULT_SKIP_BRIGHTNESS_INCREASES = (
False,
)
DOCS[CONF_SKIP_BRIGHTNESS_INCREASES] = (
"Skip sending adaptation commands when the target brightness "
"is greater than the current entity brightness. Will "
"result in lights which have been manually dimmed "
"not increasing in brightness."
"Prevent automatic adaptation from increasing brightness above the light's "
"reported numeric brightness, while still adapting to lower brightness targets "
"and adapting color. A retained brightness on an off light is also used as the "
"ceiling. If brightness is missing or non-numeric, the calculated target is used. "
"Bare turn-on and leaving sleep mode may therefore keep a light dim until you "
"request a brighter level directly or disable this option. This option does not "
"override manual-control pauses."
)
CONF_INTERCEPT, DEFAULT_INTERCEPT = "intercept", True

View file

@ -250,6 +250,12 @@ change_switch_settings:
example: 0
selector:
text: null
skip_brightness_increases:
description: Prevent automatic adaptation from increasing brightness above the light's reported numeric brightness, while still adapting to lower brightness targets and adapting color. A retained brightness on an off light is also used as the ceiling. If brightness is missing or non-numeric, the calculated target is used. Bare turn-on and leaving sleep mode may therefore keep a light dim until you request a brighter level directly or disable this option. This option does not override manual-control pauses.
required: false
example: false
selector:
boolean: null
autoreset_control_seconds:
description: Automatically reset the manual control after a number of seconds. Set to 0 to disable. ⏲️
required: false

View file

@ -75,6 +75,7 @@
"send_split_delay": "send_split_delay",
"adapt_delay": "adapt_delay",
"skip_redundant_commands": "skip_redundant_commands: Skip sending adaptation commands whose target state already equals the light's known state. Minimizes network traffic and improves the adaptation responsivity in some situations. 📉Disable if physical light states get out of sync with HA's recorded state.",
"skip_brightness_increases": "skip_brightness_increases: Prevent automatic adaptation from increasing brightness above the light's reported numeric brightness, while still adapting to lower brightness targets and adapting color. A retained brightness on an off light is also used as the ceiling. If brightness is missing or non-numeric, the calculated target is used. Bare turn-on and leaving sleep mode may therefore keep a light dim until you request a brighter level directly or disable this option. This option does not override manual-control pauses.",
"intercept": "intercept: Intercept and adapt `light.turn_on` calls to enabling instantaneous color and brightness adaptation. 🏎️ Disable for lights that do not support `light.turn_on` with color and brightness.",
"multi_light_intercept": "multi_light_intercept: Intercept and adapt `light.turn_on` calls that target multiple lights. ➗⚠️ This might result in splitting up a single `light.turn_on` call into multiple calls, e.g., when lights are in different switches. Requires `intercept` to be enabled.",
"include_config_in_attributes": "include_config_in_attributes: Show all options as attributes on the switch in Home Assistant when set to `true`. 📝"
@ -278,6 +279,10 @@
"description": "Wait time (seconds) between light turn on and Adaptive Lighting applying changes. Might help to avoid flickering. ⏲️",
"name": "adapt_delay"
},
"skip_brightness_increases": {
"description": "Prevent automatic adaptation from increasing brightness above the light's reported numeric brightness, while still adapting to lower brightness targets and adapting color. A retained brightness on an off light is also used as the ceiling. If brightness is missing or non-numeric, the calculated target is used. Bare turn-on and leaving sleep mode may therefore keep a light dim until you request a brighter level directly or disable this option. This option does not override manual-control pauses.",
"name": "skip_brightness_increases"
},
"autoreset_control_seconds": {
"description": "Automatically reset the manual control after a number of seconds. Set to 0 to disable. ⏲️",
"name": "autoreset_control_seconds"

View file

@ -76,6 +76,7 @@
"send_split_delay": "send_split_delay",
"adapt_delay": "adapt_delay",
"skip_redundant_commands": "skip_redundant_commands: Skip sending adaptation commands whose target state already equals the light's known state. Minimizes network traffic and improves the adaptation responsivity in some situations. 📉Disable if physical light states get out of sync with HA's recorded state.",
"skip_brightness_increases": "skip_brightness_increases: Prevent automatic adaptation from increasing brightness above the light's reported numeric brightness, while still adapting to lower brightness targets and adapting color. A retained brightness on an off light is also used as the ceiling. If brightness is missing or non-numeric, the calculated target is used. Bare turn-on and leaving sleep mode may therefore keep a light dim until you request a brighter level directly or disable this option. This option does not override manual-control pauses.",
"intercept": "intercept: Intercept and adapt `light.turn_on` calls to enabling instantaneous color and brightness adaptation. 🏎️ Disable for lights that do not support `light.turn_on` with color and brightness.",
"multi_light_intercept": "multi_light_intercept: Intercept and adapt `light.turn_on` calls that target multiple lights. ➗⚠️ This might result in splitting up a single `light.turn_on` call into multiple calls, e.g., when lights are in different switches. Requires `intercept` to be enabled.",
"include_config_in_attributes": "include_config_in_attributes: Show all options as attributes on the switch in Home Assistant when set to `true`. 📝"
@ -279,6 +280,10 @@
"description": "Wait time (seconds) between light turn on and Adaptive Lighting applying changes. Might help to avoid flickering. ⏲️",
"name": "adapt_delay"
},
"skip_brightness_increases": {
"description": "Prevent automatic adaptation from increasing brightness above the light's reported numeric brightness, while still adapting to lower brightness targets and adapting color. A retained brightness on an off light is also used as the ceiling. If brightness is missing or non-numeric, the calculated target is used. Bare turn-on and leaving sleep mode may therefore keep a light dim until you request a brighter level directly or disable this option. This option does not override manual-control pauses.",
"name": "skip_brightness_increases"
},
"autoreset_control_seconds": {
"description": "Automatically reset the manual control after a number of seconds. Set to 0 to disable. ⏲️",
"name": "autoreset_control_seconds"

View file

@ -28,6 +28,10 @@ The Adaptive Lighting switch exposes these read-only attributes for its lights:
These lists report manual-control flags. Actual adaptation also depends on `take_over_control_mode` and the brightness/color adaptation switches. For example, under the default `pause_all` mode, manually changing only brightness leaves `manual_control_color` empty while pausing both brightness and color adaptation. Under `pause_changed`, color can continue adapting.
The `skip_brightness_increases` option provides a dim-only policy for automatic adaptation. Adaptive Lighting can lower brightness and continue adapting color, but it will not raise brightness above the light's reported numeric value. To keep adapting after direct or physical brightness changes, use `take_over_control: false` and `detect_non_ha_changes: false`; otherwise the existing `pause_all` or `pause_changed` manual-control policy can pause adaptation before this brightness ceiling is applied.
This option does not store a brightness to restore later. A retained brightness reported while a light is off remains the ceiling on a bare turn-on, and leaving sleep mode does not necessarily restore the normal brighter target. Send a direct brightness request or disable `skip_brightness_increases` when you want to brighten the light. If the light reports no numeric brightness, Adaptive Lighting uses its calculated target.
The attributes are absent when the Adaptive Lighting switch is off. Use a fallback when checking them in templates:
```jinja

View file

@ -35,6 +35,8 @@ Sleep mode is configured through the main Adaptive Lighting configuration. See t
| `sleep_transition` | 1 | Transition duration in seconds |
| `transition_until_sleep` | false | Gradually transition to sleep settings after sunset |
With `skip_brightness_increases` enabled, leaving sleep mode does not necessarily restore the normal brighter target. The light's reported sleep brightness remains the automatic ceiling because Adaptive Lighting does not store restoration state. Send a direct brightness request or disable `skip_brightness_increases` when you want to brighten the light.
## Automation Examples
See [Automation Examples](../automation-examples.md) for sleep mode automation recipes, including:

View file

@ -32,48 +32,49 @@ All configuration options are listed below with their default values. These opti
<!-- CODE:END -->
<!-- OUTPUT:START -->
<!-- ⚠️ This content is auto-generated by `markdown-code-runner`. -->
| Variable name | Description | Default | Type |
|:--------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------|:----------------------------------------|
| `lights` | List of light entity_ids to be controlled (may be empty). 🌟 | `[]` | list of `entity_id`s |
| `interval` | Frequency to adapt the lights, in seconds. 🔄 | `90` | `int > 0` |
| `transition` | Duration of transition when lights change, in seconds. 🕑 | `45` | `float` 0-6553 |
| `initial_transition` | Duration of the first transition when lights turn from `off` to `on` in seconds. ⏲️ | `1` | `float` 0-6553 |
| `min_brightness` | Minimum brightness percentage. 💡 | `1` | `int` 1-100 |
| `max_brightness` | Maximum brightness percentage. 💡 | `100` | `int` 1-100 |
| `min_color_temp` | Warmest color temperature in Kelvin. 🔥 | `2000` | `int` 1000-10000 |
| `max_color_temp` | Coldest color temperature in Kelvin. ❄️ | `5500` | `int` 1000-10000 |
| `prefer_rgb_color` | Whether to prefer RGB color adjustment over light color temperature when possible. 🌈 | `False` | `bool` |
| `sleep_brightness` | Brightness percentage of lights in sleep mode. 😴 | `1` | `int` 1-100 |
| `sleep_rgb_or_color_temp` | Use either `"rgb_color"` or `"color_temp"` in sleep mode. 🌙 | `color_temp` | one of `['color_temp', 'rgb_color']` |
| `sleep_color_temp` | Color temperature in sleep mode (used when `sleep_rgb_or_color_temp` is `color_temp`) in Kelvin. 😴 | `1000` | `int` 1000-10000 |
| `sleep_rgb_color` | RGB color in sleep mode (used when `sleep_rgb_or_color_temp` is "rgb_color"). 🌈 | `[255, 56, 0]` | RGB color |
| `sleep_transition` | Duration of transition when "sleep mode" is toggled in seconds. 😴 | `1` | `float` 0-6553 |
| `transition_until_sleep` | When enabled, Adaptive Lighting will treat sleep settings as the minimum, transitioning to these values after sunset. 🌙 | `False` | `bool` |
| `sunrise_time` | Set a fixed time (HH:MM:SS) for sunrise. 🌅 | `None` | `str` |
| `min_sunrise_time` | Set the earliest virtual sunrise time (HH:MM:SS), allowing for later sunrises. 🌅 | `None` | `str` |
| `max_sunrise_time` | Set the latest virtual sunrise time (HH:MM:SS), allowing for earlier sunrises. 🌅 | `None` | `str` |
| `sunrise_offset` | Adjust sunrise time with a positive or negative offset in seconds. ⏰ | `0` | `int` |
| `sunset_time` | Set a fixed time (HH:MM:SS) for sunset. 🌇 | `None` | `str` |
| `min_sunset_time` | Set the earliest virtual sunset time (HH:MM:SS), allowing for later sunsets. 🌇 | `None` | `str` |
| `max_sunset_time` | Set the latest virtual sunset time (HH:MM:SS), allowing for earlier sunsets. 🌇 | `None` | `str` |
| `sunset_offset` | Adjust sunset time with a positive or negative offset in seconds. ⏰ | `0` | `int` |
| `brightness_mode` | Brightness mode to use. Possible values are `default`, `linear`, and `tanh` (uses `brightness_mode_time_dark` and `brightness_mode_time_light`). 📈 | `default` | one of `['default', 'linear', 'tanh']` |
| `brightness_mode_time_dark` | (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness before/after sunrise/sunset. 📈📉 | `900` | `int` |
| `brightness_mode_time_light` | (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness after/before sunrise/sunset. 📈📉. | `3600` | `int` |
| `take_over_control` | Pause adaptation of individual lights and hand over (manual) control to other sources that issue `light.turn_on` calls for lights that are on. 🔒 | `True` | `bool` |
| `take_over_control_mode` | The adaptation pausing mode when other sources change brightness and/or color of lights. `pause_all` always pauses both brightness and color adaptation. `pause_changed` pauses the adaptation of only the changed attributes and continues adapting unchanged attributes, e.g., continues color adaptation when only brightness was changed. | `pause_all` | one of `['pause_all', 'pause_changed']` |
| `detect_non_ha_changes` | Detects and halts adaptations for non-`light.turn_on` state changes. Needs `take_over_control` enabled. 🕵️ Caution: ⚠️ Some lights might falsely indicate an 'on' state, which could result in lights turning on unexpectedly. Note that this calls `homeassistant.update_entity` every `interval`! Disable this feature if you encounter such issues. | `False` | `bool` |
| `autoreset_control_seconds` | Automatically reset the manual control after a number of seconds. Set to 0 to disable. ⏲️ | `0` | `int` 0-31536000 |
| `only_once` | Adapt lights only when they are turned on (`true`) or keep adapting them (`false`). 🔄 | `False` | `bool` |
| `adapt_only_on_bare_turn_on` | When turning lights on initially. If set to `true`, AL adapts only if `light.turn_on` is invoked without specifying color or brightness. ❌🌈 This e.g., prevents adaptation when activating a scene and marks the light as manually controlled. If `false`, AL adapts regardless of the presence of color or brightness in the initial `service_data`. Needs `take_over_control` enabled. 🕵️ | `False` | `bool` |
| `reset_manual_control_on_sleep_mode_change` | Reset manual control when the sleep mode switch is toggled. Set to `false` to preserve manual control across sleep mode changes. 😴 | `True` | `bool` |
| `separate_turn_on_commands` | Use separate `light.turn_on` calls for color and brightness, needed for some light types. 🔀 | `False` | `bool` |
| `send_split_delay` | Delay (ms) between `separate_turn_on_commands` for lights that don't support simultaneous brightness and color setting. ⏲️ | `0` | `int` 0-10000 |
| `adapt_delay` | Wait time (seconds) between light turn on and Adaptive Lighting applying changes. Might help to avoid flickering. ⏲️ | `0` | `float > 0` |
| `skip_redundant_commands` | Skip sending adaptation commands whose target state already equals the light's known state. Minimizes network traffic and improves the adaptation responsivity in some situations. 📉Disable if physical light states get out of sync with HA's recorded state. | `False` | `bool` |
| `intercept` | Intercept and adapt `light.turn_on` calls to enabling instantaneous color and brightness adaptation. 🏎️ Disable for lights that do not support `light.turn_on` with color and brightness. | `True` | `bool` |
| `multi_light_intercept` | Intercept and adapt `light.turn_on` calls that target multiple lights. ➗⚠️ This might result in splitting up a single `light.turn_on` call into multiple calls, e.g., when lights are in different switches. Requires `intercept` to be enabled. | `True` | `bool` |
| `include_config_in_attributes` | Show all options as attributes on the switch in Home Assistant when set to `true`. 📝 | `False` | `bool` |
| Variable name | Description | Default | Type |
|:--------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------|:----------------------------------------|
| `lights` | List of light entity_ids to be controlled (may be empty). 🌟 | `[]` | list of `entity_id`s |
| `interval` | Frequency to adapt the lights, in seconds. 🔄 | `90` | `int > 0` |
| `transition` | Duration of transition when lights change, in seconds. 🕑 | `45` | `float` 0-6553 |
| `initial_transition` | Duration of the first transition when lights turn from `off` to `on` in seconds. ⏲️ | `1` | `float` 0-6553 |
| `min_brightness` | Minimum brightness percentage. 💡 | `1` | `int` 1-100 |
| `max_brightness` | Maximum brightness percentage. 💡 | `100` | `int` 1-100 |
| `min_color_temp` | Warmest color temperature in Kelvin. 🔥 | `2000` | `int` 1000-10000 |
| `max_color_temp` | Coldest color temperature in Kelvin. ❄️ | `5500` | `int` 1000-10000 |
| `prefer_rgb_color` | Whether to prefer RGB color adjustment over light color temperature when possible. 🌈 | `False` | `bool` |
| `sleep_brightness` | Brightness percentage of lights in sleep mode. 😴 | `1` | `int` 1-100 |
| `sleep_rgb_or_color_temp` | Use either `"rgb_color"` or `"color_temp"` in sleep mode. 🌙 | `color_temp` | one of `['color_temp', 'rgb_color']` |
| `sleep_color_temp` | Color temperature in sleep mode (used when `sleep_rgb_or_color_temp` is `color_temp`) in Kelvin. 😴 | `1000` | `int` 1000-10000 |
| `sleep_rgb_color` | RGB color in sleep mode (used when `sleep_rgb_or_color_temp` is "rgb_color"). 🌈 | `[255, 56, 0]` | RGB color |
| `sleep_transition` | Duration of transition when "sleep mode" is toggled in seconds. 😴 | `1` | `float` 0-6553 |
| `transition_until_sleep` | When enabled, Adaptive Lighting will treat sleep settings as the minimum, transitioning to these values after sunset. 🌙 | `False` | `bool` |
| `sunrise_time` | Set a fixed time (HH:MM:SS) for sunrise. 🌅 | `None` | `str` |
| `min_sunrise_time` | Set the earliest virtual sunrise time (HH:MM:SS), allowing for later sunrises. 🌅 | `None` | `str` |
| `max_sunrise_time` | Set the latest virtual sunrise time (HH:MM:SS), allowing for earlier sunrises. 🌅 | `None` | `str` |
| `sunrise_offset` | Adjust sunrise time with a positive or negative offset in seconds. ⏰ | `0` | `int` |
| `sunset_time` | Set a fixed time (HH:MM:SS) for sunset. 🌇 | `None` | `str` |
| `min_sunset_time` | Set the earliest virtual sunset time (HH:MM:SS), allowing for later sunsets. 🌇 | `None` | `str` |
| `max_sunset_time` | Set the latest virtual sunset time (HH:MM:SS), allowing for earlier sunsets. 🌇 | `None` | `str` |
| `sunset_offset` | Adjust sunset time with a positive or negative offset in seconds. ⏰ | `0` | `int` |
| `brightness_mode` | Brightness mode to use. Possible values are `default`, `linear`, and `tanh` (uses `brightness_mode_time_dark` and `brightness_mode_time_light`). 📈 | `default` | one of `['default', 'linear', 'tanh']` |
| `brightness_mode_time_dark` | (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness before/after sunrise/sunset. 📈📉 | `900` | `int` |
| `brightness_mode_time_light` | (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness after/before sunrise/sunset. 📈📉. | `3600` | `int` |
| `take_over_control` | Pause adaptation of individual lights and hand over (manual) control to other sources that issue `light.turn_on` calls for lights that are on. 🔒 | `True` | `bool` |
| `take_over_control_mode` | The adaptation pausing mode when other sources change brightness and/or color of lights. `pause_all` always pauses both brightness and color adaptation. `pause_changed` pauses the adaptation of only the changed attributes and continues adapting unchanged attributes, e.g., continues color adaptation when only brightness was changed. | `pause_all` | one of `['pause_all', 'pause_changed']` |
| `detect_non_ha_changes` | Detects and halts adaptations for non-`light.turn_on` state changes. Needs `take_over_control` enabled. 🕵️ Caution: ⚠️ Some lights might falsely indicate an 'on' state, which could result in lights turning on unexpectedly. Note that this calls `homeassistant.update_entity` every `interval`! Disable this feature if you encounter such issues. | `False` | `bool` |
| `autoreset_control_seconds` | Automatically reset the manual control after a number of seconds. Set to 0 to disable. ⏲️ | `0` | `int` 0-31536000 |
| `only_once` | Adapt lights only when they are turned on (`true`) or keep adapting them (`false`). 🔄 | `False` | `bool` |
| `adapt_only_on_bare_turn_on` | When turning lights on initially. If set to `true`, AL adapts only if `light.turn_on` is invoked without specifying color or brightness. ❌🌈 This e.g., prevents adaptation when activating a scene and marks the light as manually controlled. If `false`, AL adapts regardless of the presence of color or brightness in the initial `service_data`. Needs `take_over_control` enabled. 🕵️ | `False` | `bool` |
| `reset_manual_control_on_sleep_mode_change` | Reset manual control when the sleep mode switch is toggled. Set to `false` to preserve manual control across sleep mode changes. 😴 | `True` | `bool` |
| `separate_turn_on_commands` | Use separate `light.turn_on` calls for color and brightness, needed for some light types. 🔀 | `False` | `bool` |
| `send_split_delay` | Delay (ms) between `separate_turn_on_commands` for lights that don't support simultaneous brightness and color setting. ⏲️ | `0` | `int` 0-10000 |
| `adapt_delay` | Wait time (seconds) between light turn on and Adaptive Lighting applying changes. Might help to avoid flickering. ⏲️ | `0` | `float > 0` |
| `skip_redundant_commands` | Skip sending adaptation commands whose target state already equals the light's known state. Minimizes network traffic and improves the adaptation responsivity in some situations. 📉Disable if physical light states get out of sync with HA's recorded state. | `False` | `bool` |
| `skip_brightness_increases` | Prevent automatic adaptation from increasing brightness above the light's reported numeric brightness, while still adapting to lower brightness targets and adapting color. A retained brightness on an off light is also used as the ceiling. If brightness is missing or non-numeric, the calculated target is used. Bare turn-on and leaving sleep mode may therefore keep a light dim until you request a brighter level directly or disable this option. This option does not override manual-control pauses. | `False` | `bool` |
| `intercept` | Intercept and adapt `light.turn_on` calls to enabling instantaneous color and brightness adaptation. 🏎️ Disable for lights that do not support `light.turn_on` with color and brightness. | `True` | `bool` |
| `multi_light_intercept` | Intercept and adapt `light.turn_on` calls that target multiple lights. ➗⚠️ This might result in splitting up a single `light.turn_on` call into multiple calls, e.g., when lights are in different switches. Requires `intercept` to be enabled. | `True` | `bool` |
| `include_config_in_attributes` | Show all options as attributes on the switch in Home Assistant when set to `true`. 📝 | `False` | `bool` |
<!-- OUTPUT:END -->

View file

@ -8,6 +8,7 @@ from homeassistant.components.adaptive_lighting.adaptation_utils import (
ServiceData,
_create_service_call_data_iterator,
_has_relevant_service_data_attributes,
_remove_brightness_increases,
_remove_redundant_attributes,
_split_service_call_data,
get_light_control_attributes,
@ -26,7 +27,7 @@ from homeassistant.components.light import (
ATTR_HS_COLOR,
ATTR_TRANSITION,
)
from homeassistant.const import ATTR_ENTITY_ID, STATE_ON
from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON
from homeassistant.core import Context, State
@ -182,6 +183,51 @@ async def test_remove_redundant_attributes(
assert _remove_redundant_attributes(service_data, state) == service_data_expected
@pytest.mark.parametrize(
("target", "attributes", "state", "brightness_expected"),
[
(101, {ATTR_BRIGHTNESS: 100}, STATE_ON, False),
(100, {ATTR_BRIGHTNESS: 100}, STATE_ON, True),
(99, {ATTR_BRIGHTNESS: 100}, STATE_ON, True),
(101, {}, STATE_ON, True),
(101, {ATTR_BRIGHTNESS: None}, STATE_ON, True),
(101, {ATTR_BRIGHTNESS: "unknown"}, STATE_ON, True),
(101, {}, STATE_OFF, True),
(101, {ATTR_BRIGHTNESS: 100}, STATE_OFF, False),
],
ids=[
"target above reported ceiling",
"target equal to reported ceiling",
"target below reported ceiling",
"missing reported brightness",
"none reported brightness",
"non-numeric reported brightness",
"off without retained brightness",
"off with retained brightness",
],
)
def test_remove_brightness_increases_uses_reported_numeric_ceiling(
target,
attributes,
state,
brightness_expected,
):
"""Only a reported numeric brightness may cap an automatic target."""
service_data = {
ATTR_ENTITY_ID: "light.test",
ATTR_BRIGHTNESS: target,
ATTR_COLOR_TEMP_KELVIN: 3000,
}
filtered = _remove_brightness_increases(
service_data,
State("light.test", state, attributes),
)
assert (ATTR_BRIGHTNESS in filtered) is brightness_expected
assert filtered[ATTR_COLOR_TEMP_KELVIN] == 3000
@pytest.mark.parametrize(
("service_data", "expected_relevant"),
[

View file

@ -40,12 +40,14 @@ from homeassistant.components.adaptive_lighting.const import (
CONF_INITIAL_TRANSITION,
CONF_MANUAL_CONTROL,
CONF_MAX_BRIGHTNESS,
CONF_MAX_COLOR_TEMP,
CONF_MIN_BRIGHTNESS,
CONF_MIN_COLOR_TEMP,
CONF_MULTI_LIGHT_INTERCEPT,
CONF_PREFER_RGB_COLOR,
CONF_RESET_MANUAL_CONTROL_ON_SLEEP_MODE_CHANGE,
CONF_SEPARATE_TURN_ON_COMMANDS,
CONF_SKIP_BRIGHTNESS_INCREASES,
CONF_SKIP_REDUNDANT_COMMANDS,
CONF_SLEEP_RGB_OR_COLOR_TEMP,
CONF_SLEEP_TRANSITION,
@ -643,6 +645,198 @@ async def test_light_settings(hass):
assert_expected_color_temp(state)
@pytest.mark.parametrize("separate", [False, True])
@pytest.mark.parametrize("skip_redundant", [False, True])
async def test_dim_only_apply_preserves_brightness_and_adapts_color(
hass,
separate,
skip_redundant,
):
"""The apply service must keep mixed color adaptation below the ceiling."""
switch, (light, *_) = await setup_lights_and_switch(
hass,
{
CONF_SKIP_BRIGHTNESS_INCREASES: True,
CONF_SKIP_REDUNDANT_COMMANDS: skip_redundant,
CONF_SEPARATE_TURN_ON_COMMANDS: separate,
CONF_TAKE_OVER_CONTROL: False,
CONF_DETECT_NON_HA_CHANGES: False,
CONF_MIN_BRIGHTNESS: 80,
CONF_MAX_BRIGHTNESS: 80,
CONF_MIN_COLOR_TEMP: 3000,
CONF_MAX_COLOR_TEMP: 3000,
},
)
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{
ATTR_ENTITY_ID: light.entity_id,
ATTR_BRIGHTNESS: 100,
ATTR_COLOR_TEMP_KELVIN: 4000,
},
blocking=True,
)
await hass.services.async_call(
DOMAIN,
SERVICE_APPLY,
{
ATTR_ENTITY_ID: switch.entity_id,
CONF_LIGHTS: [light.entity_id],
ATTR_ADAPT_BRIGHTNESS: True,
ATTR_ADAPT_COLOR: True,
CONF_TRANSITION: 0,
},
blocking=True,
)
await hass.async_block_till_done()
state = hass.states.get(light.entity_id)
assert state.attributes[ATTR_BRIGHTNESS] == 100
assert state.attributes[ATTR_COLOR_TEMP_KELVIN] == pytest.approx(3000, abs=5)
async def test_dim_only_allows_lower_automatic_brightness(hass):
"""The apply service may still dim a light below its reported brightness."""
switch, (light, *_) = await setup_lights_and_switch(
hass,
{
CONF_SKIP_BRIGHTNESS_INCREASES: True,
CONF_TAKE_OVER_CONTROL: False,
CONF_DETECT_NON_HA_CHANGES: False,
CONF_MIN_BRIGHTNESS: 20,
CONF_MAX_BRIGHTNESS: 20,
},
)
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: light.entity_id, ATTR_BRIGHTNESS: 100},
blocking=True,
)
await hass.services.async_call(
DOMAIN,
SERVICE_APPLY,
{
ATTR_ENTITY_ID: switch.entity_id,
CONF_LIGHTS: [light.entity_id],
ATTR_ADAPT_BRIGHTNESS: True,
ATTR_ADAPT_COLOR: False,
CONF_TRANSITION: 0,
},
blocking=True,
)
await hass.async_block_till_done()
assert hass.states.get(light.entity_id).attributes[ATTR_BRIGHTNESS] == 51
async def test_dim_only_bare_turn_on_uses_retained_off_brightness(hass):
"""A bare turn-on must treat retained OFF brightness as the ceiling."""
_, (*_, light) = await setup_lights_and_switch(
hass,
{
CONF_LIGHTS: [ENTITY_LIGHT_3],
CONF_SKIP_BRIGHTNESS_INCREASES: True,
CONF_INTERCEPT: True,
CONF_TAKE_OVER_CONTROL: False,
CONF_DETECT_NON_HA_CHANGES: False,
CONF_MIN_BRIGHTNESS: 80,
CONF_MAX_BRIGHTNESS: 80,
CONF_MIN_COLOR_TEMP: 3000,
CONF_MAX_COLOR_TEMP: 3000,
},
all_lights=True,
)
state = hass.states.get(light.entity_id)
attributes = dict(state.attributes)
attributes[ATTR_BRIGHTNESS] = 100
hass.states.async_set(light.entity_id, STATE_OFF, attributes)
with patch.object(
light,
"async_turn_on",
wraps=light.async_turn_on,
) as turn_on:
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: light.entity_id},
blocking=True,
)
await hass.async_block_till_done()
service_data = turn_on.call_args_list[0].kwargs
assert ATTR_BRIGHTNESS not in service_data
assert service_data[ATTR_COLOR_TEMP_KELVIN] == 3000
assert hass.states.get(light.entity_id).attributes[
ATTR_COLOR_TEMP_KELVIN
] == pytest.approx(3000, abs=5)
async def test_dim_only_sleep_exit_does_not_restore_brightness(hass):
"""Leaving sleep mode must keep the reported sleep brightness ceiling."""
switch, (light, *_) = await setup_lights_and_switch(
hass,
{
CONF_SKIP_BRIGHTNESS_INCREASES: True,
CONF_TAKE_OVER_CONTROL: False,
CONF_DETECT_NON_HA_CHANGES: False,
CONF_MIN_BRIGHTNESS: 80,
CONF_MAX_BRIGHTNESS: 80,
},
)
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: switch.sleep_mode_switch.entity_id},
blocking=True,
)
await hass.async_block_till_done()
sleep_brightness = hass.states.get(light.entity_id).attributes[ATTR_BRIGHTNESS]
assert sleep_brightness == 3
await hass.services.async_call(
SWITCH_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: switch.sleep_mode_switch.entity_id},
blocking=True,
)
await hass.async_block_till_done()
assert (
hass.states.get(light.entity_id).attributes[ATTR_BRIGHTNESS] == sleep_brightness
)
async def test_dim_only_allows_explicit_manual_brightness(hass):
"""A direct brightness request must remain able to brighten an on light."""
_, (light, *_) = await setup_lights_and_switch(
hass,
{
CONF_SKIP_BRIGHTNESS_INCREASES: True,
CONF_INTERCEPT: True,
CONF_TAKE_OVER_CONTROL: False,
CONF_DETECT_NON_HA_CHANGES: False,
CONF_MIN_BRIGHTNESS: 20,
CONF_MAX_BRIGHTNESS: 20,
},
)
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: light.entity_id, ATTR_BRIGHTNESS: 220},
blocking=True,
)
await hass.async_block_till_done()
assert hass.states.get(light.entity_id).attributes[ATTR_BRIGHTNESS] == 220
async def test_manager_not_tracking_untracked_lights(hass):
"""Test that lights that are not in a Adaptive Lighting switch aren't tracked."""
switch, _ = await setup_lights_and_switch(hass)
@ -2717,6 +2911,10 @@ async def test_change_switch_settings_service(hass):
):
await change_switch_settings(**{CONF_MAX_BRIGHTNESS: 5000})
assert not switch._skip_brightness_increases
await change_switch_settings(**{CONF_SKIP_BRIGHTNESS_INCREASES: True})
assert switch._skip_brightness_increases
# Change CONF_MIN_COLOR_TEMP, the factory default is 2000, but setup_lights_and_switch
# sets it to 2500
assert switch._sun_light_settings.min_color_temp == 2500