Calibrating color temperature to match multiple lights

I have some light strips that have different white color temperatures than most of my bulbs, so I wrote a script to adjust them based on a manual calibration.

The basic idea is that you set a reference light to a low temperature (2700K) and then manually find the corresponding temperature for the new light (2128K). Then you do the same thing for a high temperature (4000K and 3015K in my case).

Then you put them in the “calibration” line in the script below as [2700, 2128, 4000, 3015] with the light ID in the light line.

You need to then have the script trigger whenever you want to update. You should probably trigger on both color temperature changes and when the lights themselves turn on.

I added three other guards in this script: first, it will only change the color temperature if the light is on (so it doesn’t turn on off lights) or if it is a group, and, it only sets the color temperature if the bulb is in color_temperature mode (so if it is in color mode it won’t switch).

The example script below gets the color temperature from “input_select.global_color_temp_k” and operates on the three lights listed in the “for_each” and the trigger.

- alias: Update Color Temperature for Calibrated Lights
  id: update_color_temperature_for_calibrated_lights
  trigger:
     - platform: state
       entity_id:
         - input_select.global_color_temp_k, light.living_room_white_led_strip_no_ct, light.led_strip_2,  light.living_room_tv_led_strip
  action:
    repeat:
      for_each:
        - light: light.living_room_white_led_strip_no_ct
          calibration: [2700, 2128, 4000, 3015]
        - light: light.led_strip_2
          calibration: [2700, 2066, 4000, 4000]
        - light: light.living_room_tv_led_strip
          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

The commented out part is for debugging.

1 Like

How has this been working for you? Have there been any issues?
Does it work with automated color temperature tools like circadian rhythm, or will it get is a feedback loop?
I want to do something similar, as CCT lights from Aliexpress often in software support 2700-6500, but the actual bulbs might only go to 5500 or down to 3000.

@simnick – To make this work with my automated color temperature script I’ve modified that script to ignore these lights and instead use this one. (I do it by having my automated color temperature script ignore lights that have “_noct” in their name, and then I add that to these lights.

I don’t know of any way to do this that would effectively bypass the color temperature setting for all lights. Even if you used a Light Template, I think you would still see both the original light and the Template Light being changed by a scrip that changes all lights.

-David

1 Like