WTH can't we easily increase/decrease the color temperature of a light?

TL;DR We have _step arguments for brightness in light.turn_on service. But we don’t have anything similar for the white color temperature.

Context

Let’s imagine you have a remote control (probably a Zigbee remote, but could be in whatever technology). Maybe the older IKEA 5-button remote, or the newer IKEA 4-button remote. If you would to pair these remote controls directly to a light, one pair of buttons would increase/decrease the brightness, and the other pair would increase/decrease the color temperature.

So, you may want to replicate the default behavior of those remotes, but using HA. Possibly because you want to control a non-zigbee light, or because you don’t want to go through the trouble of turning the lights on and off several times in order to pair them. Easy, right? I’m assuming most people would think about doing it.

Problem

Well, it’s not that easy. Let’s take a look at the arguments for the light.turn_on service:

  • Set absolute amounts for: hs_color, xy_color, rgb_color, rgbw_color, rgbww_color, color_temp (in mireds), kelvin, brightness, brightness_pct.
  • Set relative increments/decrements for: brightness_step, brightness_step_pct.

Let’s also take a look at the available Actions when setting up from the GUI:

  • Turn off
  • Turn on
  • Toggle
  • Increase brightness
  • Decrease brightness
  • Flash

So, it’s easy (almost trivial) to configure an automation to increase/decrease the brightness of a light. However, there is no obvious way to do the same for the color temperature.

Bonus problem 1

When decreasing the brightness, HA will happily decrease it up to zero, turning off the light. Which can make sense sometimes, but also makes it very difficult to replicate the stock behavior of those remotes: decrease the brightness until the minimum, but do not turn off the light!

This should be a WTH of its own, but I’m putting it here because it is somewhat related.

My workaround

I have the following action bound to a blueprint for the Aqara Cube controller:

service: light.turn_on
data:
  color_temp: |-
    {{ min(
         max(
           (
             (state_attr('light.example', 'color_temp') or 0)
             + (relative_degrees * 200 / 360)
           ),
           state_attr('light.example', 'min_mireds') or 0
         ),
         state_attr('light.example', 'max_mireds') or 1000
       )
    }}
target:
  entity_id: light.example

That’s… a lot of YAML for something that sounds simple. I should probably refactor this into a script, and just call that script.

Bonus problem 2

If I call light.turn_on and I pass a color_temp value outside the range, HA will set it to that out-of-range amount. That’s why I had to do the min() and max() dance; otherwise the remote would set a value that is too high, and then it would take a lot of time until the reverse action would start taking effect (and in between it would look like it’s not working).

Like I said, it’s troublesome, and it’s beyond what many people would ever bother doing themselves.

Expectation

When setting up an action, I wish I could select “Make xxx light warmer color” and “Make xxx light colder color”. Currently, I can select such actions for brightness.