First automation scenario with a lightbulb: I want to change brightness and/or Kelvins depending on week days and hours

Hello there,
I want to do something fairly simple with my lightbulbs, but after several tries, I apparently don’t have the correct knowledge. Would you mind to help me ?

Hardware
HASS: Raspberry 3+ with Home Assistant OS

Light: Ledvance SMART+ classic A 60 E27 tunable white, “Ledvance A60 TW Value II” as displayed in HASS (Amazon link)

What I want to do

I want to change lightbulb “heat” color to 4000 K on work hours, and 2700 K outside of them. If not possible, lower brightness outside of work hours.
I’d like the change to be effective wether the lightbulb is on or off (no smart switch yet).
I’m comfortable with file editing (my job is related to coding).

What I did so far

  1. I added two “entries” (helpers ? I’m not in english, this is the 4th tab in Settings > devices […]): input_datetime.teletravail_heure_debut (value=9) and input_datetime.teletravail_heure_fin (value=18).

  2. I added a “binary sensor” in configuration.yaml file (edited with “File editor” 5.5.0 addon), as suggested on some page:

binary_sensor:
  - platform: workday
    name: Jours de télétravail
    country: FR
    workdays: [mon, tue, wed, thu]
    excludes: [fri, sat, sun, holiday]
#    add_holidays: []

After several failed attemps I tried the UX in HASS and the yaml generated is as follow:

alias: Heures de travail
description: ""
trigger: []
condition:
  - condition: time
    after: input_datetime.teletravail_heure_debut
    before: input_datetime.teletravail_heure_fin
    weekday:
      - mon
      - tue
      - wed
      - thu
action:
  - device_id: 7183e38aa54080048a4370e6721ade08
    domain: light
    entity_id: light.ledvance_a60_tw_value_ii_light
    type: flash
mode: single

It misses the holidays or some manual tuning I had in the binary sensor but well ok, not that important.

  1. I tried to make a scenario but for this device I don’t have any action like “set brightness” or “set color temperature” or anything that look like it.
    I have the following actions available: switch on or off, toggle, increase or decrease brightness, define value “start-up current level” (value range 0-255), define value for “start-up color temperature” (value range 153-370), identify (makes the lightbulb blink).

I tried several times to change the values manually in “start-up current level” and “start-up color temperature”, but it does absolutely nothing whatever I try after that: switch off then on via the current switch or via the HASS UX switch, waiting 10s after/before or not.

Can anyone help me understand what I did wrong ?

Thank you for your time :slight_smile:

You need a trigger for your automation… when should the conditions be tested?

Not all lights will support changing their attributes with the light off. So unless you are fine about turning the lights on in order to change that, this will be a challenge.

Call the service light.turn_on instead and you will have all the options you are looking for. :wink:

Something like this:

action:
  - service: light.turn_on
    target:
      entity_id: light.ledvance_a60_tw_value_ii_light
    data:
      kelvin: 4000

And in the end your automation could look like this (there’s lots of spaces for improvement in this example):

alias: Heures de travail
description: ""
trigger:
  - platform: time_pattern
    minutes: /1
condition:
  - condition: state
    entity_id: light.ledvance_a60_tw_value_ii_light
    state: "on"
action:
  - if:
      - condition: time
        after: input_datetime.teletravail_heure_debut
        before: input_datetime.teletravail_heure_fin
        weekday:
          - mon
          - tue
          - wed
          - thu
    then:
      - service: light.turn_on
        data:
          kelvin: 4000
        target:
          entity_id: light.ledvance_a60_tw_value_ii_light
    else:
      - service: light.turn_on
        data:
          kelvin: 2700
        target:
          entity_id: light.ledvance_a60_tw_value_ii_light
mode: single
1 Like

Wow, awesome!

So, the way to handle the situation when the light is off is to make it repeat every minute. Interesting, I’ll remember that.
However, when I switch off the light via wall switch, I think the state stays “on” in HASS. Not sure your condition will return false unless I switch it off via HASS or smart switch (do’nt have one yet, but it’s planned).
With that in mind, it means the zigbee signal will be sent every minute when light is on, which is 100% of the time in my actual configuration, including during sleep. I’m not confortable with this. Is there any way to detect if device is visible or something equivalent to “can receive instructions”?

Question: can we make a condition in the action>if, based on current color settings ? Like “set it to 4000 K if it’s not 4000 K”.

Not necessarily. It probably will work better if you have as trigger each time it crossed one of the times defined in your input Helpers, so you don’t have to run it all the time and will run only when needed, with the advantage of not changing the light settings every minute is someone changed manually.
I’ve used once a minute just to have some trigger… It was an easy one, not the best one. :wink:
This one will probably be better as it triggers only when you cross your two time sets (when you want to change the light settings):


alias: Heures de travail
description: ""
trigger:
  - platform: time
    at: input_datetime.teletravail_heure_debut
  - platform: time
    at: input_datetime.teletravail_heure_fin
condition:
  - condition: state
    entity_id: light.ledvance_a60_tw_value_ii_light
    state: "on"
action:
  - if:
      - condition: time
        after: input_datetime.teletravail_heure_debut
        before: input_datetime.teletravail_heure_fin
        weekday:
          - mon
          - tue
          - wed
          - thu
    then:
      - service: light.turn_on
        data:
          kelvin: 4000
        target:
          entity_id: light.ledvance_a60_tw_value_ii_light
    else:
      - service: light.turn_on
        data:
          kelvin: 2700
        target:
          entity_id: light.ledvance_a60_tw_value_ii_light
mode: single

When you cut off the lights power, it will probably stay on the last state for a few seconds until the system detects it is not communicating anymore and the it’s state in Home Assistant will become either “unknown” or “unavailable”.
During those few seconds, the condition I’ve created is not preventing HA to send the turn on command, which probably will result in an error entry in your log. After those few seconds, when the light is unavailable, the automation will stop running, as one of the conditions is to have the lights “on”.

Yeap. You can add a condition for the attribute kelvin of your light. Something like:

condition: state
entity_id: light.balcony_lamp_light
attribute: kelvin
state: 4000

But I wouldn’t spend time with that… If you send a new command to set a light to the same point the light is already, nothing is gonna happen, so I won’t be spending more time to reduce this command flowing a couple of times per day. But if you want to remove that, another condition testing for the kelvin value will be pretty easy.

1 Like

Well, having your Zigbee lights connected to a physical light switch can be an issue. If your Zigbee network have more than that light, is it possible that other devices will use your light as a router in the mesh, and when the light turns off you will have your mesh network failing until the mesh is rebuilt. You probably will feel some failures or slowness in your network.
You should really go to a smart switch. You can buy some cheap Zigbee buttons (Amazon, Ikea, Lidl, etc.). If you are using a Zigbee controller connected to your Home Assistant most of the buttons will be supported.
The Zigbee protocol allows you even to connect your button directly to your light without using Home Assistant, which will make your network even more reliable.

Holy @$*%, I never thought about that. Should I run a command or something to rebuild the mesh ?

hmm do I have to do something specific for that? Depending 100% on Home Assistant is the very reason buying ZigBee switch was not my priority.

I do rely on HA for my Zigbee network. That is not an issue… but you have to be aware that your zigbee network will be out for a couple of minutes every time you restart Home Assistant, which shouldn’t happen that often and so is not a problem for me.
But if you want to increase this reliability, that is definitely something to look at as this is one of the nicer features on Zigbee.
How to set that depend on which Zigbee integration you are using (ZHA, Zigbee2MQTT, Deconz, etc.).

How do I know that? I remember having Zigbee2MQTT being installed at one point, but that was for a specific need which ended impossible (using ZGP switches) so I probably removed it.
Which one car work without Home Assistant?

ZHA - Zigbee Home Automation

If you open your light settings on Home Assistant and select the “Related” tab you should be able to see the type of integration used:

1 Like

Ok, I think I’m good then :slight_smile:

I am, right?

Ok, you are using ZHA… There’s not right or wrong here… Each solutions have its pros and cons…

You can find more about binding zigbee devices on a ZHA environment here:

1 Like

Hi,
Here is what I did to auto-adjust color temperature for all the lights I want:

First, I have an automation that triggers every 10 minutes, whenever any lights change, or if the global color temperature changes. It triggers a “update_color_temperature” event.

- alias: Trigger Color Temperature Update
  id: trigger_color_temperature_update
  mode: single
  trigger:
    - platform: time_pattern
      minutes: "/10"
    - platform: state
      entity_id: sensor.on_lights
    - platform: state
      entity_id: input_select.global_color_temp_k
  action:
    - delay: "00:00:05"
    - event: update_color_temperature

Then I have a script that goes through all lights and looks for lights that are:
“on” AND “not groups” AND “in color_temp mode” AND “have a different color temp” AND "do not have no_ct in their name.

For all those bulbs, it sets the color temp to the value of input_select.global_color_temp_k.

This prevents any lights that are off from turning on, doesn’t change lights that are in color mode, and only updates lights that need to be updated. When a light is turned on, the update gets triggered and the light automatically adjusts.

For some lights that I don’t want to change, I just add “no_ct” to the end of their name and they are skipped.

- alias: Auto Update Lights Color Temperature
  id: auto_update_lights_color_temperature
  mode: restart
  trigger:
    - platform: event
      event_type: update_color_temperature
  action:
    # - service: system_log.write
    #   data:
    #     message: >
    #       {% for state in states.light
    #       if is_state(state.entity_id, 'on')
    #       and (state_attr(state.entity_id, 'entity_id') == None)
    #       and (state_attr(state.entity_id, 'color_mode') == 'color_temp')
    #       and ('no_ct' not in state.entity_id)  -%}
    #           {{state.entity_id}}{{ "," if not loop.last else "" }}
    #       {%- endfor %}
    #     level: warning
    ## 26-Aug-2022: Use a choose so we don't do anything if there are no lights to change
    - choose:
        # Check if there are any lights to adjust and only do so if there are!
        - conditions: >
            {% for state in states.light 
              if is_state(state.entity_id, 'on') 
              and (state_attr(state.entity_id, 'entity_id') == None)
              and (state_attr(state.entity_id, 'color_mode') == 'color_temp')
              and (state_attr(state.entity_id,'color_temp')|int(370) != ((1000000/(states('input_select.global_color_temp_k')|int(2700)))|int))
              and ('no_ct' not in state.entity_id)  -%}
              {%- if loop.first -%}
                {{"true" if loop.length>0 else "false"}}
              {%- endif -%}
            {%- endfor %}
          sequence:
            # - service: system_log.write
            #   data:
            #     message: "Need to adjust temperature."
            #     level: warning
            - service: light.turn_on
              data:
                entity_id: >
                  {% for state in states.light 
                  if is_state(state.entity_id, 'on') 
                  and (state_attr(state.entity_id, 'entity_id') == None) 
                  and (state_attr(state.entity_id, 'color_mode') == 'color_temp') 
                  and (state_attr(state.entity_id,'color_temp')|int(370) != ((1000000/(states('input_select.global_color_temp_k')|int(2700)))|int))
                  and ('no_ct' not in state.entity_id)  -%}
                      {{state.entity_id}}{{ "," if not loop.last else "" }}
                  {%- endfor %}
                color_temp: "{{(1000000/(states('input_select.global_color_temp_k')|int(2700)))|int}}"
                transition: 10

However, I have some lights that don’t match in color temperature, so for them I have a custom calibration automation that is also triggered:

