Media_player.template

Hi everyone,

I’m using the very nice App ControllerX (ControllerX. Bring full functionality to light and media player controllers) to control the volume of the current playing media player.

But a problem one of my media players (an old Harman Kardon) doesn’t have any way to control it but with IR-remote. So I setup an IR-sender with esphome but problem ControllerX expects a media_player entity so it can use the services set_volume(or in the dev version volume_up/down).

After searching I didn’t found a way to create my own media_player entity like you do with switches and lights (templating) So I started to create my own custom_component


At this moment it doesn’t have all the actions that a normal media_player has but it’s usable.

There’s one downside: to use this component you need to override all the template entities!
(if this is wrong please correct me)

How to install:

  1. Create a ‘custom_components’ folder in your config folder(if it doesn’t exist)
  2. Create ‘template’ folder in the custom_components folder
  3. Copy all the file from https://github.com/home-assistant/core/tree/dev/homeassistant/components/template to this folder (I read that this is needed otherwise the component isn’t overriden)
  4. Copy my media_player.py to this folder
  5. Create your config like following example:
media_player:
  - platform: template
    media_players:
      receiver:
        friendly_name: Receiver
        current_source_template: "{{ states('input_text.selected_source') }}"
        value_template: >
          {% if is_state("input_boolean.receiver_on", "on") -%}
            on
          {%- else -%}
            off
          {%- endif %}
        turn_on:
          service: switch.turn_on
          data_template:
            entity_id: switch.receiver_on
        turn_off:
          service: switch.turn_on
          data_template:
            entity_id: switch.receiver_off
        volume_up:
          service: switch.turn_on
          data_template:
            entity_id: switch.volume_up
        volume_down:
          service: switch.turn_on
          data_template:
            entity_id: switch.vol
        input_templates:
          source 1:
            service: input_boolean.turn_on
            data_template:
              entity_id: input_boolean.source_1
          source 2:
            service: input_boolean.turn_on
            data_template:
              entity_id: input_boolean.source_2

Hope someone finds this usefull and if there’s anything wrong create a issue!

10 Likes

After searching I didn’t found a way to create my own media_player entity like you do with switches and lights (templating)

But there is the universal media player?

True but this needs existing media players (children) and you can control these children using switches. This component creates a media player from scratch.

2 Likes

Just making sure your efforts are worth it :+1:

@Sennevds
Maybe it’s better to pick a dedicated platform-name instead of template, that way you wouldn’t need to copy all files from original HA template components. Eventually like this project: https://github.com/custom-components/media_player.braviatv_psk

1 Like

Good idea. Still don’t get it why you should copy everything if you only want to override one file or add a file but maybe I should change it.

Can anyone please share config for implementing Harmony Hub receiver (I have Logitech Z5500) to this component.
I was experimenting but can not get around it to get it working.

I can control it through script but It would be much nicer to control it with media player which I can also port to HomeKit.

z5500_volume_up:
  alias: Z-5500 Volume Up
  sequence:
    service: remote.send_command
    data:
      entity_id: remote.living_room
      command:
        - VolumeUp
      device: 59435264

Thanks!

@mathew007 you could try something like this

media_player:
  - platform: media_player_template
    media_players:
      receiver:
        friendly_name: Receiver
        volume_up:
          service: remote.send_command
          data:
            entity_id: remote.living_room
            command:
              - VolumeUp
            device: 59435264
        volume_down:
          service: remote.send_command
          data:
            entity_id: remote.living_room
            command:
              - VolumeDown
            device: 59435264

Thanks for quick reply.
I’ve tried your suggestion but I get this error:

Invalid config for [media_player.media_player_template]: required key not provided @ data['media_players']['receiver']['turn_off']. Got None required key not provided @ data['media_players']['receiver']['turn_on']. Got None required key not provided @ data['media_players']['receiver']['value_template']. Got None. (See /config/configuration.yaml, line 147). Please check the docs at https://github.com/Sennevds/media_player.template

You need to have the turn_on and turn_off parameters.
You also need a value_template but if you don’t have a way to know if the receiver is on or off you could have a template that returns on

Thanks!
Now I am getting closer :slight_smile:

media_player:
  - platform: media_player_template
    media_players:
      receiver:
        friendly_name: Receiver
        value_template: >
          {% if is_state_attr('remote.living_room', 'current_activity', 'Listen to Music') -%}
            on
          {%- else -%}
            off
          {%- endif %}
        turn_on:
          service: remote.turn_on
          data:
            entity_id: remote.living_room
            activity: 'Listen to Music'
        turn_off:
          service: remote.turn_on
          data:
            entity_id: remote.living_room
            activity: 'PowerOff'
        volume_up:
          service: remote.send_command
          data:
            entity_id: remote.living_room
            command:
              - VolumeUp
            device: 59435264
        volume_down:
          service: remote.send_command
          data:
            entity_id: remote.living_room
            command:
              - VolumeDown
            device: 59435264
        mute:
          service: remote.send_command
          data:
            entity_id: remote.living_room
            command:
              - Mute
            device: 59435264

