Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ The YAML and frontend configuration methods support all of the options listed be
| `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_brightness` | Brightness percentage of lights in sleep mode. Set to 0 to prevent lights from turning on. 😴 | `1` | `int` 0-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 |
Expand Down
2 changes: 1 addition & 1 deletion custom_components/adaptive_lighting/adaptation_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def _split_service_call_data(service_data: ServiceData) -> list[ServiceData]:
split_data = {
attribute: service_data[attribute]
for attribute in attributes
if service_data.get(attribute)
if service_data.get(attribute) is not None
}
if split_data:
service_datas.append(common_data | split_data)
Expand Down
6 changes: 4 additions & 2 deletions custom_components/adaptive_lighting/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ class TakeOverControlMode(Enum):
)

CONF_SLEEP_BRIGHTNESS, DEFAULT_SLEEP_BRIGHTNESS = "sleep_brightness", 1
DOCS[CONF_SLEEP_BRIGHTNESS] = "Brightness percentage of lights in sleep mode. 😴"
DOCS[CONF_SLEEP_BRIGHTNESS] = (
"Brightness percentage of lights in sleep mode. Set to 0 to prevent lights from turning on. 😴"
)

CONF_SLEEP_COLOR_TEMP, DEFAULT_SLEEP_COLOR_TEMP = "sleep_color_temp", 1000
DOCS[CONF_SLEEP_COLOR_TEMP] = (
Expand Down Expand Up @@ -330,7 +332,7 @@ def int_between(min_int: int, max_int: int) -> vol.All:
(CONF_MIN_COLOR_TEMP, DEFAULT_MIN_COLOR_TEMP, int_between(1000, 10000)),
(CONF_MAX_COLOR_TEMP, DEFAULT_MAX_COLOR_TEMP, int_between(1000, 10000)),
(CONF_PREFER_RGB_COLOR, DEFAULT_PREFER_RGB_COLOR, bool),
(CONF_SLEEP_BRIGHTNESS, DEFAULT_SLEEP_BRIGHTNESS, int_between(1, 100)),
(CONF_SLEEP_BRIGHTNESS, DEFAULT_SLEEP_BRIGHTNESS, int_between(0, 100)),
(
CONF_SLEEP_RGB_OR_COLOR_TEMP,
DEFAULT_SLEEP_RGB_OR_COLOR_TEMP,
Expand Down
2 changes: 1 addition & 1 deletion custom_components/adaptive_lighting/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ change_switch_settings:
selector:
boolean: null
sleep_brightness:
description: Brightness percentage of lights in sleep mode. 😴
description: Brightness percentage of lights in sleep mode. Set to 0 to prevent lights from turning on. 😴
required: false
example: 1
selector:
Expand Down
4 changes: 2 additions & 2 deletions custom_components/adaptive_lighting/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
"interval": "Frequency to adapt the lights, in seconds. 🔄",
"transition": "Duration of transition when lights change, in seconds. 🕑",
"initial_transition": "Duration of the first transition when lights turn from `off` to `on` in seconds. ⏲️",
"sleep_brightness": "Brightness percentage of lights in sleep mode. 😴",
"sleep_brightness": "Brightness percentage of lights in sleep mode. Set to 0 to prevent lights from turning on. 😴",
"sleep_rgb_or_color_temp": "Use either `\"rgb_color\"` or `\"color_temp\"` in sleep mode. 🌙",
"sleep_color_temp": "Color temperature in sleep mode (used when `sleep_rgb_or_color_temp` is `color_temp`) in Kelvin. 😴",
"sleep_rgb_color": "RGB color in sleep mode (used when `sleep_rgb_or_color_temp` is \"rgb_color\"). 🌈",
Expand Down Expand Up @@ -212,7 +212,7 @@
"name": "send_split_delay"
},
"sleep_brightness": {
"description": "Brightness percentage of lights in sleep mode. 😴",
"description": "Brightness percentage of lights in sleep mode. Set to 0 to prevent lights from turning on. 😴",
"name": "sleep_brightness"
},
"sleep_rgb_or_color_temp": {
Expand Down
4 changes: 2 additions & 2 deletions custom_components/adaptive_lighting/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"interval": "Frequency to adapt the lights, in seconds. 🔄",
"transition": "Duration of transition when lights change, in seconds. 🕑",
"initial_transition": "Duration of the first transition when lights turn from `off` to `on` in seconds. ⏲️",
"sleep_brightness": "Brightness percentage of lights in sleep mode. 😴",
"sleep_brightness": "Brightness percentage of lights in sleep mode. Set to 0 to prevent lights from turning on. 😴",
"sleep_rgb_or_color_temp": "Use either `\"rgb_color\"` or `\"color_temp\"` in sleep mode. 🌙",
"sleep_color_temp": "Color temperature in sleep mode (used when `sleep_rgb_or_color_temp` is `color_temp`) in Kelvin. 😴",
"sleep_rgb_color": "RGB color in sleep mode (used when `sleep_rgb_or_color_temp` is \"rgb_color\"). 🌈",
Expand Down Expand Up @@ -213,7 +213,7 @@
"name": "send_split_delay"
},
"sleep_brightness": {
"description": "Brightness percentage of lights in sleep mode. 😴",
"description": "Brightness percentage of lights in sleep mode. Set to 0 to prevent lights from turning on. 😴",
"name": "sleep_brightness"
},
"sleep_rgb_or_color_temp": {
Expand Down
2 changes: 1 addition & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ All configuration options are listed below with their default values. These opti
| `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_brightness` | Brightness percentage of lights in sleep mode. Set to 0 to prevent lights from turning on. 😴 | `1` | `int` 0-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 |
Expand Down
79 changes: 79 additions & 0 deletions tests/test_switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
CONF_MULTI_LIGHT_INTERCEPT,
CONF_PREFER_RGB_COLOR,
CONF_SEPARATE_TURN_ON_COMMANDS,
CONF_SLEEP_BRIGHTNESS,
CONF_SLEEP_RGB_OR_COLOR_TEMP,
CONF_SUNRISE_OFFSET,
CONF_SUNRISE_TIME,
Expand Down Expand Up @@ -2997,3 +2998,81 @@ async def _flush_attr_state(hass, entity_id):
assert (
light.brightness == manual_brightness
), f"AL overrode manual brightness {manual_brightness} with {al_brightness}"


async def test_zero_sleep_brightness_and_separate_turn_on_commands(hass):
"""Test behavior when sleep_brightness is 0 with separate_turn_on_commands enabled.

This test verifies that when:
- CONF_SLEEP_BRIGHTNESS: 0 (brightness set to 0%)
- CONF_SEPARATE_TURN_ON_COMMANDS: True (split brightness and color commands)
- Sleep mode is active

Attempting to turn on a light results in the light staying OFF because:
1. With separate_turn_on_commands=True, the first command sets brightness=0
2. Setting brightness to 0 is equivalent to turning the light off
3. The second command (color) is then skipped because the light is off

This documents the edge case behavior where sleep_brightness=0 effectively
prevents lights from turning on when using separate turn-on commands.
"""
switch, (light, *_) = await setup_lights_and_switch(
hass,
{
CONF_SEPARATE_TURN_ON_COMMANDS: True,
CONF_SLEEP_BRIGHTNESS: 0,
},
)

# Turn on the light without sleep mode
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: ENTITY_LIGHT_1},
blocking=True,
)
await hass.async_block_till_done()

assert (
hass.states.get(ENTITY_LIGHT_1).state == STATE_ON
), "light is not on after normal turn on"

# Turn off the light without sleep mode
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: ENTITY_LIGHT_1},
blocking=True,
)
await hass.async_block_till_done()

assert (
hass.states.get(ENTITY_LIGHT_1).state == STATE_OFF
), "light is not off after normal turn off"

# Turn on sleep mode
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()

assert (
switch.sleep_mode_switch.is_on
), "sleep mode is not on after toggling the switch"

# Turn on the light while in sleep mode
await hass.services.async_call(
LIGHT_DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: ENTITY_LIGHT_1},
blocking=True,
)
await hass.async_block_till_done()

# The light should be in "off" state even if we turned it on
assert (
hass.states.get(ENTITY_LIGHT_1).state == STATE_OFF
), "light is on, even though sleep mode should prevent it"
Loading