Data_template - Need help formatting this

Hi,

Can anyone kindly show me the correct way to format this template as I know it’s wrong but not sure how it is supposed to be :confused:

  action:
  - service: media_player.play_media
    data_template:
      entity_id: 'media_player.john_s_speaker{% if is_state("input_boolean.kitchen_enabled", "on") -%} , media_player.kitchen_speaker{%- else -%}{%- endif %}''
      media_content_id: http://url.com/audio.mp3
      media_content_type: audio/mp3

Thank you!

I assume what you want is to use John’s speaker if the input_boolean is on otherwise use the kitchen speaker.

  action:
  - service: media_player.play_media
    data_template:
      entity_id: "media_player.{{'john_s_speaker' if is_state('input_boolean.kitchen_enabled', 'on') else 'kitchen_speaker' }}"
      media_content_id: http://url.com/audio.mp3
      media_content_type: audio/mp3

If the input_boolean is the automation’s trigger then the template can be this:

      entity_id: "media_player.{{'john_s_speaker' if trigger.to_state.state == 'on' else 'kitchen_speaker' }}"

Thanks 123.

Basically, my plan is to add multiple speakers (with corresponding booleans that act as the speaker’s toggle to enable/disable them). media_player.john_s_speaker will always play.

However, the other speakers (e.g. kitchen, bedroom etc) should only play if their boolean toggle is enabled.

Is it possible to format the template such that it APPENDS the additional speakers to entity_id: ?

In other words something like this,

entity_id: media_player.john_s_speaker, [ + media_player.kitchen_speaker - if boolean enabled], [+ media_player.bathroom_speaker - if boolean enabled] etc

Any help would be most appreciated in helping to achieve this. Thank you!

This always sets John’s speaker as the default speaker and then checks each input_boolean to determine if it should append another speaker.

  action:
  - service: media_player.play_media
    data_template:
      entity_id: >-
        {% set x = 'media_player.john_s_speaker' %}
        {% if states('input_boolean.kitchen') == 'on' %}
        {% set x = x~', media_player.kitchen_speaker' %}
        {% elif states('input_boolean.bathroom') == 'on' %}
        {% set x = x~', media_player.bathroom_speaker' %}
        {% elif states('input_boolean.hallway') == 'on' %}
        {% set x = x~', media_player.hallway_speaker' %}
        {% endif %}
        {{ x }}
      media_content_id: http://url.com/audio.mp3
      media_content_type: audio/mp3

If you have far more than 3 or 4 speakers then it may be more efficient to use a for-loop with a dictionary (listing all the input_booleans with matching speaker names). Otherwise, the method I’ve shown is simple but effective.


EDIT
Added missing entity_id:

2 Likes

You’re missing the entity_id field. Also, I seem to recall that the entity_id field inside a data_template does not accept comma separated lists, it only accepts the ‘-{{}}\n’ templated lists. I never tested it myself but I remember walking someone through this exact type of template and it never worked. That could be because the user I was helping wasn’t templating it correctly though.

Ouch! Glaring omission on my part. Thanks!

I’ll give this a spin and see if a comma-separated list, produced by a data_template, is accepted by entity_id.


EDIT

Tested this simple automation and confirmed it works.

- alias: 'test CSV list'
  trigger:
  - platform: state
    entity_id: input_boolean.toggler
  action:
  - service: light.toggle
    data_template:
      entity_id: >-
        {% set x = 'light.family' %}
        {% set x = x~', light.kitchen' %}
        {% set x = x~', light.mantle' %}
        {% set x = x~', light.hallway' %}
        {{ x }}
1 Like

Wow, impressive thank you so much 123!

I just tested this out and noticed that only the first 2 speakers play. (From our example, it is John’s speaker and the Kitchen Speaker). The bottom 2 speakers do not play for some reason.

I swapped the speaker names round and can confirm it’s only the first 2.

Any ideas what may be the issue? :thinking:

Please post the entire automation so I can examine it.

Sure, here it is (audio url has been replaced for privacy reasons).
Thanks!

- id: '1013100'
  alias: Play Adhan
  trigger:
  - entity_id: input_boolean.adhan
    from: 'off'
    platform: state
    to: 'on'
  condition: []
  action:
  - service: media_player.play_media
    data_template:
      entity_id: >-
        {% set x = 'media_player.hanif_s_speaker' %}
        {% if states('input_boolean.mum_enabled') == 'on' %}
        {% set x = x~', media_player.mums_speaker' %}
        {% elif states('input_boolean.kitchen_enabled') == 'on' %}
        {% set x = x~', media_player.kitchen_speaker' %}
        {% elif states('input_boolean.jane_enabled') == 'on' %}
        {% set x = x~', media_player.jane_s_speaker' %}
        {% endif %}
        {{ x }}
      media_content_id: https://susam.in/files/music/twinkle-twinkle-little-star/twinkle-twinkle-little-star.mp3
      media_content_type: audio/mp3

