Skip to content

Instantly share code, notes, and snippets.

@wbyoung
Last active March 21, 2025 21:45
Show Gist options
  • Save wbyoung/6e722a2fd891a3a41638846b52630d8b to your computer and use it in GitHub Desktop.
Save wbyoung/6e722a2fd891a3a41638846b52630d8b to your computer and use it in GitHub Desktop.
Adaptive Lighting Adjustments While Off
alias: Adjust Adaptive Lighting Controlled Lights While Off
mode: restart
triggers:
- trigger: time_pattern
minutes: /5
variables:
adjust_hue: true
adjust_inovelli: true
- trigger: state
entity_id: !include ../../entity_lists/adaptive-lighting.yaml
to: null
variables:
adjust_inovelli: true
- trigger: state
entity_id: !include ../../entity_lists/adaptive-lighting.yaml
attribute: manual_control
variables:
adjust_inovelli: true
conditions: []
action:
- alias: "Variables: adjustments"
variables:
adjustments: >
{% set ns = namespace(adjustments=[]) %}
{% set adaptive_switches = integration_entities('adaptive_lighting')
|reject('search', '_adapt_color_')
|reject('search', '_adapt_brightness_')
|reject('search', '_sleep_mode_')
|list %}
{% for adaptive_switch in adaptive_switches %}
{% set config = state_attr(adaptive_switch, 'configuration') %}
{% set brightness = state_attr(adaptive_switch, 'brightness_pct') %}
{% set temp_mired = state_attr(adaptive_switch, 'color_temp_mired') %}
{% set lights = expand(config.lights|default([]))
|map(attribute='entity_id')
|list %}
{% for light in lights %}
{% set is_off = is_state(light, 'off') %}
{% set is_adapting =
is_state(adaptive_switch, 'on') and
state_attr(adaptive_switch, 'manual_control')|length == 0 %}
{% set type = none %}
{% if device_attr(light, 'name') is search('^signify netherlands', ignorecase=true) and is_off %}
{% set type = 'hue' %}
{% elif device_attr(light, 'name') is search('^inovelli', ignorecase=true) %}
{% set smart_bulb_mode = light|regex_replace('^light\.(.*)_light', 'switch.\\1_smart_bulb_mode') %}
{% if not is_state(smart_bulb_mode, 'on') %}
{% set type = 'inovelli' %}
{% endif %}
{% endif %}
{% if not type %}{% continue %}{% endif %}
{% set ns.adjustments = ns.adjustments + [{
'type': type,
'entity_id': light,
'brightness': brightness,
'temp_mired': temp_mired,
'is_adapting': is_adapting,
}] %}
{% endfor %}
{% endfor %}
{{ ns.adjustments }}
- repeat:
for_each: '{{ adjustments }}'
sequence:
- choose:
- conditions:
- condition: template
value_template: >
{{
adjust_hue and
repeat.item.type == 'hue' and
repeat.item.is_adapting
}}
sequence:
- action: zha_toolkit.zcl_cmd
data:
ieee: "{{ repeat.item.entity_id }}"
cluster: 64515
dir: 0
manf: 4107
cmd: 0x00
# for details on the format of the arguments, see
# see https://github.com/chrivers/bifrost/blob/master/doc/hue-zigbee-format.md
args: >
{# constants #}
{% set hue_header_flags = {
'on_off': 2 ** 0,
'brightness': 2 ** 1,
'color_mired': 2 ** 2,
'color_xy': 2 ** 3,
'fade_speed': 2 ** 4,
'effect_type': 2 ** 5,
'gradient_params': 2 ** 6,
'effect_speed': 2 ** 7,
'gradient_colors': 2 ** 8,
} %}
{# arg builder #}
{% set ns = namespace(args=[]) %}
{% macro append_arg(ns, value, bytes=1) %}
{% for i in range(0, bytes) %}
{% set ns.args = ns.args + [
((value / (2 ** (i * 8)))|int % (2 ** 8))|bitwise_and(0xff),
] %}
{% endfor %}
{% endmacro %}
{# header flags for what changes are being requested #}
{% set header_flags = 0
|bitwise_or(hue_header_flags.brightness)
|bitwise_or(hue_header_flags.color_mired) %}
{# build args #}
{% set _ = append_arg(ns, header_flags, bytes=2) %}
{% set _ = append_arg(ns, (repeat.item.brightness / 100 * 253 + 1)|round) %}
{% set _ = append_arg(ns, (repeat.item.temp_mired), bytes=2) %}
{{ ns.args }}
- conditions:
- condition: template
value_template: >
{{
adjust_inovelli and
repeat.item.type == 'inovelli'
}}
sequence:
- alias: "Variables: dimming_level_id"
variables:
dimming_level_id: >
{{
repeat.item.entity_id
|regex_replace('^(?:light|fan)\.(.*?)(?:_light)?$', 'number.\\1_local_default_dimming_level')
}}
- alias: "Variables: current_dimming_level, target_dimming_level"
variables:
current_dimming_level: "{{ states(dimming_level_id) }}"
target_dimming_level: >
{{
(repeat.item.brightness / 100 * 253 + 1)|round
if repeat.item.is_adapting
else 255
}}
- if:
- condition: template
value_template: >
{{ current_dimming_level != target_dimming_level }}
then:
- action: number.set_value
target:
entity_id: "{{ dimming_level_id }}"
data:
value: "{{ target_dimming_level }}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment