From 312c594b25beb4f61cb3d91ab099d607bac15830 Mon Sep 17 00:00:00 2001 From: Benjamin Auquite Date: Mon, 3 Apr 2023 17:50:41 -0500 Subject: [PATCH 1/4] first commit --- custom_components/adaptive_lighting/const.py | 13 +++++++ custom_components/adaptive_lighting/switch.py | 34 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/custom_components/adaptive_lighting/const.py b/custom_components/adaptive_lighting/const.py index bb0c07cd..1d9e66ca 100644 --- a/custom_components/adaptive_lighting/const.py +++ b/custom_components/adaptive_lighting/const.py @@ -35,6 +35,18 @@ DOCS[CONF_DETECT_NON_HA_CHANGES] = ( "Requires `take_over_control`. 🕵️" ) +( + CONF_IGNORE_LIGHT_TURNON_WITH_CUSTOM_DATA, + DEFAULT_IGNORE_LIGHT_TURNON_WITH_CUSTOM_DATA, +) = ( + "ignore_turnon_with_custom_data", + False, +) +DOCS[CONF_IGNORE_LIGHT_TURNON_WITH_CUSTOM_DATA] = ( + "Ignores any lights turned off -> on with custom brightness/color data." + " Only a few lights are supported at this time." +) + CONF_INCLUDE_CONFIG_IN_ATTRIBUTES, DEFAULT_INCLUDE_CONFIG_IN_ATTRIBUTES = ( "include_config_in_attributes", False, @@ -224,6 +236,7 @@ def int_between(min_int, max_int): VALIDATION_TUPLES = [ (CONF_LIGHTS, DEFAULT_LIGHTS, cv.entity_ids), (CONF_PREFER_RGB_COLOR, DEFAULT_PREFER_RGB_COLOR, bool), + (CONF_IGNORE_LIGHT_TURNON_WITH_CUSTOM_DATA, bool), (CONF_INCLUDE_CONFIG_IN_ATTRIBUTES, DEFAULT_INCLUDE_CONFIG_IN_ATTRIBUTES, bool), (CONF_INITIAL_TRANSITION, DEFAULT_INITIAL_TRANSITION, VALID_TRANSITION), (CONF_SLEEP_TRANSITION, DEFAULT_SLEEP_TRANSITION, VALID_TRANSITION), diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index 031396fe..910ee85b 100644 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -99,6 +99,7 @@ from .const import ( CONF_ADAPT_UNTIL_SLEEP, CONF_AUTORESET_CONTROL, CONF_DETECT_NON_HA_CHANGES, + CONF_IGNORE_LIGHT_TURNON_WITH_CUSTOM_DATA, CONF_INCLUDE_CONFIG_IN_ATTRIBUTES, CONF_INITIAL_TRANSITION, CONF_INTERVAL, @@ -797,6 +798,9 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): attrdata[k] = v.total_seconds() self._config.update(attrdata) + self._ignore_light_turnon_with_custom_data = data[ + CONF_IGNORE_LIGHT_TURNON_WITH_CUSTOM_DATA + ] self._initial_transition = data[CONF_INITIAL_TRANSITION] self._sleep_transition = data[CONF_SLEEP_TRANSITION] self._only_once = data[CONF_ONLY_ONCE] @@ -1671,6 +1675,7 @@ class TurnOnOffListener: entity_ids, event.context.id, ) + for eid in entity_ids: task = self.sleep_tasks.get(eid) if task is not None: @@ -1685,6 +1690,35 @@ class TurnOnOffListener: # Restart the auto reset timer timer.start() + # Do not adapt any lights turned on with custom brightness/color_temp/rgb_color + # Probably doesn't work for most lights. + # Check if the option is enabled first. + switches = _get_switches_with_lights(self.hass, entity_ids) + found = False + for switch in switches: + if switch._ignore_light_turnon_with_custom_data: + found = True + # Option not enabled on any of the light's switches. + if not found: + return + # Check for custom data in service data. + if ( + ATTR_COLOR_TEMP_KELVIN in service_data + or ATTR_RGB_COLOR in service_data + or ATTR_BRIGHTNESS in service_data + or ATTR_XY_COLOR in service_data + or ATTR_HS_COLOR in service_data + or "color_temp" in service_data + ): + _LOGGER.info( + "%s: Light %s was turned on with custom settings." + "Setting as manually controlled.", + self._name, + entity_id, + ) + self.mark_as_manual_control(entity_ids) + _fire_manual_control_event(switch, entity_ids, event.context.id) + async def state_changed_event_listener(self, event: Event) -> None: """Track 'state_changed' events.""" entity_id = event.data.get(ATTR_ENTITY_ID, "") From a2e12ae6fcf64210ccff59429c6a92caa7a41d2f Mon Sep 17 00:00:00 2001 From: Benjamin Auquite Date: Mon, 3 Apr 2023 17:52:33 -0500 Subject: [PATCH 2/4] unpack list `entity_ids` --- custom_components/adaptive_lighting/switch.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index 910ee85b..7824e777 100644 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -1716,8 +1716,9 @@ class TurnOnOffListener: self._name, entity_id, ) - self.mark_as_manual_control(entity_ids) - _fire_manual_control_event(switch, entity_ids, event.context.id) + for eid in entity_ids: + self.mark_as_manual_control(eid) + _fire_manual_control_event(switch, eid, event.context.id) async def state_changed_event_listener(self, event: Event) -> None: """Track 'state_changed' events.""" From f73032c045be914a1ae1c330af77cf50bb97c5fa Mon Sep 17 00:00:00 2001 From: Benjamin Auquite Date: Mon, 3 Apr 2023 18:00:45 -0500 Subject: [PATCH 3/4] Update const.py --- custom_components/adaptive_lighting/const.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/custom_components/adaptive_lighting/const.py b/custom_components/adaptive_lighting/const.py index 1d9e66ca..64c3db10 100644 --- a/custom_components/adaptive_lighting/const.py +++ b/custom_components/adaptive_lighting/const.py @@ -236,7 +236,11 @@ def int_between(min_int, max_int): VALIDATION_TUPLES = [ (CONF_LIGHTS, DEFAULT_LIGHTS, cv.entity_ids), (CONF_PREFER_RGB_COLOR, DEFAULT_PREFER_RGB_COLOR, bool), - (CONF_IGNORE_LIGHT_TURNON_WITH_CUSTOM_DATA, bool), + ( + CONF_IGNORE_LIGHT_TURNON_WITH_CUSTOM_DATA, + DEFAULT_IGNORE_LIGHT_TURNON_WITH_CUSTOM_DATA, + bool, + ), (CONF_INCLUDE_CONFIG_IN_ATTRIBUTES, DEFAULT_INCLUDE_CONFIG_IN_ATTRIBUTES, bool), (CONF_INITIAL_TRANSITION, DEFAULT_INITIAL_TRANSITION, VALID_TRANSITION), (CONF_SLEEP_TRANSITION, DEFAULT_SLEEP_TRANSITION, VALID_TRANSITION), From 299a5fcd71da055408a39bef42db1e51444d6d9f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 3 Apr 2023 23:02:27 +0000 Subject: [PATCH 4/4] Update README.md, strings.json, and services.yaml --- README.md | 63 ++++++++++--------- .../adaptive_lighting/strings.json | 1 + .../adaptive_lighting/translations/en.json | 1 + 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index c7a873d0..857be993 100644 --- a/README.md +++ b/README.md @@ -88,37 +88,38 @@ The YAML and frontend configuration methods support all of the options listed be -| Variable name | Description | Default | Type | -|:-------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------|:-------------------------------------| -| `lights` | List of light entity_ids to be controlled (may be empty). 🌟 | `[]` | list of `entity_id`s | -| `prefer_rgb_color` | Whether to prefer RGB color adjustment over light color temperature when possible. 🌈 | `False` | `bool` | -| `include_config_in_attributes` | Show all options as attributes on the switch in Home Assistant when set to `true`. 📝 | `False` | `bool` | -| `initial_transition` | Duration of the first transition when lights turn from `off` to `on` in seconds. ⏲️ | `1` | `float` 0-6553 | -| `sleep_transition` | Duration of transition when "sleep mode" is toggled in seconds. 😴 | `1` | `float` 0-6553 | -| `transition` | Duration of transition when lights change, in seconds. 🕑 | `45` | `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` | -| `interval` | Frequency to adapt the lights, in seconds. 🔄 | `90` | `int > 0` | -| `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 | -| `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 | -| `sunrise_time` | Set a fixed time (HH:MM:SS) for sunrise. 🌅 | `None` | `str` | -| `max_sunrise_time` | Set the latest virtual sunrise time (HH:MM:SS), allowing for earlier real 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 real sunsets. 🌇 | `None` | `str` | -| `sunset_offset` | Adjust sunset time with a positive or negative offset in seconds. ⏰ | `0` | `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` | Detect non-`light.turn_on` state changes and stop adapting lights. Requires `take_over_control`. 🕵️ | `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` | -| `autoreset_control_seconds` | Automatically reset the manual control after a number of seconds. Set to 0 to disable. ⏲️ | `0` | `int` 0-31536000 | +| Variable name | Description | Default | Type | +|:---------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------------|:-------------------------------------| +| `lights` | List of light entity_ids to be controlled (may be empty). 🌟 | `[]` | list of `entity_id`s | +| `prefer_rgb_color` | Whether to prefer RGB color adjustment over light color temperature when possible. 🌈 | `False` | `bool` | +| `ignore_turnon_with_custom_data` | Ignores any lights turned off -> on with custom brightness/color data. Only a few lights are supported at this time. | `False` | `bool` | +| `include_config_in_attributes` | Show all options as attributes on the switch in Home Assistant when set to `true`. 📝 | `False` | `bool` | +| `initial_transition` | Duration of the first transition when lights turn from `off` to `on` in seconds. ⏲️ | `1` | `float` 0-6553 | +| `sleep_transition` | Duration of transition when "sleep mode" is toggled in seconds. 😴 | `1` | `float` 0-6553 | +| `transition` | Duration of transition when lights change, in seconds. 🕑 | `45` | `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` | +| `interval` | Frequency to adapt the lights, in seconds. 🔄 | `90` | `int > 0` | +| `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 | +| `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 | +| `sunrise_time` | Set a fixed time (HH:MM:SS) for sunrise. 🌅 | `None` | `str` | +| `max_sunrise_time` | Set the latest virtual sunrise time (HH:MM:SS), allowing for earlier real 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 real sunsets. 🌇 | `None` | `str` | +| `sunset_offset` | Adjust sunset time with a positive or negative offset in seconds. ⏰ | `0` | `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` | Detect non-`light.turn_on` state changes and stop adapting lights. Requires `take_over_control`. 🕵️ | `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` | +| `autoreset_control_seconds` | Automatically reset the manual control after a number of seconds. Set to 0 to disable. ⏲️ | `0` | `int` 0-31536000 | diff --git a/custom_components/adaptive_lighting/strings.json b/custom_components/adaptive_lighting/strings.json index 54af5e11..fb345bba 100644 --- a/custom_components/adaptive_lighting/strings.json +++ b/custom_components/adaptive_lighting/strings.json @@ -21,6 +21,7 @@ "data": { "lights": "lights: List of light entity_ids to be controlled (may be empty). 🌟", "prefer_rgb_color": "prefer_rgb_color: Whether to prefer RGB color adjustment over light color temperature when possible. 🌈", + "ignore_turnon_with_custom_data": "ignore_turnon_with_custom_data: Ignores any lights turned off -> on with custom brightness/color data. Only a few lights are supported at this time.", "include_config_in_attributes": "include_config_in_attributes: Show all options as attributes on the switch in Home Assistant when set to `true`. 📝", "initial_transition": "initial_transition: Duration of the first transition when lights turn from `off` to `on` in seconds. ⏲️", "sleep_transition": "sleep_transition: Duration of transition when \"sleep mode\" is toggled in seconds. 😴", diff --git a/custom_components/adaptive_lighting/translations/en.json b/custom_components/adaptive_lighting/translations/en.json index 38fb7b0e..f14e0c0c 100644 --- a/custom_components/adaptive_lighting/translations/en.json +++ b/custom_components/adaptive_lighting/translations/en.json @@ -22,6 +22,7 @@ "data": { "lights": "lights: List of light entity_ids to be controlled (may be empty). 🌟", "prefer_rgb_color": "prefer_rgb_color: Whether to prefer RGB color adjustment over light color temperature when possible. 🌈", + "ignore_turnon_with_custom_data": "ignore_turnon_with_custom_data: Ignores any lights turned off -> on with custom brightness/color data. Only a few lights are supported at this time.", "include_config_in_attributes": "include_config_in_attributes: Show all options as attributes on the switch in Home Assistant when set to `true`. 📝", "initial_transition": "initial_transition: Duration of the first transition when lights turn from `off` to `on` in seconds. ⏲️", "sleep_transition": "sleep_transition: Duration of transition when \"sleep mode\" is toggled in seconds. 😴",