How to use area_name(trigger.device_id) to specify a media_player in automation

I am trying to build a voice-driven automation which will play music on a specified media player, but where the target media player is determined by the Area in which the voice assistant device is location. I’m using Atom Echo speakers for this purpose.
So for example, if I issue the command to the Atom Echo in the kitchen, the music will play on the media player in the kitchen.
The automation is currently able to play music to a specified (i.e. hard-coded) media player (i.e. in the study in the example below), but I’m struggling with the syntax to make the media_player if variable depending on area_name(trigger.device_id)

Can anyone provide any pointers?

Here is my existing automation, which plays music on my study media player and correctly notifies my phone of the area from which the command originated:

alias: Voice command to play track (device aware)
description: ""
triggers:
  - command:
      - play {track_name}
    trigger: conversation
conditions: []
actions:
  - action: script.music_search_first_match
    metadata: {}
    data:
      search_query: "{{ trigger.slots.track_name }}"
      match_type: first
      media_content_type: Tracks
      media_player: media_player.study_speaker_lms_castbridge
  - action: notify.mobile_app_ian_galaxy_s24_ultra
    metadata: {}
    data:
      message: "{{ area_name(trigger.device_id) }}"
mode: single

The most basic way would be to use area_entities() then select for results that match media_player:

  - action: script.music_search_first_match
    metadata: {}
    data:
      search_query: "{{ trigger.slots.track_name }}"
      match_type: first
      media_content_type: Tracks
      media_player: |
        {{ area_entities(area_id(trigger.device_id))
        | select('match', 'media_player.') | first }}

Unfortunately, that can give you the wrong player if you have Areas with multiple media_player entities, which is pretty common. So, a better option might be to add a label to any media player you want to use with this type of script then use that in the selection:

{{ area_entities(area_id(trigger.device_id))
| select('in', label_entities('Selected Media Players')) | first }}

That’s an interesting suggestion - I haven’t looked into labels before.

So I created a label called ‘Selected Media Players’, and applied it to two media players:

media_player.kitchen_display_lms_castbridge
media_player.bedroom

My automation now looks like this, but the media_player id is not being rendered. This is what the Trace shows:

params:
  domain: script
  service: music_search_first_match
  service_data:
    search_query: you only live once
    match_type: first
    media_content_type: Tracks
    media_player:
      '[object Object]': null

The value of area_id(trigger.device_id) is Bedroom

This is what the automation looks like:

alias: Voice command to play track (device aware)
description: ""
triggers:
  - command:
      - play {track_name}
    trigger: conversation
conditions: []
actions:
  - action: script.music_search_first_match
    metadata: {}
    data:
      search_query: "{{ trigger.slots.track_name }}"
      match_type: first
      media_content_type: Tracks
      media_player:
        {{ area_entities(area_id(trigger.device_id)))
        | select('in', label_entities('Selected Media Players')) | first }}
  - action: notify.mobile_app_ian_galaxy_s24_ultra
    metadata: {}
    data:
      message: "{{ area_name(trigger.device_id) }}"
mode: single

Could it be that the media_player name is case-sensitive? i.e. do I need to rename the “Bedroom” area as “bedroom”?

You are missing the multi-line quote indicator after media_player:… it should be media_player: |

Actually that was deliberate - if I include that I get this syntax error:

Message malformed: template value should be a string for dictionary value @ data['actions'][0]['data']

???

alias: Voice command to play track (device aware)
description: ""
triggers:
  - command:
      - play {track_name}
    trigger: conversation
conditions: []
actions:
  - action: script.music_search_first_match
    continue_on_error: true
    metadata: {}
    data:
      search_query: "{{ trigger.slots.track_name }}"
      match_type: first
      media_content_type: Tracks
      media_player: |
        {{ area_entities(area_id(trigger.device_id)))
        | select('in', label_entities('Selected Media Players')) | first }}
  - action: notify.mobile_app_ian_galaxy_s24_ultra
    continue_on_error: true
    metadata: {}
    data:
      message: "{{ area_name(trigger.device_id) }}"
mode: single

It looks like I left in an extraneous ) on the first line of the template… :man_facepalming:

The action should be as follows:

  - action: script.music_search_first_match
    continue_on_error: true
    metadata: {}
    data:
      search_query: "{{ trigger.slots.track_name }}"
      match_type: first
      media_content_type: Tracks
      media_player: |
        {{ area_entities(area_id(trigger.device_id))
        | select('in', label_entities('Selected Media Players')) | first }}

Ah sorry I should have spotted that.
Many thanks - this seems to work perfectly!

Hi, please take the time to mark the post with the solution as the answer, you do that by selecting the three dots under the post:

image

Then select the check box:

image
By doing so:

  • this thread can be useful to other users as well (this thread comes up as solution when starting a thread which is similar to yours).
  • this prevents that someone else steps in trying to help

Thanks for giving back to the community! :+1: