mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-10-31 07:27:54 +01:00
🐛 Follow the profile's adapt switches when applying a time
`adaptive_lighting.apply` with `time` now adapts (and marks as manually controlled) only what the profile adapts itself, going by its Adapt Brightness and Adapt Color switches, unless `adapt_brightness` or `adapt_color` is passed. Without `time`, `apply` still adapts both by default. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
a3782c8e77
commit
92ae6d9ccc
5 changed files with 65 additions and 14 deletions
|
|
@ -233,7 +233,7 @@ Provide a switch in `entity_id`, a list of `lights`, or both.
|
|||
|
||||
With `time`, the lights get the values Adaptive Lighting would use at that time today, for example to dim a room to its evening settings early.
|
||||
The adapted attributes are then marked as manually controlled, exactly as if you had changed them yourself: the regular adaptation leaves them alone until manual control is reset (see `autoreset_control_seconds` and `adaptive_lighting.set_manual_control`), and an `adaptive_lighting.manual_control` event is fired.
|
||||
When sleep mode is on, the sleep settings are applied instead, whatever the time.
|
||||
When sleep mode is on, the sleep settings are applied instead, whatever the time. Unless `adapt_brightness` or `adapt_color` is given, only what the profile adapts (its Adapt Brightness and Adapt Color switches) is applied.
|
||||
|
||||
```yaml
|
||||
action: adaptive_lighting.apply
|
||||
|
|
|
|||
|
|
@ -521,8 +521,8 @@ def apply_service_schema() -> vol.Schema:
|
|||
vol.Optional(CONF_ENTITY_ID): cv.entity_ids, # type: ignore[arg-type]
|
||||
vol.Optional(CONF_LIGHTS, default=[]): cv.entity_ids, # type: ignore[arg-type]
|
||||
vol.Optional(CONF_TRANSITION): VALID_TRANSITION,
|
||||
vol.Optional(ATTR_ADAPT_BRIGHTNESS, default=True): cv.boolean,
|
||||
vol.Optional(ATTR_ADAPT_COLOR, default=True): cv.boolean,
|
||||
vol.Optional(ATTR_ADAPT_BRIGHTNESS): cv.boolean,
|
||||
vol.Optional(ATTR_ADAPT_COLOR): cv.boolean,
|
||||
vol.Optional(CONF_PREFER_RGB_COLOR, default=False): cv.boolean,
|
||||
vol.Optional(CONF_TURN_ON_LIGHTS, default=False): cv.boolean,
|
||||
vol.Optional(CONF_APPLY_TIME): cv.time,
|
||||
|
|
|
|||
|
|
@ -424,22 +424,31 @@ async def handle_apply_service(hass: HomeAssistant, service_call: ServiceCall) -
|
|||
switches = _switches_from_service_call(hass, service_call)
|
||||
lights = data[CONF_LIGHTS]
|
||||
apply_time: datetime.time | None = data.get(CONF_APPLY_TIME)
|
||||
# Applying the settings of another time of day only sticks if the regular
|
||||
# adaptation leaves the light alone, so treat it like a manual change.
|
||||
manual_attributes = LightControlAttributes.NONE
|
||||
if apply_time is not None:
|
||||
if data[ATTR_ADAPT_BRIGHTNESS]:
|
||||
manual_attributes |= LightControlAttributes.BRIGHTNESS
|
||||
if data[ATTR_ADAPT_COLOR]:
|
||||
manual_attributes |= LightControlAttributes.COLOR
|
||||
for switch in switches:
|
||||
all_lights = switch._resolve_lights(lights or None)
|
||||
switch.manager.lights.update(all_lights)
|
||||
adapt_brightness = data.get(ATTR_ADAPT_BRIGHTNESS)
|
||||
adapt_color = data.get(ATTR_ADAPT_COLOR)
|
||||
at_time = None
|
||||
manual_attributes = LightControlAttributes.NONE
|
||||
if apply_time is not None:
|
||||
tz = switch._sun_light_settings.timezone # pylint: disable=protected-access
|
||||
today = dt_util.now(tz).date()
|
||||
at_time = datetime.datetime.combine(today, apply_time, tzinfo=tz)
|
||||
# Adapt what the regular adaptation would, unless specified.
|
||||
if adapt_brightness is None:
|
||||
adapt_brightness = switch.adapt_brightness_switch.is_on
|
||||
if adapt_color is None:
|
||||
adapt_color = switch.adapt_color_switch.is_on
|
||||
# Applying the settings of another time of day only sticks if the
|
||||
# regular adaptation leaves the light alone, so treat it like a
|
||||
# manual change.
|
||||
if adapt_brightness:
|
||||
manual_attributes |= LightControlAttributes.BRIGHTNESS
|
||||
if adapt_color:
|
||||
manual_attributes |= LightControlAttributes.COLOR
|
||||
adapt_brightness = True if adapt_brightness is None else adapt_brightness
|
||||
adapt_color = True if adapt_color is None else adapt_color
|
||||
for light in all_lights:
|
||||
if data[CONF_TURN_ON_LIGHTS] or is_on(hass, light):
|
||||
context = switch.create_context(
|
||||
|
|
@ -460,8 +469,8 @@ async def handle_apply_service(hass: HomeAssistant, service_call: ServiceCall) -
|
|||
light,
|
||||
context=context,
|
||||
transition=transition,
|
||||
adapt_brightness=data[ATTR_ADAPT_BRIGHTNESS],
|
||||
adapt_color=data[ATTR_ADAPT_COLOR],
|
||||
adapt_brightness=adapt_brightness,
|
||||
adapt_color=adapt_color,
|
||||
prefer_rgb_color=data[CONF_PREFER_RGB_COLOR],
|
||||
force=True,
|
||||
at_time=at_time,
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ data:
|
|||
time: "22:00:00"
|
||||
```
|
||||
|
||||
With `time`, the lights get the values Adaptive Lighting would use at that time today. The adapted attributes are then marked as manually controlled, exactly as if you had changed them yourself: the regular adaptation leaves them alone until manual control is reset (for example by `autoreset_control_seconds` or `adaptive_lighting.set_manual_control`), and an `adaptive_lighting.manual_control` event is fired. When sleep mode is on, the sleep settings are applied instead, whatever the time.
|
||||
With `time`, the lights get the values Adaptive Lighting would use at that time today. The adapted attributes are then marked as manually controlled, exactly as if you had changed them yourself: the regular adaptation leaves them alone until manual control is reset (for example by `autoreset_control_seconds` or `adaptive_lighting.set_manual_control`), and an `adaptive_lighting.manual_control` event is fired. When sleep mode is on, the sleep settings are applied instead, whatever the time. Unless `adapt_brightness` or `adapt_color` is given, only what the profile adapts (its Adapt Brightness and Adapt Color switches) is applied.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -2354,6 +2354,48 @@ async def test_apply_service_at_time_marks_manual_before_adapting(hass):
|
|||
assert manual_during_adaptation == [LightControlAttributes.ALL]
|
||||
|
||||
|
||||
async def test_apply_service_at_time_follows_adapt_switches(hass):
|
||||
"""With 'time', only what the profile adapts is applied and made manual."""
|
||||
switch, _ = await setup_lights_and_switch(hass)
|
||||
await hass.services.async_call(
|
||||
SWITCH_DOMAIN,
|
||||
SERVICE_TURN_OFF,
|
||||
{ATTR_ENTITY_ID: switch.adapt_color_switch.entity_id},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.services.async_call(
|
||||
LIGHT_DOMAIN,
|
||||
SERVICE_TURN_ON,
|
||||
{
|
||||
ATTR_ENTITY_ID: ENTITY_LIGHT_1,
|
||||
ATTR_BRIGHTNESS: 10,
|
||||
ATTR_COLOR_TEMP_KELVIN: 3000,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
switch.manager.reset(ENTITY_LIGHT_1)
|
||||
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_APPLY,
|
||||
{
|
||||
ATTR_ENTITY_ID: switch.entity_id,
|
||||
CONF_LIGHTS: [ENTITY_LIGHT_1],
|
||||
CONF_APPLY_TIME: "12:00:00",
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
attributes = hass.states.get(ENTITY_LIGHT_1).attributes
|
||||
assert attributes[ATTR_BRIGHTNESS] != 10
|
||||
assert attributes[ATTR_COLOR_TEMP_KELVIN] == 3000
|
||||
assert (
|
||||
switch.manager.get_manual_control_attributes(ENTITY_LIGHT_1)
|
||||
== LightControlAttributes.BRIGHTNESS
|
||||
)
|
||||
|
||||
|
||||
async def test_apply_service_at_time_sleep_mode_and_partial(hass):
|
||||
"""Sleep mode takes precedence, and only adapted attributes become manual."""
|
||||
switch, _ = await setup_lights_and_switch(hass, {CONF_SLEEP_TRANSITION: 0})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue