Reliably set light temperature of different light models in one area

Hey everyone!

I have a setup where there are different light models, which have different ranges of temperature, in one area. I would like to control them all at once. Since they have different temperature ranges, the lights should be set to their respective max or min temperature if I try to set the temperature to a value beyond those max/min points.

Unfortunately, simply calling the light.turn_on service with my desired mired (or kelvin) value doesn’t work reliably. If the value is outside of the range for a particular light, it will not react properly.

I tried solving this with templating the automation’s action field, along the lines of:

  {% for entityId in area_entities("living_room") if entityId.startswith("light.") %}
    {%- set target_temp = 3000 -%}
    {%- set mmax = state_attr(entityId, 'max_mireds') -%}
    {%- set mmin = state_attr(entityId, 'min_mireds') -%}
    - service: light.turn_on
    data:
      color_temp: {{ min(max(target_temp, mmin), mmax) }}
    target:
      entity_id: {{ entityId }}
  {% endfor %}

The area ID and target_temp values would, of course, be passed from outside and are just set here for testing and demonstration purposes.

Unfortunately, the action field in automations does not seem to support templating (I get the error Message malformed: expected dictionary @ data['action'][0] while trying to save the automation).

Two other options that could work but I am trying to avoid

  • Hard-code the lights into the automations. At the moment I only have one automation that, with templating, is able to automate all rooms. I don’t want to have to create (and maintain) multiple automations to set the temperature just to target different devices / areas.
  • Using a script would probably work. However, in the past, the reliability of scripts has not been great for me. So ideally I would also like to avoid scripts, although this would probably be my next attempt if nothing else is possible.

I feel like I have all the pieces: I can get target lights and I can get the correct mireds value for each light, as I do in the templating snippet above. However, I don’t seem to be able to figure out how to put this together in the context of an automation. Can anyone give me a pointer here? Many thanks!

Alright, I figured it out. I did not realize that repeat offers a for_each option. With that, I made it work as follows, directly as automation action:

repeat:
  for_each: |
    {{ area_entities(trigger.event.data.area) }}
  sequence:
    - condition: template
      value_template: '{{ repeat.item.startswith("light.") }}'
    - service: light.turn_on
      data:
        color_temp: |
          {{ min(max(trigger.event.data.mireds, state_attr(repeat.item,
          'min_mireds')), state_attr(repeat.item, 'max_mireds')) }}
      target:
        entity_id: '{{ repeat.item }}'

where the automation is triggered by an event with data along the lines of:

area: living_room
mireds: 345

This might not be super efficient, as some data has to be collected and filtered on every execution. Since I am not sure how significant of an impact that will actually have during usage, I’ll give it a try like this for a while. In theory, I suppose some of these values could be pre-computed, e.g. at server start-up.

And for future reference: the reason your first example gave an error is because the template was a single line. In that case it should have been between quotes.