Everything looks like it should work. I suggest you try this:

Set all 3 of these input_booleans to on:

input_boolean.mum_enabled
input_boolean.kitchen_enabled
input_boolean.jane_enabled

Now paste the entire template into Home Assistant’s Template Editor:

        {% set x = 'media_player.hanif_s_speaker' %}
        {% if states('input_boolean.mum_enabled') == 'on' %}
        {% set x = x~', media_player.mums_speaker' %}
        {% elif states('input_boolean.kitchen_enabled') == 'on' %}
        {% set x = x~', media_player.kitchen_speaker' %}
        {% elif states('input_boolean.jane_enabled') == 'on' %}
        {% set x = x~', media_player.jane_s_speaker' %}
        {% endif %}
        {{ x }}

It should produce this (ensure all commas are present):

media_player.hanif_s_speaker, media_player.mums_speaker, media_player.kitchen_speaker, media_player.jane_s_speaker

If it does but only the first two speakers play, then the problem lies elsewhere (it’s not related to the template).

(… or the names of the input_booleans or media_players shown in the template do not match the ones you defined in the configuration file.)

this could be helpful, I use a little script in the automations to do just what you want.

script:
  say_next_alarm:
    alias: Say next alarm
    sequence:
      - service: tts.google_say
        data_template:
          language: >
            {{states('input_select.intercom_language')|lower}}
          entity_id:
            - >
              {{states('sensor.intercom')}}
            - >
              {{states('sensor.sleep_radio')}}
          message: >
            {{states('sensor.next_alarm_text')}}

in this particular script, I use 2 templates on the entity_id, but in your case simply replace the first with your always-on player.

Thanks, just tested it out in the Template Editor.

It’s only showing:

 media_player.hanif_s_speaker, media_player.mums_speaker 

with all booleans enabled.


If I set input_boolean.mum_enabled to: off (but keep all the other booleans on) this is the output:

media_player.hanif_s_speaker, media_player.kitchen_speaker

If I set both input_boolean.mum_enabled and input_boolean.kitchen_enabled to off (leaving only input_boolean.jane_enabled as on, this is the output:

media_player.hanif_s_speaker, media_player.jane_s_speaker

From this, I can only assume that there is some sort of character limit that is truncating the rest from showing maybe?

Checked many times to ensure that’s not the case :stuck_out_tongue:

It’s not a character limit issue. With all four speakers it’s only ~115 characters long.

My mistake! It’s a logic error in the template!

I need a few moments to sort it out …


Replace the existing template with this one:

        {% set x = 'media_player.hanif_s_speaker' %}
        {% if states('input_boolean.mum_enabled') == 'on' %}
        {% set x = x~', media_player.mums_speaker' %}{% endif %}
        {% if states('input_boolean.kitchen_enabled') == 'on' %}
        {% set x = x~', media_player.kitchen_speaker' %}{% endif %}
        {% if states('input_boolean.jane_enabled') == 'on' %}
        {% set x = x~', media_player.jane_s_speaker' %}{% endif %}
        {{ x }}
1 Like

It’s working! :ok_hand:

Thank you SO much for helping me out with this. Now I’ve got switches for each speaker thanks to you :smiley:

1 Like

You’re welcome! Glad to hear it now works correctly for you.

nice!
since I own a couple of extra media-players, I was thinking of a way to create a group dynamically with all the ‘on’ players, and have that in a template, so I could use the group in the entity_id.

Would that be possible?

I have 1 player always on, have a ‘broadcast’ group with all players, and this would be a 3d group, with selected players, made dynamically. Could be done in python I guess, but maybe we don’t need that?

1 Like

I’m guessing the guy I helped did it wrong then. I always thought it worked but I gave up on the guy when he claimed it didn’t. He must have had a typo. Oh well.

1 Like

Truly one of the more challenging aspects of assisting others is to second-guess the reported results in the event the suggestion was applied incorrectly. So not only predict the expected correct but also incorrect outcomes and what may have caused them. Add the fact I’m prone to making erroneous suggestions (case in point: in this very thread) and it all leads to a long session of head-scratching and confusion. Which is why it’s always helpful to have a fresh pairs of eyes available.

I’m reminded of a cartoon from my childhood where the character misreads a giant sign above a building. The first word is “Brain” but the character refers to it as “rain”. When informed of the error, he replies “The ‘B’ was so big that I didn’t see it!” :slight_smile:

2 Likes

That was my original plan and it would make the code so much cleaner and easier to maintain that way. Quite refreshing knowing there’s others out there with similar needs and (think alike) :slight_smile:

Hopefully someone could shed some light on this in the near future as to whether this is easy to achieve…

Neat a.F!
But for documentation purposes
How would you go on this for-loop?