Returning an entire object with templates instead of just a simple value

Hi there !

I have spent som time now struggling with templating (in a script, but not only).

I have read articles, found work-arounds, but nothing very that will be easily maintainable overtime.

My “problem” is that it seems that templating does not allow to set anything more than a simple “value” for a given “key”. You cannot create an entire “object” and assign it to a “key”.

For the sake of clarity, imagine the script below in “scripts.yml”:
(We try to dynamically create a scene then apply it altoghether.)

A requirement is that the scene can be very different from a call to another. It may not even include the same lights from a call to another… Or the list of lights could be passed as a variable…

test:
  alias: test
  sequence:
  - service: scene.apply
    data_template:
      entities:
        light.test_a:
          state: 'on'
          brightness: 100
        light.test_b:
          state: 'on'
          brightness: 100

What if you want to include or exclude a light ?
What if you want to iterate through a list of lights ?

I’d need something that would build the list of entities. Something similar to this:

test:
  alias: test
  variables:
    mode: 'dim'
  sequence:
  - service: scene.apply
    data_template:
      entities: >
        {{ '{"light.test_a":{"state":"on", "brightness": 100},
             "light.test_b":{"state":"on", "brightness": 100}}' | from_json }}

Of course the above code does not work (hence my question).

It is just an exemple. In real life you’d want to build the list of entities from a variable, then only include lights that are already ‘on’ for instance, and adjust different properties from a light to another.

But anyway, the real question here is: how do you guys achieve this kind of complexity ?
If you cannot create entire objects / trees and assign them under a “key” in the yaml file, how do you create complex scripts ?

Many thanx in advance for your time.

This will dim all lights that are on to the specified brightness.

sequence:
  - service: light.turn_on
    data:
      entity_id: {{ expand(states.light) | selectattr('state', 'eq', 'on') | map(attribute='object_id') | list | join(', ')}}
      brightness: "{{brightness}}"

You are going to be limited by the service you are trying to use. Like trying to do this with scenes.

If you want this kind of crazy stuff, you should look at AppDaemon. You can do pretty much anything you can imagine there.

It’s getting better though. 0.118 finally supports template types, so you don’t always have to return a string. I thought I read somewhere that support for template keys was being looked at, but maybe I dreamed that lol.

1 Like

Is there a reason you chose to use expand(states.light) instead of just states.light to produce a collection of all lights to feed to selectattr?

No good one. copy/paste from one of my similar automations that uses a light group. Just replaced the group with the light domain without thinking lol

Thanx very much for your time and thank you for pointing out AppDaemon which I do not know.

The “long” story here is that the thing with “scene.apply” is that it also allows for using the “transition” attribute (which I did not metion: my bad).

But “scene.apply” does not seem to allow for choosing a list of entities: not like “light.turn_on” … so I cannot choose to ignore lights that are already “on”…

Actually your script is fairly close to what I would like to achieve. Except for the transition.

I’m using a work-around:

  • I set a “brightness” anyway, but transition to “off” when the light is noton”.
    an “not on” is not as simple as it seems, because
  • Then “scene.apply” does not seem to turn the light off…
    … instead, it’s “on” with a brithness of 0 (even though I specifically set it to “off”: I guess that’s the price to pay for setting inconsistent orders in the scene…)
  • moreover, it is dirty as hell because I have to duplicate the same code over and over again to includ all light and apply the same algorithm to each of them.

This is why I was searching for a better way to “build” complex objects to be set in the data-template attribute… and I must confess that it’s been quite a frustrating experience so far

→ Here’s maybe a note to whom it may concern: there are indeed a thousand ways of doind a thousand stuffs in HA but you’ll soon realise that there are not so many ways to do the one thing you want…
… and worse than that, any small change in an automation often require a complete refactoring of the “code” and an entire change of paradigm…