- alias: Update Color Temperature for Calibrated Lights
  id: update_color_temperature_for_calibrated_lights
  trigger:
    - platform: event
      event_type: update_color_temperature
  action:
    repeat:
      for_each:
        - light: light.living_room_white_led_strip_no_ct
          calibration: [2700, 2128, 4000, 3015]
        - light: light.living_room_tv_led_strip_no_ct
          calibration: [2700, 2066, 4000, 4000]
        - light: light.led_strip_2_no_ct
          calibration: [2700, 2066, 4000, 4000]
      sequence:
        # Check if it is on, not a group, and in color_temp mode
        - if: "{{ is_state(repeat.item.light, 'on') and (state_attr(repeat.item.light, 'entity_id') == None) and (state_attr(repeat.item.light, 'color_mode') == 'color_temp') }}"
          then:
            # - service: system_log.write
            #   data:
            #     message: >
            #       {%- set desired_low = repeat.item.calibration[0]|int(2700) -%}
            #       {%- set actual_low = repeat.item.calibration[1]|int(2700) -%}
            #       {%- set desired_high = repeat.item.calibration[2]|int(4000) -%}
            #       {%- set actual_high = repeat.item.calibration[3]|int(4000) -%}
            #       {%- set scale = (actual_high-actual_low)/(desired_high-desired_low)|float(1.0) -%}
            #       {%- set offset = (actual_low)-(desired_low)*scale|float(0.0) -%}
            #       {%- set target = states('input_select.global_color_temp_k')|float(2700) -%}
            #       {%- set use = target*scale+offset -%}
            #       "Calibrated color temperature for {{repeat.item.light}} is {{use}} with scale: {{scale}}, offset: {{offset}}, target: {{target}}."
            - service: light.turn_on
              data:
                entity_id: "{{ repeat.item.light }}"
                kelvin: >
                  {%- set desired_low = repeat.item.calibration[0]|int(2700) -%}
                  {%- set actual_low = repeat.item.calibration[1]|int(2700) -%}
                  {%- set desired_high = repeat.item.calibration[2]|int(4000) -%}
                  {%- set actual_high = repeat.item.calibration[3]|int(4000) -%}
                  {%- set scale = (actual_high-actual_low)/(desired_high-desired_low)|float(1.0) -%}
                  {%- set offset = (actual_low)-(desired_low)*scale|float(0.0) -%}
                  {%- set target = states('input_select.global_color_temp_k')|float(2700) -%}
                  {{ target*scale+offset|int(target) }}
                transition: 10

I also have automations that change the color temperature during the day. This also triggers an update of all bulbs:

- alias: "Auto Color Temp Wakeup 1"
  id: auto_color_temp_wakeup_1
  trigger:
    platform: time
    at: "06:00:00"
  action:
    - service: input_select.select_option
      data:
        entity_id: input_select.global_color_temp_k
        option: "2700"

- alias: Auto Color Temp Morning 2
  id: auto_color_temp_morning_2
  trigger:
    platform: time
    at: "06:55:00"
  action:
    - service: input_select.select_option
      data:
        entity_id: input_select.global_color_temp_k
        option: "3000"

- alias: Auto Color Temp Day 3
  id: auto_color_temp_day_3
  trigger:
    platform: time
    at: "08:00:00"
  action:
    - service: input_select.select_option
      data:
        entity_id: input_select.global_color_temp_k
        option: "3300"

- alias: Auto Color Temp Afternoon 4
  id: auto_color_temp_afternoon_4
  trigger:
    platform: time
    at: "17:00:00"
  action:
    - service: input_select.select_option
      data:
        entity_id: input_select.global_color_temp_k
        option: "3000"

- alias: Auto Color Temp Evening 5
  id: auto_color_temp_evening_5
  trigger:
    platform: time
    at: "20:00:00"
  action:
    - service: input_select.select_option
      data:
        entity_id: input_select.global_color_temp_k
        option: "2700"

- alias: Auto Color Temp Night 6
  id: auto_color_temp_night_6
  trigger:
    platform: time
    at: "22:00:00"
  action:
    - service: input_select.select_option
      data:
        entity_id: input_select.global_color_temp_k
        option: "2500"

The problem of turning off lights and losing them from the mesh is a big one!
I have 14 bulbs on track lights, and when the wall switch goes off the mesh gets totally screwed up.
So what I did was have one ZigBee network for those bulbs and one for remotes. This means even when the wall switch is shut off, the network the remotes are on does not get affected.

1 Like

That’s a lot of useful stuff here. I don’t understand all of it, but I’m glad it is there and I will study it once I have a bit of free time. Thank you!