Nanoleaf Essentials bulbs brightness transition script

So currently transitioning (fading) your Nanoleaf Essentials bulbs from one brightness to another using the built-in method does not work. So here is a script that will allow you to add transitions to your automations and other scripts. You will need to create input_boolean.transition_running. I use that in my scripts/automations to stop the script if I want to run it again.

For example, I have automatic theater lighting, so when the TV is playing the lights dim, when the TV stops the lights slowly brighten. So if I pause and then unpause a TV show the brighten transition may still be running when I turn the show back on. I don’t want to wait for the lights to get to full brightness before dimming again. I want the lights to start dimming right away.

Also, I have to pause my circadian light automation while a transition is running otherwise they both try to run at the same time and the lights are overloaded with commands. So, this input_boolean.transition_running makes pausing and starting that automation much more convenient.

Enjoy! and feel free to give feedback or ask questions.

alias: Light Transition
fields:
  target_lights:
    name: Lights
    description: Light to transition
    required: true
    selector:
      entity:
        domain: light
        multiple: false
  to_brightness_pct:
    name: Brightness
    description: Percent brightness desired
    required: true
    selector:
      number:
        min: 0
        max: 100
  seconds_of_transition:
    name: Transition
    description: How many seconds to transition
    required: true
    default: 2
    selector:
      number:
        min: 1
        max: 200
variables:
  to_brightness_a: "{{ (to_brightness_pct | int * 2.55) | int }}"
  from_brightness_b: >-
    {{ 0 if state_attr(target_lights, 'brightness') is none else
    state_attr(target_lights, 'brightness') | int }}
  transition_step_count_c: "{{ seconds_of_transition | int * 4 - 1 }}"
  transition_step_amount_d: >-
    {{ ((to_brightness_a - from_brightness_b) / transition_step_count_c) | float
    }}
sequence:
  - service: input_boolean.turn_on
    data: {}
    target:
      entity_id: input_boolean.transition_running
  - if:
      - condition: template
        value_template: "{{ is_state(target_lights, 'off') }}"
    then:
      - service: light.turn_on
        data:
          brightness: 5
        target:
          entity_id: "{{ target_lights }}"
      - delay:
          hours: 0
          minutes: 0
          seconds: 0
          milliseconds: 250
    enabled: true
  - service: automation.turn_off
    data: {}
    target:
      entity_id: automation.circadian_color_temperature
  - repeat:
      count: "{{ transition_step_count_c }}"
      sequence:
        - if:
            - condition: state
              entity_id: input_boolean.transition_running
              state: "off"
          then:
            - stop: ""
        - service: light.turn_on
          data:
            brightness: >-
              {{ max(from_brightness_b + (transition_step_amount_d *
              repeat.index), 5) }}
          target:
            entity_id: "{{ target_lights }}"
        - delay:
            hours: 0
            minutes: 0
            seconds: 0
            milliseconds: 250
    enabled: true
  - if:
      - condition: state
        entity_id: input_boolean.transition_running
        state: "off"
    then:
      - stop: ""
  - if:
      - condition: template
        value_template: "{{ to_brightness_a | int == 0 }}"
    then:
      - service: light.turn_off
        data: {}
        target:
          entity_id: "{{ target_lights }}"
    else:
      - service: light.turn_on
        data:
          brightness: "{{ max(to_brightness_a, 5) | int }}"
        target:
          entity_id: "{{ target_lights }}"
  - delay:
      hours: 0
      minutes: 0
      seconds: 1
      milliseconds: 0
  - service: input_boolean.turn_off
    data: {}
    target:
      entity_id: input_boolean.transition_running
mode: parallel
max: 10

Can you create a video on how this works? It’s a little hard to follow as a beginner here.

What part are you having a hard time following? Are you able to copy the script into your Home Assistant?

Hey,

Thanks @themanieldaniel for the script !
I took the liberty to update it a bit for my personal convenience:

  • Most important change: replace the use of input_boolean.transition_running by input_text.lights_transitioning. This list contains the lights id’s that are currently transitioning. This allows for multiple lights parallel execution, while restarting if the same light is transitioned again before the end of the current transition
  • change variables names
  • replace circadian automation with adaptive lighting manual mode
  • put light.turn_on and wait in parallel to avoid extra waiting time as the light.turn_on service already has some latency → this will wait for the longest command to end before continuing the loop
alias: Light Transition
fields:
  target_lights:
    name: Lights
    description: Light to transition
    required: true
    selector:
      entity:
        domain: light
        multiple: false
  to_brightness_pct:
    name: Brightness
    description: Percent brightness desired
    required: true
    selector:
      number:
        min: 0
        max: 100
  seconds_of_transition:
    name: Transition
    description: How many seconds to transition
    required: true
    default: 2
    selector:
      number:
        min: 1
        max: 200
variables:
  steps_per_second: 10
  steps_total: "{{ seconds_of_transition | int * steps_per_second }}"
  interval_ms: "{{ (1000 / steps_per_second) }}"
  brightness_from: >-
    {{ 0 if state_attr(target_lights, 'brightness') is none else
    state_attr(target_lights, 'brightness') | int }}
  brightness_to: "{{ (to_brightness_pct | int * 2.55) | int }}"
  brightness_step_delta: "{{ (brightness_to - brightness_from) / steps_total | float }}"
sequence:
  - if:
      - condition: template
        value_template: |
          {{ target_lights in states('input_text.lights_transitioning') }}
    then:
      - service: input_text.set_value
        data:
          value: >-
            {{ states('input_text.lights_transitioning') |
            replace(target_lights+',', '') }}
        target:
          entity_id: input_text.lights_transitioning
        alias: Remove light from transitioning lights list
      - delay:
          hours: 0
          minutes: 0
          seconds: 0
          milliseconds: "{{ interval_ms }}"
    alias: Cancel any running transition for the same light
  - service: input_text.set_value
    data:
      value: "{{ states('input_text.lights_transitioning') + target_lights + ',' }}"
    target:
      entity_id: input_text.lights_transitioning
    alias: Add light to transitioning lights list
  - continue_on_error: true
    service: adaptive_lighting.set_manual_control
    data:
      manual_control: true
      lights:
        - "{{ target_lights }}"
    alias: Disable Adaptive Lighting on the lights
    enabled: true
  - if:
      - condition: template
        value_template: "{{ is_state(target_lights, 'off') }}"
    then:
      - service: light.turn_on
        data:
          brightness_pct: 1
        target:
          entity_id: "{{ target_lights }}"
    enabled: true
    alias: If light is off, turn it on to minimum
  - repeat:
      count: "{{ steps_total | int - 1 }}"
      sequence:
        - if:
            - condition: template
              value_template: >-
                {{ target_lights not in
                states('input_text.lights_transitioning') }}
          then:
            - stop: Transition is restarting for the light
          alias: Stop if transition is restarting for same light
        - parallel:
            - continue_on_error: true
              service: light.turn_on
              data:
                brightness: >-
                  {{ max(brightness_from + (brightness_step_delta *
                  (repeat.index)), 5) }}
              target:
                entity_id: "{{ target_lights }}"
              alias: Transition light
            - delay:
                hours: 0
                minutes: 0
                seconds: 0
                milliseconds: "{{ interval_ms }}"
    enabled: true
    alias: Transition light {{steps_total - 1 }} times
  - if:
      - condition: template
        value_template: "{{ target_lights not in states('input_text.lights_transitioning') }}"
    then:
      - stop: Transition is restarting for the light
    alias: Stop if transition is restarting for same light
  - service: light.turn_on
    data:
      brightness_pct: "{{ to_brightness_pct }}"
    target:
      entity_id: "{{ target_lights }}"
    alias: "Last step: set light to requested brightness %"
  - service: input_text.set_value
    data:
      value: >-
        {{ states('input_text.lights_transitioning') |
        replace(target_lights+',', '') }}
    target:
      entity_id: input_text.lights_transitioning
    alias: Remove light from transitioning lights list
mode: parallel
max: 10
icon: mdi:lightbulb-on-40
1 Like

Great work @damru and thanks for taking the time to adjust the script and post it!

Since posting my script over 6 months ago I have made several adjustments as well and cringe a little bit at my original script. But I don’t regret posting it because it was functional and I realize everything has to have a starting point. I am still learning and improving my templating and scripting skills and trying new approaches to getting things automated.

Thanks again for the feedback and letting me know that this was a starting point for you.

Just deployed this and it’s been the perfect solution to a perplexing issue. So thanks for that!

I was wondering if this could be used to specify the intended color or temp instead of just brightness? My thought is that it could transition to meet adaptive lighting where it is currently configured for more advanced wake-up tuning for specific days or triggers.

Ideally Nanoleaf would just release more developer documentation for these bulbs, but from what I see on their forums, it’s been requested for awhile and there’s nothing.

whats your new code look like?
Just got some bulbs. Fooling around.