mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-11 14:24:03 +02:00
Add adapt_only_on_bare_turn_on which instantly triggers manual_control when turning on with brightness or color (#709)
This commit is contained in:
parent
3f17738bd1
commit
d44cb66148
6 changed files with 131 additions and 53 deletions
78
README.md
78
README.md
|
|
@ -97,45 +97,45 @@ The YAML and frontend configuration methods support all of the options listed be
|
|||
|
||||
<!-- START_OUTPUT -->
|
||||
<!-- THIS CONTENT IS AUTOMATICALLY GENERATED -->
|
||||
| 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` |
|
||||
| `only_once` | Adapt lights only when they are turned on (`true`) or keep adapting them (`false`). 🔄 | `False` | `bool` |
|
||||
| `take_over_control` | Disable Adaptive Lighting if another source calls `light.turn_on` while lights are on and being adapted. Note that this calls `homeassistant.update_entity` every `interval`! 🔒 | `True` | `bool` |
|
||||
| `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. 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` |
|
||||
| `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` |
|
||||
| `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. | `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` | Disable Adaptive Lighting if another source calls `light.turn_on` while lights are on and being adapted. Note that this calls `homeassistant.update_entity` every `interval`! 🔒 | `True` | `bool` |
|
||||
| `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. 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. If `false`, AL adapts regardless of the presence of color or brightness in the initial `service_data`. Needs `take_over_control` enabled. 🕵️ | `False` | `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` |
|
||||
| `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. | `True` | `bool` |
|
||||
| `include_config_in_attributes` | Show all options as attributes on the switch in Home Assistant when set to `true`. 📝 | `False` | `bool` |
|
||||
|
||||
<!-- END_OUTPUT -->
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,18 @@ DOCS[CONF_ONLY_ONCE] = (
|
|||
"(`false`). 🔄"
|
||||
)
|
||||
|
||||
CONF_ADAPT_ONLY_ON_BARE_TURN_ON, DEFAULT_ADAPT_ONLY_ON_BARE_TURN_ON = (
|
||||
"adapt_only_on_bare_turn_on",
|
||||
False,
|
||||
)
|
||||
DOCS[CONF_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. "
|
||||
"If `false`, AL adapts regardless of the presence of color or brightness in the initial `service_data`. "
|
||||
"Needs `take_over_control` enabled. 🕵️ "
|
||||
)
|
||||
|
||||
CONF_PREFER_RGB_COLOR, DEFAULT_PREFER_RGB_COLOR = "prefer_rgb_color", False
|
||||
DOCS[CONF_PREFER_RGB_COLOR] = (
|
||||
"Whether to prefer RGB color adjustment over "
|
||||
|
|
@ -329,7 +341,6 @@ VALIDATION_TUPLES = [
|
|||
),
|
||||
(CONF_BRIGHTNESS_MODE_TIME_DARK, DEFAULT_BRIGHTNESS_MODE_TIME_DARK, int),
|
||||
(CONF_BRIGHTNESS_MODE_TIME_LIGHT, DEFAULT_BRIGHTNESS_MODE_TIME_LIGHT, int),
|
||||
(CONF_ONLY_ONCE, DEFAULT_ONLY_ONCE, bool),
|
||||
(CONF_TAKE_OVER_CONTROL, DEFAULT_TAKE_OVER_CONTROL, bool),
|
||||
(CONF_DETECT_NON_HA_CHANGES, DEFAULT_DETECT_NON_HA_CHANGES, bool),
|
||||
(
|
||||
|
|
@ -338,6 +349,7 @@ VALIDATION_TUPLES = [
|
|||
int_between(0, 365 * 24 * 60 * 60), # 1 year max
|
||||
),
|
||||
(CONF_ONLY_ONCE, DEFAULT_ONLY_ONCE, bool),
|
||||
(CONF_ADAPT_ONLY_ON_BARE_TURN_ON, DEFAULT_ADAPT_ONLY_ON_BARE_TURN_ON, bool),
|
||||
(CONF_SEPARATE_TURN_ON_COMMANDS, DEFAULT_SEPARATE_TURN_ON_COMMANDS, bool),
|
||||
(CONF_SEND_SPLIT_DELAY, DEFAULT_SEND_SPLIT_DELAY, int_between(0, 10000)),
|
||||
(CONF_ADAPT_DELAY, DEFAULT_ADAPT_DELAY, cv.positive_float),
|
||||
|
|
|
|||
|
|
@ -45,10 +45,11 @@
|
|||
"brightness_mode": "brightness_mode: Brightness mode to use. Possible values are `default`, `linear`, and `tanh` (uses `brightness_mode_time_dark` and `brightness_mode_time_light`). 📈",
|
||||
"brightness_mode_time_dark": "brightness_mode_time_dark: (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness before/after sunrise/sunset. 📈📉",
|
||||
"brightness_mode_time_light": "brightness_mode_time_light: (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness after/before sunrise/sunset. 📈📉.",
|
||||
"only_once": "only_once: Adapt lights only when they are turned on (`true`) or keep adapting them (`false`). 🔄",
|
||||
"take_over_control": "take_over_control: Disable Adaptive Lighting if another source calls `light.turn_on` while lights are on and being adapted. Note that this calls `homeassistant.update_entity` every `interval`! 🔒",
|
||||
"detect_non_ha_changes": "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. Disable this feature if you encounter such issues.",
|
||||
"autoreset_control_seconds": "autoreset_control_seconds: Automatically reset the manual control after a number of seconds. Set to 0 to disable. ⏲️",
|
||||
"only_once": "only_once: Adapt lights only when they are turned on (`true`) or keep adapting them (`false`). 🔄",
|
||||
"adapt_only_on_bare_turn_on": "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. If `false`, AL adapts regardless of the presence of color or brightness in the initial `service_data`. Needs `take_over_control` enabled. 🕵️ ",
|
||||
"separate_turn_on_commands": "separate_turn_on_commands: Use separate `light.turn_on` calls for color and brightness, needed for some light types. 🔀",
|
||||
"send_split_delay": "send_split_delay: Delay (ms) between `separate_turn_on_commands` for lights that don't support simultaneous brightness and color setting. ⏲️",
|
||||
"adapt_delay": "adapt_delay: Wait time (seconds) between light turn on and Adaptive Lighting applying changes. Might help to avoid flickering. ⏲️",
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ from .const import (
|
|||
ATTR_ADAPT_COLOR,
|
||||
ATTR_ADAPTIVE_LIGHTING_MANAGER,
|
||||
CONF_ADAPT_DELAY,
|
||||
CONF_ADAPT_ONLY_ON_BARE_TURN_ON,
|
||||
CONF_ADAPT_UNTIL_SLEEP,
|
||||
CONF_AUTORESET_CONTROL,
|
||||
CONF_BRIGHTNESS_MODE,
|
||||
|
|
@ -876,15 +877,18 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
self._adapt_delay = data[CONF_ADAPT_DELAY]
|
||||
self._send_split_delay = data[CONF_SEND_SPLIT_DELAY]
|
||||
self._take_over_control = data[CONF_TAKE_OVER_CONTROL]
|
||||
self._detect_non_ha_changes = data[CONF_DETECT_NON_HA_CHANGES]
|
||||
if not data[CONF_TAKE_OVER_CONTROL] and data[CONF_DETECT_NON_HA_CHANGES]:
|
||||
if not data[CONF_TAKE_OVER_CONTROL] and (
|
||||
data[CONF_DETECT_NON_HA_CHANGES] or data[CONF_ADAPT_ONLY_ON_BARE_TURN_ON]
|
||||
):
|
||||
_LOGGER.warning(
|
||||
"%s: Config mismatch: 'detect_non_ha_changes: true' "
|
||||
"requires 'take_over_control' to be enabled. Adjusting config "
|
||||
"%s: Config mismatch: `detect_non_ha_changes` or `adapt_only_on_bare_turn_on` "
|
||||
"set to `true` requires `take_over_control` to be enabled. Adjusting config "
|
||||
"and continuing setup with `take_over_control: true`.",
|
||||
self._name,
|
||||
)
|
||||
self._take_over_control = True
|
||||
self._detect_non_ha_changes = data[CONF_DETECT_NON_HA_CHANGES]
|
||||
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._multi_light_intercept = data[CONF_MULTI_LIGHT_INTERCEPT]
|
||||
|
|
@ -1446,13 +1450,14 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
|
||||
async def _respond_to_off_to_on_event(self, entity_id: str, event: Event) -> None:
|
||||
assert not self.manager.is_proactively_adapting(event.context.id)
|
||||
from_turn_on = self.manager._off_to_on_state_event_is_from_turn_on(
|
||||
entity_id,
|
||||
event,
|
||||
)
|
||||
if (
|
||||
self._take_over_control
|
||||
and not self._detect_non_ha_changes
|
||||
and not self.manager._off_to_on_state_event_is_from_turn_on(
|
||||
entity_id,
|
||||
event,
|
||||
)
|
||||
and not from_turn_on
|
||||
):
|
||||
# There is an edge case where 2 switches control the same light, e.g.,
|
||||
# one for brightness and one for color. Now we will mark both switches
|
||||
|
|
@ -1468,6 +1473,25 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity):
|
|||
self.manager.mark_as_manual_control(entity_id)
|
||||
return
|
||||
|
||||
if (
|
||||
self._take_over_control
|
||||
and self._adapt_only_on_bare_turn_on
|
||||
and from_turn_on
|
||||
):
|
||||
service_data = self.manager.turn_on_event[entity_id].data[ATTR_SERVICE_DATA]
|
||||
if self.manager._mark_manual_control_if_non_bare_turn_on(
|
||||
entity_id,
|
||||
service_data,
|
||||
):
|
||||
_LOGGER.debug(
|
||||
"Skipping responding to 'off' → 'on' event for '%s' with context.id='%s' because"
|
||||
" we only adapt on bare `light.turn_on` events and not on service_data: '%s'",
|
||||
entity_id,
|
||||
event.context.id,
|
||||
service_data,
|
||||
)
|
||||
return
|
||||
|
||||
if self._adapt_delay > 0:
|
||||
await asyncio.sleep(self._adapt_delay)
|
||||
|
||||
|
|
@ -2070,6 +2094,14 @@ class AdaptiveLightingManager:
|
|||
# and of TOGGLE calls when toggling off.
|
||||
or self.hass.states.is_state(entity_id, STATE_ON)
|
||||
or self.manual_control.get(entity_id, False)
|
||||
or (
|
||||
switch._take_over_control
|
||||
and switch._adapt_only_on_bare_turn_on
|
||||
and self._mark_manual_control_if_non_bare_turn_on(
|
||||
entity_id,
|
||||
data[CONF_PARAMS],
|
||||
)
|
||||
)
|
||||
):
|
||||
_LOGGER.debug(
|
||||
"Switch is off or light is already on for entity_id='%s', skipped='%s'"
|
||||
|
|
@ -2622,6 +2654,7 @@ class AdaptiveLightingManager:
|
|||
turn_on_event = self.turn_on_event.get(light)
|
||||
if (
|
||||
turn_on_event is not None
|
||||
and not self.is_proactively_adapting(turn_on_event.context.id)
|
||||
and not is_our_context(turn_on_event.context)
|
||||
and not force
|
||||
):
|
||||
|
|
@ -2855,6 +2888,21 @@ class AdaptiveLightingManager:
|
|||
)
|
||||
return False
|
||||
|
||||
def _mark_manual_control_if_non_bare_turn_on(
|
||||
self,
|
||||
entity_id: str,
|
||||
service_data: ServiceData,
|
||||
) -> bool:
|
||||
_LOGGER.debug(
|
||||
"_mark_manual_control_if_non_bare_turn_on: entity_id='%s', service_data='%s'",
|
||||
entity_id,
|
||||
service_data,
|
||||
)
|
||||
if any(attr in service_data for attr in COLOR_ATTRS | BRIGHTNESS_ATTRS):
|
||||
self.mark_as_manual_control(entity_id)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class _AsyncSingleShotTimer:
|
||||
def __init__(self, delay, callback) -> None:
|
||||
|
|
|
|||
|
|
@ -46,10 +46,11 @@
|
|||
"brightness_mode": "brightness_mode: Brightness mode to use. Possible values are `default`, `linear`, and `tanh` (uses `brightness_mode_time_dark` and `brightness_mode_time_light`). 📈",
|
||||
"brightness_mode_time_dark": "brightness_mode_time_dark: (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness before/after sunrise/sunset. 📈📉",
|
||||
"brightness_mode_time_light": "brightness_mode_time_light: (Ignored if `brightness_mode='default'`) The duration in seconds to ramp up/down the brightness after/before sunrise/sunset. 📈📉.",
|
||||
"only_once": "only_once: Adapt lights only when they are turned on (`true`) or keep adapting them (`false`). 🔄",
|
||||
"take_over_control": "take_over_control: Disable Adaptive Lighting if another source calls `light.turn_on` while lights are on and being adapted. Note that this calls `homeassistant.update_entity` every `interval`! 🔒",
|
||||
"detect_non_ha_changes": "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. Disable this feature if you encounter such issues.",
|
||||
"autoreset_control_seconds": "autoreset_control_seconds: Automatically reset the manual control after a number of seconds. Set to 0 to disable. ⏲️",
|
||||
"only_once": "only_once: Adapt lights only when they are turned on (`true`) or keep adapting them (`false`). 🔄",
|
||||
"adapt_only_on_bare_turn_on": "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. If `false`, AL adapts regardless of the presence of color or brightness in the initial `service_data`. Needs `take_over_control` enabled. 🕵️ ",
|
||||
"separate_turn_on_commands": "separate_turn_on_commands: Use separate `light.turn_on` calls for color and brightness, needed for some light types. 🔀",
|
||||
"send_split_delay": "send_split_delay: Delay (ms) between `separate_turn_on_commands` for lights that don't support simultaneous brightness and color setting. ⏲️",
|
||||
"adapt_delay": "adapt_delay: Wait time (seconds) between light turn on and Adaptive Lighting applying changes. Might help to avoid flickering. ⏲️",
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ from custom_components.adaptive_lighting.const import (
|
|||
SERVICE_CHANGE_SWITCH_SETTINGS,
|
||||
SERVICE_SET_MANUAL_CONTROL,
|
||||
SLEEP_MODE_SWITCH,
|
||||
CONF_ADAPT_ONLY_ON_BARE_TURN_ON,
|
||||
UNDO_UPDATE_LISTENER,
|
||||
)
|
||||
from custom_components.adaptive_lighting.switch import (
|
||||
|
|
@ -561,9 +562,19 @@ async def test_manager_not_tracking_untracked_lights(hass):
|
|||
assert light not in switch.manager.lights
|
||||
|
||||
|
||||
async def test_manual_control(hass):
|
||||
@pytest.mark.parametrize("adapt_only_on_bare_turn_on", [True, False])
|
||||
@pytest.mark.parametrize("proactive_service_call_adaptation", [True, False])
|
||||
async def test_manual_control(
|
||||
hass, adapt_only_on_bare_turn_on, proactive_service_call_adaptation
|
||||
):
|
||||
"""Test the 'manual control' tracking."""
|
||||
switch, (light, *_) = await setup_lights_and_switch(hass)
|
||||
switch, (light, *_) = await setup_lights_and_switch(
|
||||
hass,
|
||||
{
|
||||
CONF_ADAPT_ONLY_ON_BARE_TURN_ON: adapt_only_on_bare_turn_on,
|
||||
INTERNAL_CONF_PROACTIVE_SERVICE_CALL_ADAPTATION: proactive_service_call_adaptation,
|
||||
},
|
||||
)
|
||||
assert switch._take_over_control
|
||||
assert hass.states.get(ENTITY_LIGHT_1).state == STATE_ON
|
||||
|
||||
|
|
@ -639,9 +650,14 @@ async def test_manual_control(hass):
|
|||
await change_manual_control(True)
|
||||
assert manual_control[ENTITY_LIGHT_1]
|
||||
await turn_light(False)
|
||||
assert not manual_control[ENTITY_LIGHT_1], manual_control
|
||||
await turn_light(True, brightness=increased_brightness())
|
||||
assert hass.states.get(ENTITY_LIGHT_1).state == STATE_ON
|
||||
assert not manual_control[ENTITY_LIGHT_1], manual_control
|
||||
if adapt_only_on_bare_turn_on:
|
||||
# Marks as manually controlled beacuse we turned it on with brightness
|
||||
assert manual_control[ENTITY_LIGHT_1], manual_control
|
||||
else:
|
||||
assert not manual_control[ENTITY_LIGHT_1], manual_control
|
||||
|
||||
# Check that toggling (sleep mode) switch resets manual control
|
||||
for entity_id in [ENTITY_SWITCH, ENTITY_SLEEP_MODE_SWITCH]:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue