diff --git a/README.md b/README.md index 037a6b05..c354153d 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ The `adaptive_lighting.manual_control` event is fired when a light is marked as - [:sunny: Sun Position](#sunny-sun-position) - [:thermometer: Color Temperature](#thermometer-color-temperature) - [:high_brightness: Brightness](#high_brightness-brightness) + - [While using `adapt_until_sleep: true`](#while-using-adapt_until_sleep-true) - [:busts_in_silhouette: Contributors](#busts_in_silhouette-contributors) @@ -95,6 +96,7 @@ The YAML and frontend configuration methods support all of the options listed be | `lights` | List of light entities to be controlled by Adaptive Lighting (may be empty). 🌟 | `[]` | list of `entity_id`s | | `prefer_rgb_color` | Use RGB color adjustment instead of native light color temperature. 🌈 | `False` | `bool` | | `include_config_in_attributes` | Show all options as attributes on the switch in Home Assistant when set to `true`. 📝 | `False` | `bool` | +| `adapt_until_sleep` | When `true`, Adaptive Lighting will use the sleep settings as the minimum, and transition to these values past the sunset | `False` | `bool` | | `initial_transition` | Duration of the first transition when lights turn from `off` to `on`. ⏲️ | `1` | `float` 0-6553 | | `sleep_transition` | Duration of transition when 'sleep mode' is toggled. 😴 | `1` | `float` 0-6553 | | `transition` | Duration of transition when lights change, in seconds. 🕑 | `45` | `float` 0-6553 | @@ -364,6 +366,10 @@ These graphs were generated using the values calculated by the Adaptive Lighting #### :high_brightness: Brightness ![cl_brightness|690x130](https://community-home-assistant-assets.s3.dualstack.us-west-2.amazonaws.com/original/3X/5/8/58ebd994b62a8b1abfb3497a5288d923ff4e2330.PNG) +#### While using `adapt_until_sleep: true` +![image](https://user-images.githubusercontent.com/2219836/228949675-f9699624-8abc-466c-bb04-250ce0f495b8.png) + + ## :busts_in_silhouette: Contributors diff --git a/custom_components/adaptive_lighting/const.py b/custom_components/adaptive_lighting/const.py index 471d593c..a5a5f2c1 100644 --- a/custom_components/adaptive_lighting/const.py +++ b/custom_components/adaptive_lighting/const.py @@ -140,6 +140,15 @@ DOCS[CONF_TAKE_OVER_CONTROL] = ( CONF_TRANSITION, DEFAULT_TRANSITION = "transition", 45 DOCS[CONF_TRANSITION] = "Duration of transition when lights change, in seconds. 🕑" +CONF_ADAPT_UNTIL_SLEEP, DEFAULT_ADAPT_UNTIL_SLEEP = ( + "transition_until_sleep", + False, +) +DOCS[CONF_ADAPT_UNTIL_SLEEP] = ( + "When checked, Adaptive Lighting will use the sleep settings as the minimum," + " and transition to these values past the sunset" +) + CONF_ADAPT_DELAY, DEFAULT_ADAPT_DELAY = "adapt_delay", 0 DOCS[CONF_ADAPT_DELAY] = ( "Wait time (seconds) between light turn on and Adaptive Lighting applying " @@ -190,6 +199,7 @@ VALIDATION_TUPLES = [ (CONF_INITIAL_TRANSITION, DEFAULT_INITIAL_TRANSITION, VALID_TRANSITION), (CONF_SLEEP_TRANSITION, DEFAULT_SLEEP_TRANSITION, VALID_TRANSITION), (CONF_TRANSITION, DEFAULT_TRANSITION, VALID_TRANSITION), + (CONF_ADAPT_UNTIL_SLEEP, DEFAULT_ADAPT_UNTIL_SLEEP, bool), (CONF_INTERVAL, DEFAULT_INTERVAL, cv.positive_int), (CONF_MIN_BRIGHTNESS, DEFAULT_MIN_BRIGHTNESS, int_between(1, 100)), (CONF_MAX_BRIGHTNESS, DEFAULT_MAX_BRIGHTNESS, int_between(1, 100)), diff --git a/custom_components/adaptive_lighting/strings.json b/custom_components/adaptive_lighting/strings.json index 5a8ef6af..2ebd96d0 100644 --- a/custom_components/adaptive_lighting/strings.json +++ b/custom_components/adaptive_lighting/strings.json @@ -22,6 +22,7 @@ "lights": "lights", "initial_transition": "initial_transition: When lights turn 'off' to 'on'. (seconds)", "include_config_in_attributes": "include_config_in_attributes: All config options will be listed as attributes under the adaptive-lighting switch this integration creates. (default: false)", + "adapt_until_sleep": "adapt_until_sleep: When checked, Adaptive Lighting will use the sleep settings as the minimum, and transition to these values past the sunset (default: false)", "sleep_transition": "sleep_transition: When 'sleep_state' changes. (seconds)", "interval": "interval: Time between switch updates. (seconds)", "max_brightness": "max_brightness: Highest brightness of lights during a cycle. (%)", diff --git a/custom_components/adaptive_lighting/switch.py b/custom_components/adaptive_lighting/switch.py index 6527b73d..75361965 100644 --- a/custom_components/adaptive_lighting/switch.py +++ b/custom_components/adaptive_lighting/switch.py @@ -97,6 +97,7 @@ from .const import ( ATTR_ADAPT_COLOR, ATTR_TURN_ON_OFF_LISTENER, CONF_ADAPT_DELAY, + CONF_ADAPT_UNTIL_SLEEP, CONF_AUTORESET_CONTROL, CONF_DETECT_NON_HA_CHANGES, CONF_INCLUDE_CONFIG_IN_ATTRIBUTES, @@ -834,6 +835,7 @@ class AdaptiveSwitch(SwitchEntity, RestoreEntity): self._sun_light_settings = SunLightSettings( name=self._name, astral_location=location, + adapt_until_sleep=data[CONF_ADAPT_UNTIL_SLEEP], max_brightness=data[CONF_MAX_BRIGHTNESS], max_color_temp=data[CONF_MAX_COLOR_TEMP], min_brightness=data[CONF_MIN_BRIGHTNESS], @@ -1325,6 +1327,7 @@ class SunLightSettings: name: str astral_location: astral.Location + adapt_until_sleep: bool max_brightness: int max_color_temp: int min_brightness: int @@ -1474,7 +1477,12 @@ class SunLightSettings: delta = self.max_color_temp - self.min_color_temp ct = (delta * percent) + self.min_color_temp return 5 * round(ct / 5) # round to nearest 5 - return self.min_color_temp + if percent == 0 or not self.adapt_until_sleep: + return self.min_color_temp + if self.adapt_until_sleep and percent < 0: + delta = abs(self.min_color_temp - self.sleep_color_temp) + ct = (delta * abs(1 + percent)) + self.sleep_color_temp + return 5 * round(ct / 5) # round to nearest 5 def get_settings( self, is_sleep, transition