Count media players with specific media_title information?

I would like to have a generic binary_sensor which tells me whether any of my media players has a specific string in its attribute media_title.

(My goal behind it)

I find advertisement breaks quite annoying. The purpose is to detect whether my favorite radio station plays advertisements right now because it puts a signal word into the media_title. Therefore, I might be able to automate something like lowering the volume or playing something different while advertisements are being broadcast.


I have defined the mediaplayer group media_player.mediaplayers which contains all my players. I would like to examine the whole group to make it generic in order to find the desired information.

The problem is that not all media players provide the media_title attribute all the time or are offline so I have to filter for it. Unfortunately, I do not get it going although I have spent hours of trying. The following example does not work but may illustrate what I would like to get:

binary_sensor:

- platform: template
  sensors:

    media_player_radiostation_plays_commercial:
      value_template: >
        {% set entities = state_attr('media_player.mediaplayers', 'entity_id') %}
        {% set advertisements = states.media_player | selectattr('entity_id', 'in', entities)
                                                    | selectattr('media_title', 'eq', 'SIGNALWORD')
                                                    | list
                                                    | length %}
        {{ advertisements >= 1 }}

Can someone point me in the right direction, please? Many thanks in advance!

Copy-paste the following template into the Template Editor and test it.

{{ expand(state_attr('media_player.mediaplayers', 'entity_id'))
   | selectattr('attributes.media_title', 'defined')
   | selectattr('attributes.media_title', 'search', 'SIGNALWORD')
   | list | length }}

Thank you for your response!

I have tested it. Whatever I put in there for SIGNALWORD the resulting value is always 0.

If I shorten your code to the first two lines

{{ expand(state_attr('media_player.mediaplayers', 'entity_id'))
   | selectattr('attributes.media_title', 'defined') }}

the Template editor throws an <generator object select_or_reject at 0x...> error. So I assume the subsequent filters do not work anyway. Is that correct?

No, that’s incorrect.

Post the information for one of your media_players that contains the signal word in its media_title attribute. It can be a screenshot of the media _player as displayed in Developer Tools > States.

Here you are:

source_list:
  - Line-in
group_members:
  - media_player.michael
volume_level: 0
is_volume_muted: false
media_content_id: >-
  aac://<MEDIA_URL>
media_content_type: music
media_title: '<RADIOTEXT>'
media_channel: <RADIOSTATIONNAME>
shuffle: false
repeat: 'off'
queue_position: 1
queue_size: 1
device_class: speaker
entity_picture: >-
  /api/media_player_proxy/media_player.michael?token=8744a17597834e264c77f00379a4bc7f008e16712ae495336c3e6e6af6c2be4e&cache=2065258da7dfdd64
friendly_name: Michael
supported_features: 981567

In fact I am looking for the word Werbung but this will occur only for a couple of minutes at the end of every hour. So I currently use the word SWR3 which will occur on a regular base between songs.

What is media_player.mediaplayers and what is the current value of its entity_id attribute?

Also, what is the result of the following template:

{{ states.media_player
   | selectattr('attributes.media_title', 'defined')
   | selectattr('attributes.media_title', 'search', 'SWR3')
   | list | length }}
1 Like

It is my group of media players which I have defined via UI.

It is an array of all media players within the group:

['media_player.bad', 'media_player.esszimmer', 'media_player.kodi', 'media_player.kueche', 'media_player.michael', 'media_player.schlafzimmer', 'media_player.tv', 'media_player.vorrat', 'media_player.vorrat_2']

Oh wow, it is 1 once the search term is being matched…! I guess you have found a solution!

Thanks a million, Tara @123!

1 Like

Try this version. It will report a list containing which media_player has the signal word.

{{ states.media_player
   | selectattr('attributes.media_title', 'defined')
   | selectattr('attributes.media_title', 'search', 'SWR3')
   | map(attribute='entity_id') | list }}

You’ll need that if your goal is to lower the volume of the media_player that’s playing an advertisement.

1 Like

Thank you very much for your bonus answer! Much appreciated.

For reference - this is my final solution which works perfectly:

binary_sensor:

- platform: template
  sensors:

	# returns True if <SIGNALWORD> is being broadcast on any media player
    media_player_radio_station_plays_advertisement_anywhere:
      friendly_name: 'Media Player: Radio station plays advertisement anywhere?'
      value_template: >
        {% set advertisements = states.media_player
								| selectattr('attributes.media_title', 'defined')
								| selectattr('attributes.media_title', 'search', '<SIGNALWORD>')
								| list | length %}
        {{ advertisements >= 1 }}

Thanks again to Taras @123 for your excellent support!

1 Like

For future reference, when creating new Template Sensors you should consider using modern format. The example you posted is a Template Binary Sensor in, what is now known as, legacy format.

Legacy format has not been deprecated but it will no longer receive enhancements. For future-proofing, it’s suggested to use modern format.

Here’s your Template Binary Sensor in modern format.

template:
  - binary_sensor:
      name: 'Media Player: Radio station plays advertisement anywhere'
      state: >
        {% set advertisements = states.media_player
          | selectattr('attributes.media_title', 'defined')
          | selectattr('attributes.media_title', 'search', '<SIGNALWORD>')
          | list | length %}
        {{ advertisements >= 1 }}

The main thing to keep in mind is that modern format Template Sensors have their own domain name called template. In other words, modern format Template Sensors, Template Binary Sensors, and Trigger-based Template (Binary) Sensors are configured under the template: key.

Reference: Template Sensor

1 Like

I was not aware of this. Thank you for the heads-up! I will continuously rewrite my sensors now.

Be advised that you are not obligated to convert your existing, legacy-based Template Sensors to modern format. It’s entirely optional.

If decide to convert them, be advised the conversion process must be done in a specific way otherwise you might lose the sensor’s history (if that’s important to you).

For more information, refer to the following post:

1 Like

Please note - I have a follow-up question:

Thank you!