Add skip_brightness_increases conf option

This commit is contained in:
Tim Stallmann 2025-03-26 08:06:15 -04:00
commit 2965c9ec9c
6 changed files with 47 additions and 6 deletions

View file

@ -142,7 +142,8 @@ The YAML and frontend configuration methods support all of the options listed be
| `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_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`
| `skip_brightness_increases` | Skip sending adaptation commands when the light entity is already dimmed below the the current target brightness. Lights will only ever get dimmer with this command enabled. | `False` | `bool` || `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` |

View file

@ -130,6 +130,18 @@ def _remove_redundant_attributes(
}
def _remove_brightness_increases(
service_data: ServiceData,
state: State,
) -> ServiceData:
"""Filter service data by removing brightness increases."""
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]
}
def _has_relevant_service_data_attributes(service_data: ServiceData) -> bool:
"""Determines whether the service data justifies an adaptation service call.
@ -145,6 +157,7 @@ async def _create_service_call_data_iterator(
hass: HomeAssistant,
service_datas: list[ServiceData],
filter_by_state: bool,
skip_brightness_increases: bool,
) -> AsyncGenerator[ServiceData]:
"""Enumerates and filters a list of service datas on the fly.
@ -156,15 +169,23 @@ async def _create_service_call_data_iterator(
flexibility because entity states can change while the items are iterated.
"""
for service_data in service_datas:
if filter_by_state and (entity_id := service_data.get(ATTR_ENTITY_ID)):
if (filter_by_state or skip_brightness_increases) and (
entity_id := service_data.get(ATTR_ENTITY_ID)
):
current_entity_state = hass.states.get(entity_id)
# Filter data to remove attributes that equal the current state
if current_entity_state is not None:
service_data = _remove_redundant_attributes( # noqa: PLW2901
service_data,
state=current_entity_state,
)
if filter_by_state:
service_data = _remove_redundant_attributes( # noqa: PLW2901
service_data,
state=current_entity_state,
)
if skip_brightness_increases:
service_data = _remove_brightness_increases( # noqa: PLW2901
service_data,
state=current_entity_state,
)
# Emit service data if it still contains relevant attributes (else try next)
if _has_relevant_service_data_attributes(service_data):
@ -240,6 +261,7 @@ def prepare_adaptation_data(
split: bool,
filter_by_state: bool,
force: bool,
skip_brightness_increases: bool,
) -> AdaptationData:
"""Prepares a data object carrying all data required to execute an adaptation."""
_LOGGER.debug(
@ -261,6 +283,7 @@ def prepare_adaptation_data(
hass,
service_datas,
filter_by_state,
skip_brightness_increases,
)
attributes = _identify_light_control_attributes(service_data)

View file

@ -254,6 +254,17 @@ DOCS[CONF_SKIP_REDUNDANT_COMMANDS] = (
"Disable if physical light states get out of sync with HA's recorded state."
)
CONF_SKIP_BRIGHTNESS_INCREASES, DEFAULT_SKIP_BRIGHTNESS_INCREASES = (
"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."
)
CONF_INTERCEPT, DEFAULT_INTERCEPT = "intercept", True
DOCS[CONF_INTERCEPT] = (
"Intercept and adapt `light.turn_on` calls to enabling instantaneous color "
@ -402,6 +413,7 @@ VALIDATION_TUPLES: list[tuple[str, Any, Any]] = [
DEFAULT_SKIP_REDUNDANT_COMMANDS,
bool,
),
(CONF_SKIP_BRIGHTNESS_INCREASES, DEFAULT_SKIP_BRIGHTNESS_INCREASES, bool),
(CONF_INTERCEPT, DEFAULT_INTERCEPT, bool),
(CONF_MULTI_LIGHT_INTERCEPT, DEFAULT_MULTI_LIGHT_INTERCEPT, bool),
(CONF_INCLUDE_CONFIG_IN_ATTRIBUTES, DEFAULT_INCLUDE_CONFIG_IN_ATTRIBUTES, bool),

View file

@ -62,6 +62,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: Never increase brightness on a light which has been dimmed below the current target brightness.",
"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`. 📝"

View file

@ -116,6 +116,7 @@ from .const import (
CONF_PREFER_RGB_COLOR,
CONF_SEND_SPLIT_DELAY,
CONF_SEPARATE_TURN_ON_COMMANDS,
CONF_SKIP_BRIGHTNESS_INCREASES,
CONF_SKIP_REDUNDANT_COMMANDS,
CONF_SLEEP_BRIGHTNESS,
CONF_SLEEP_COLOR_TEMP,
@ -933,6 +934,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
self._adapt_only_on_bare_turn_on = data[CONF_ADAPT_ONLY_ON_BARE_TURN_ON]
self._auto_reset_manual_control_time = data[CONF_AUTORESET_CONTROL]
self._skip_redundant_commands = data[CONF_SKIP_REDUNDANT_COMMANDS]
self._skip_brightness_increases = data[CONF_SKIP_BRIGHTNESS_INCREASES]
self._intercept = data[CONF_INTERCEPT]
self._multi_light_intercept = data[CONF_MULTI_LIGHT_INTERCEPT]
if not data[CONF_INTERCEPT] and data[CONF_MULTI_LIGHT_INTERCEPT]:
@ -1286,6 +1288,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
split=self._separate_turn_on_commands,
filter_by_state=self._skip_redundant_commands,
force=force,
skip_brightness_increases=self._skip_brightness_increases,
)
async def _adapt_light(

View file

@ -63,6 +63,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: Never increase brightness on a light which has been dimmed below the current target brightness.",
"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`. 📝"