On media card there is only power button without volume buttons. For them to show up I have to click on more options. Is there a way for these buttons to show on the card?

use this one instead of the build in https://github.com/kalkih/mini-media-player

1 Like

Hello,
This looks to be just what I need.
However I am getting the error:

2020-09-27 15:34:33 ERROR (MainThread) [homeassistant.components.media_player] Error while setting up media_player_template platform for media_player
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.7/site-packages/homeassistant/helpers/entity_platform.py", line 193, in _async_setup_platform
    await asyncio.shield(task)
  File "/home/homeassistant/.homeassistant/custom_components/media_player_template/media_player.py", line 150, in async_setup_platform
    input_templates,
  File "/home/homeassistant/.homeassistant/custom_components/media_player_template/media_player.py", line 189, in __init__
    self._on_script = Script(hass, on_action)
TypeError: __init__() missing 2 required positional arguments: 'name' and 'domain'

I am using HomeAssistant 0.115.4.
Which version have you tired with?

It is definitely calling you code, and I’ve resolved errors in the config.

Any suggestions?

Hmm something must have changed in version 0.115. I have the same problem now. I will check it out!

I’ve updated the repo with a fix. Could you try it?
There’s another problem they have deprecated template.extract_entities and now I have to use event.async_track_template_result but need to find out how this works. If someone wants to help always welcome to create pull requests!

I still got the error for source selection. You forgot to add the fix here:

2020-09-28 16:56:27 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection.139878495489808] name 'friendly_name' is not defined
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 137, in handle_call_service
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 1315, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1350, in _execute_service
    await handler.func(service_call)
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 204, in handle_service
    await self.hass.helpers.service.entity_service_call(
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 459, in entity_service_call
    future.result()  # pop exception if have
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 655, in async_request_call
    await coro
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 490, in _handle_entity_call
    await result
  File "/usr/src/homeassistant/homeassistant/components/media_player/__init__.py", line 615, in async_select_source
    await self.hass.async_add_job(self.select_source, source)
  File "/config/custom_components/media_player_template/media_player.py", line 380, in select_source
    source_script = Script(self.hass, self._input_templates[source], friendly_name, domain)
NameError: name 'friendly_name' is not defined

Could you try again I’ve updated the repo

You forgot self.xxx for the other Script

Thank you, this fix is working for me in Hass 0.115.4

HI!

First of all thank you for this! I can finally create custom media players.

I’ve starting doing the first tentative and it’s working great. The are few things that doesn’t work:

  • play
  • pause
  • artist name
  • cover

Moreover I don’t understand why buttons are not exposed as in other normal lovelace media cards.

image

Below my config ( I use a denon AVR managed by Harmony + a chromecast audio)

  - platform: media_player_template
    media_players:
      denon:
        friendly_name: Denon
        value_template: >
          {% if is_state_attr("remote.soggiorno", "current_activity", "Ascolta Spotify") -%}
            on
          {%- else -%}
            off
          {%- endif %}
        turn_on:
          service: remote.turn_on
          entity_id: remote.soggiorno
          data:
            activity: 'Ascolta Spotify'
        turn_off:
          service: remote.turn_on
          data:
            entity_id: remote.soggiorno
            activity: 'PowerOff'
        volume_up:
          service: remote.send_command
          data:
            entity_id: remote.soggiorno
            command:
                - VolumeUp
            device: 45938921
        volume_down:
          service: remote.send_command
          data:
            entity_id: remote.soggiorno
            command:
                - VolumeDown
            device: 45938921
        play:
          service: media_player.media_play
          data:
            entity_id: media_player.soggiorno
        pause:
          service: media_player.media_pause
          data:
            entity_id: media_player.soggiorno
        next:
          service: media_player.media_next_track
          data:
            entity_id: media_player.soggiorno
        previous:
          service: media_player.media_previous_track
          data:
            entity_id: media_player.soggiorno
        mute:
          service: remote.send_command
          data:
            entity_id: remote.soggiorno
            command:
                - Mute
            device: 45938921
        title_template: "{{ state_attr('media_player.soggiorno', 'media_title') }}"
        album_template: "{{ state_attr('media_player.soggiorno', 'media_album_name') }}"
        artist_template: "{{ state_attr('media_player.soggiorno', 'media_artist') }}"

Any hint?