mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-19 10:14:04 +02:00
Merge main before final turn-on policy review
This commit is contained in:
commit
b34db1261c
14 changed files with 2181 additions and 25 deletions
|
|
@ -16,6 +16,18 @@ Replace every entity ID below with the IDs from your Home Assistant instance. Fr
|
|||
|
||||
Blocks that begin with `- alias` are entries for `automations.yaml`. Blocks with a top-level `script:` or `adaptive_lighting:` key are complete `configuration.yaml` examples. If your configuration uses `script: !include scripts.yaml`, omit that outer key and place its contents in `scripts.yaml`.
|
||||
|
||||
Five examples also have blueprints with selectors, so you can configure them without editing YAML:
|
||||
|
||||
| Blueprint | Purpose | Import |
|
||||
| --- | --- | --- |
|
||||
| [Sleep mode](https://github.com/basnijholt/adaptive-lighting/blob/main/blueprints/automation/sleep_mode.yaml) | Synchronize several profiles with one sleep-mode helper. | [](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgithub.com%2Fbasnijholt%2Fadaptive-lighting%2Fblob%2Fmain%2Fblueprints%2Fautomation%2Fsleep_mode.yaml) |
|
||||
| [Minimum brightness](https://github.com/basnijholt/adaptive-lighting/blob/main/blueprints/automation/turn_off_at_minimum.yaml) | Turn one light off when its target crosses down to the minimum. | [](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgithub.com%2Fbasnijholt%2Fadaptive-lighting%2Fblob%2Fmain%2Fblueprints%2Fautomation%2Fturn_off_at_minimum.yaml) |
|
||||
| [Pause at minimum](https://github.com/basnijholt/adaptive-lighting/blob/main/blueprints/automation/manual_control_at_minimum.yaml) | Pause brightness through manual control, using its existing reset behavior. | [](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgithub.com%2Fbasnijholt%2Fadaptive-lighting%2Fblob%2Fmain%2Fblueprints%2Fautomation%2Fmanual_control_at_minimum.yaml) |
|
||||
| [Schedule profile](https://github.com/basnijholt/adaptive-lighting/blob/main/blueprints/automation/schedule_profile.yaml) | Apply brightness and color temperature from Schedule helper blocks. | [](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgithub.com%2Fbasnijholt%2Fadaptive-lighting%2Fblob%2Fmain%2Fblueprints%2Fautomation%2Fschedule_profile.yaml) |
|
||||
| [Daylight limit](https://github.com/basnijholt/adaptive-lighting/blob/main/blueprints/automation/daylight_limit.yaml) | Lower maximum brightness in strong daylight. | [](https://my.home-assistant.io/redirect/blueprint_import/?blueprint_url=https%3A%2F%2Fgithub.com%2Fbasnijholt%2Fadaptive-lighting%2Fblob%2Fmain%2Fblueprints%2Fautomation%2Fdaylight_limit.yaml) |
|
||||
|
||||
Click a blueprint's import badge, confirm the import in Home Assistant, then create an automation and select your entities. You can also copy its source link into **Settings → Automations & scenes → Blueprints → Import Blueprint**. Read the matching example below for setup and behavior. Each blueprint is tested through Home Assistant alongside its YAML example. The built-in manual-control timeout needs no automation; the scripts below remain useful as actions in your own automations.
|
||||
|
||||
`change_switch_settings` updates a profile while its main switch is off, but lights are adapted only while that switch is on. It preserves manual-control flags, so manually controlled lights remain paused.
|
||||
|
||||
<details markdown="1">
|
||||
|
|
@ -38,6 +50,8 @@ This is a top-level `configuration.yaml` example. The timer clears manual contro
|
|||
<details markdown="1">
|
||||
<summary>Toggle multiple Adaptive Lighting switches to "sleep mode" using an <code>input_boolean.sleep_mode</code>.</summary>
|
||||
|
||||
Also available as a [blueprint](https://github.com/basnijholt/adaptive-lighting/blob/main/blueprints/automation/sleep_mode.yaml). Select an input boolean and the sleep-mode switches it should control.
|
||||
|
||||
```yaml
|
||||
- alias: "Adaptive lighting: toggle 'sleep mode'"
|
||||
trigger:
|
||||
|
|
@ -60,6 +74,145 @@ This is a top-level `configuration.yaml` example. The timer clears manual contro
|
|||
|
||||
</details>
|
||||
|
||||
<details markdown="1">
|
||||
<summary>Turn a light off when its adaptive brightness target reaches the minimum.</summary>
|
||||
|
||||
Prefer a form over editing YAML? Import the [blueprint](https://github.com/basnijholt/adaptive-lighting/blob/main/blueprints/automation/turn_off_at_minimum.yaml) in Home Assistant under **Settings → Automations & scenes → Blueprints → Import Blueprint**. Select your profile, its matching adapt brightness switch, one light managed by that profile, and its minimum brightness percentage. Create one automation per light. If you change the profile's minimum later, update the automation too. The blueprint and YAML example below have the same behavior.
|
||||
|
||||
The Adaptive Lighting switch already exposes its calculated `brightness_pct` target. Use its state changes to choose a power policy in an automation; no custom event is needed. This example assumes `min_brightness: 1`. Change `minimum_pct` to match your profile, and replace the switch and light entity IDs with your own.
|
||||
|
||||
The comparison uses the same rounded 0–255 brightness as an adaptation command. Comparing floating-point percentages for exact equality can miss the minimum between updates. This detects the calculated target reaching its minimum command, not the bulb finishing a transition or reaching its physical dimming limit.
|
||||
|
||||
```yaml
|
||||
- alias: "Adaptive lighting: turn off at minimum brightness"
|
||||
mode: single
|
||||
triggers:
|
||||
- trigger: state
|
||||
entity_id: switch.adaptive_lighting_living_room
|
||||
attribute: brightness_pct
|
||||
conditions:
|
||||
- condition: state
|
||||
entity_id:
|
||||
- switch.adaptive_lighting_living_room
|
||||
- switch.adaptive_lighting_living_room_adapt_brightness
|
||||
state: "on"
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{% set minimum_pct = 1 %}
|
||||
{% set minimum = (minimum_pct * 255 / 100) | round(0) %}
|
||||
{% set before = trigger.from_state.attributes.get('brightness_pct')
|
||||
if trigger.from_state else none %}
|
||||
{% set after = trigger.to_state.attributes.get('brightness_pct')
|
||||
if trigger.to_state else none %}
|
||||
{{ is_number(before) and is_number(after)
|
||||
and (before | float * 255 / 100) | round(0) > minimum
|
||||
and (after | float * 255 / 100) | round(0) <= minimum }}
|
||||
- condition: state
|
||||
entity_id: light.living_room
|
||||
state: "on"
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{{ 'light.living_room' not in
|
||||
(state_attr('switch.adaptive_lighting_living_room', 'manual_control') or []) }}
|
||||
actions:
|
||||
- action: light.turn_off
|
||||
target:
|
||||
entity_id: light.living_room
|
||||
```
|
||||
|
||||
This runs once when a valid target crosses down into the minimum range. It skips lights currently marked as manually controlled, does not repeatedly turn them off while the target remains low, and does not turn them back on later. Startup or re-enabling the profile while already at the minimum is not a new crossing. Sleep mode can also cause a crossing if its brightness is at or below the chosen minimum. Changing sleep mode clears manual control by default; set `reset_manual_control_on_sleep_mode_change: false` if you want to preserve it. For a bedtime-only policy, trigger directly on the sleep-mode switch changing to `on` instead.
|
||||
|
||||
</details>
|
||||
|
||||
<details markdown="1">
|
||||
<summary>Pause brightness at the minimum using manual control.</summary>
|
||||
|
||||
Use the [blueprint](https://github.com/basnijholt/adaptive-lighting/blob/main/blueprints/automation/manual_control_at_minimum.yaml) to mark an individual light's brightness as manually controlled when the calculated target reaches its minimum. The light stays on and the adaptation switches stay enabled. Set `take_over_control_mode: pause_changed` on the profile to keep adapting color; the default `pause_all` pauses both attributes.
|
||||
|
||||
Select the profile, its adapt-brightness switch, and a light managed by it. Match the minimum percentage to the profile's `min_brightness`. This YAML example assumes `min_brightness: 1`; change `minimum_pct` and the entity IDs to match your setup.
|
||||
|
||||
```yaml
|
||||
- alias: "Adaptive lighting: pause brightness at minimum"
|
||||
mode: single
|
||||
variables:
|
||||
minimum_pct: 1
|
||||
minimum: "{{ (minimum_pct * 255 / 100) | round(0) }}"
|
||||
triggers:
|
||||
- trigger: state
|
||||
entity_id: switch.adaptive_lighting_living_room
|
||||
attribute: brightness_pct
|
||||
conditions:
|
||||
- condition: state
|
||||
entity_id:
|
||||
- switch.adaptive_lighting_living_room
|
||||
- switch.adaptive_lighting_living_room_adapt_brightness
|
||||
state: "on"
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{% set before = trigger.from_state.attributes.get('brightness_pct')
|
||||
if trigger.from_state else none %}
|
||||
{% set after = trigger.to_state.attributes.get('brightness_pct')
|
||||
if trigger.to_state else none %}
|
||||
{{ is_number(before) and is_number(after)
|
||||
and (before | float * 255 / 100) | round(0) > minimum
|
||||
and (after | float * 255 / 100) | round(0) <= minimum }}
|
||||
- condition: state
|
||||
entity_id: light.living_room
|
||||
state: "on"
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{{ 'light.living_room' not in
|
||||
(state_attr('switch.adaptive_lighting_living_room', 'manual_control_brightness') or []) }}
|
||||
actions:
|
||||
- variables:
|
||||
light_session: "{{ states.light.living_room.last_changed.isoformat() }}"
|
||||
profile_session: "{{ states.switch.adaptive_lighting_living_room.last_changed.isoformat() }}"
|
||||
brightness_session: "{{ states.switch.adaptive_lighting_living_room_adapt_brightness.last_changed.isoformat() }}"
|
||||
- wait_template: >-
|
||||
{% set target = state_attr('switch.adaptive_lighting_living_room', 'brightness_pct') %}
|
||||
{{ not is_state('light.living_room', 'on')
|
||||
or not is_state('switch.adaptive_lighting_living_room', 'on')
|
||||
or not is_state('switch.adaptive_lighting_living_room_adapt_brightness', 'on')
|
||||
or states.light.living_room.last_changed.isoformat() != light_session
|
||||
or states.switch.adaptive_lighting_living_room.last_changed.isoformat() != profile_session
|
||||
or states.switch.adaptive_lighting_living_room_adapt_brightness.last_changed.isoformat() != brightness_session
|
||||
or not is_number(target) or (target | float * 255 / 100) | round(0) > minimum
|
||||
or 'light.living_room' in
|
||||
(state_attr('switch.adaptive_lighting_living_room', 'manual_control_brightness') or [])
|
||||
or (state_attr('light.living_room', 'brightness') | float(256)) <= minimum }}
|
||||
timeout: "00:05:00"
|
||||
continue_on_timeout: false
|
||||
- condition: template
|
||||
value_template: >-
|
||||
{% set target = state_attr('switch.adaptive_lighting_living_room', 'brightness_pct') %}
|
||||
{{ is_state('light.living_room', 'on')
|
||||
and is_state('switch.adaptive_lighting_living_room', 'on')
|
||||
and is_state('switch.adaptive_lighting_living_room_adapt_brightness', 'on')
|
||||
and states.light.living_room.last_changed.isoformat() == light_session
|
||||
and states.switch.adaptive_lighting_living_room.last_changed.isoformat() == profile_session
|
||||
and states.switch.adaptive_lighting_living_room_adapt_brightness.last_changed.isoformat() == brightness_session
|
||||
and is_number(target) and (target | float * 255 / 100) | round(0) <= minimum
|
||||
and (state_attr('light.living_room', 'brightness') | float(256)) <= minimum
|
||||
and 'light.living_room' not in
|
||||
(state_attr('switch.adaptive_lighting_living_room', 'manual_control_brightness') or []) }}
|
||||
- action: adaptive_lighting.set_manual_control
|
||||
data:
|
||||
entity_id: switch.adaptive_lighting_living_room
|
||||
lights: light.living_room
|
||||
manual_control: >-
|
||||
{{ true if 'light.living_room' in
|
||||
(state_attr('switch.adaptive_lighting_living_room', 'manual_control_color') or [])
|
||||
else 'brightness' }}
|
||||
```
|
||||
|
||||
The comparison uses the rounded 0–255 target, so it does not depend on sampling an exact floating-point minimum. It waits up to five minutes for the light to report that minimum before marking manual control, so the final dimming command can complete. Reported brightness does not prove physical fade completion. If the light, profile, or adapt-brightness switch is toggled, the target rises, brightness is marked manually controlled elsewhere, or brightness never reaches the minimum, the attempt is abandoned. Lights that cannot report the configured minimum will not be paused. Existing manual color flags are preserved, and lights whose brightness is already manually controlled are left alone. Manual-control state is shared for lights managed by multiple profiles, so their existing takeover policies still apply.
|
||||
|
||||
The usual resets apply: turning the light off, the configured `autoreset_control_seconds` timeout, clearing manual control through its service, and existing profile/sleep-switch reset behavior. After a reset, normal adaptation can increase brightness again. This runs once per downward crossing; resetting while the target remains at its minimum does not immediately mark the light again. Startup at the minimum is not a crossing either.
|
||||
|
||||
This pauses further dimming as well as brightening. To pause brightness immediately after a brightness change made through Home Assistant, use `take_over_control_mode: pause_changed` with `take_over_control: true`; that needs no additional automation.
|
||||
|
||||
</details>
|
||||
|
||||
<details markdown="1">
|
||||
<summary>Set sunrise and sunset from an alarm.</summary>
|
||||
|
||||
|
|
@ -86,6 +239,8 @@ script:
|
|||
<details markdown="1">
|
||||
<summary>Use a Schedule helper as a step-based custom lighting profile.</summary>
|
||||
|
||||
Also available as a [blueprint](https://github.com/basnijholt/adaptive-lighting/blob/main/blueprints/automation/schedule_profile.yaml). Select the main profile switch and your Schedule helper.
|
||||
|
||||
Create a [Schedule helper](https://www.home-assistant.io/integrations/schedule/) named `Adaptive Lighting Profile`. Add time blocks with Additional data like this:
|
||||
|
||||
```yaml
|
||||
|
|
@ -135,6 +290,8 @@ This creates step changes at block boundaries. It does not interpolate between s
|
|||
<details markdown="1">
|
||||
<summary>Reduce daytime brightness when an illuminance sensor detects strong daylight.</summary>
|
||||
|
||||
Also available as a [blueprint](https://github.com/basnijholt/adaptive-lighting/blob/main/blueprints/automation/daylight_limit.yaml). Select the profile and sensor, then set the lux thresholds and brightness limits. The high lux threshold must exceed the low threshold; the blueprint does nothing if they are reversed or equal.
|
||||
|
||||
Keep a low configured `min_brightness` for late night and let an automation lower `max_brightness` while the room has ample daylight. Use a sensor that is not significantly affected by the controlled lights to avoid a feedback loop.
|
||||
|
||||
```yaml
|
||||
|
|
|
|||
|
|
@ -25,6 +25,16 @@ logger:
|
|||
|
||||
After the issue occurs, create a new issue report with the log (`/config/home-assistant.log`).
|
||||
|
||||
For support, use Home Assistant's **Download diagnostics** action on the
|
||||
Adaptive Lighting config entry. The download is an on-demand snapshot of the
|
||||
profile's current switches and currently tracked light targets. It does not
|
||||
refresh group membership or predict targets a disabled profile would use after
|
||||
being enabled. It does not create live sensors; existing switch attributes
|
||||
remain the interface for automations.
|
||||
The reported last adaptation values are the shared manager's latest retained
|
||||
value for each attribute. They can come from different commands and do not
|
||||
represent one sent command or the current desired state.
|
||||
|
||||
<!-- OUTPUT:END -->
|
||||
|
||||
## Common Problems & Solutions
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue