Volume for media_player

I’m trying to create a volume sensor that will convert the volume_level on a media player to the volume shown on the front of my receiver. Receiver is in db, volume slider seems to be a float between 0-1. After I do this, i’m going to create an alexa voice command to set the volume to a specific decibel. My problem is, I’m having trouble trying to create this sensor. I understand the sensor is unnecessary in the long run, but i’d like to map the min max and increment before i create the alexa Intents.

Here is the code I’ve tried when creating a template sensor:

  # zone1_volume:
    # entity_id: media_player.yamaha_receiver
    # value_template: {{ states.attributes.volume_level }}
    # friendly_name: Reciever Volume Level

which returns an error regarding states.attributes.volume_level not being a valid key in the dictionary. I’ve also tried:

  # zone1_volume:
    # value_template: {{ states.media_player.yamaha_receiver.attributes.volume_level }}
    # friendly_name: Reciever Volume Level

This returns the same error.

So my question is 2 fold

What am i doing wrong?

and

Is there an easy way to see the structure of the objects? This has been a thorn in my side from the beginning.

1 Like

example of the error in both attempts:

17-02-07 12:57:09 ERROR (Thread-1) [homeassistant.util.yaml] invalid key: “OrderedDict([(‘states.media_player.yamaha_receiver.attributes.volume_level’, None)])”
in “/home/homeassistant/.homeassistant/sensor.yaml”, line 25, column 0

Not having a yamaha with WIFI, I can only test your template with what I have and your second example template works in the template tester for everything I have THAT’S ON. The media players registered, but off give no values.

When you look at the media player’s detail in the dev states panel, is the attribute for volume level there and named the same?

Yes. Whats odd is that I can control everything I want to do. I’ve already begun making my alexa skills. I’d still like to have a sensor that has the actual decibel level though. Anyways, here is what is listed for the media_player.

media_player.yamaha_receiver	on	      friendly_name: Yamaha Receiver
                                        is_volume_muted: false
                                                 source: PC
                                            source_list: AirPlay,Apple TV,Echo,NET RADIO,PC,Phone,Playstation 4,SERVER,TUNER,Wii U,Xbox One,iPod (USB)
                               supported_media_commands: 18828
                                           volume_level: 0.7

Well, the attribute is certainly there and spelled the same.

When you put the template by itself

{{ states.media_player.yamaha_receiver.attributes.volume_level }}

in the template tester in the dev panel, do you get 0.7 as a value? If not, maybe you need a float.

This works for me:

- platform: template
  sensors:
    denon_volume:
      value_template: >
        {% if is_state('media_player.denon_livingroom', 'on')  %}
          {{ states.media_player.denon_livingroom.attributes.volume_level }}
        {% else %}
          0
        {% endif %}

sensor.denon_volume has value of attribute volume level if the receiver is on, or 0 if the receiver is off.

This was just a quick test, still working on further automations for setting sliders and so on, but this works flawlessly.

3 Likes

That’s a nice solution! Also, this prevents getting the dreaded “Attribute None” errors when the template sensor gets rendered before the sensor you’re pulling the attribute from initializes. Something I could see happening in this case.

Nice one!

This worked for me. It’s odd how I was getting key errors on the dictionary because the device has been on the whole time. Maybe for a split second during start up the state of the object is off and it causes the error.

Automations so far, this has to change a lot because this is a short loop :stuck_out_tongue:, but just to show how they work here:

- alias: Set Denon volume slider
  hide_entity: True
  trigger:
    platform: state
    entity_id: sensor.denon_volume
  action:
     service: input_slider.select_value
     data_template:
      entity_id: input_slider.denon_volume
      value: "{{ states ('sensor.denon_volume') | float }}"

- alias: Set Denon receiver volume
  hide_entity: True
  trigger:
    platform: state
    entity_id: input_slider.denon_volume
  action:
    - service: media_player.volume_set
      data_template:
        entity_id: media_player.denon_livingroom
        volume_level: '{{ states.input_slider.denon_volume.state | float }}'

Also need some kind of conversion for the values to the dB values shown on the receiver. Don’t know how to do that yet. :expressionless:

This is what I ended up using. Its a conversion to DB and formatted nicely for the UI.

  zone1_volume:
    value_template: >
      {% if is_state('media_player.yamaha_receiver', 'on')  %}
        {% set n = states.media_player.yamaha_receiver.attributes.volume_level|float %}
        {{ '%.1f'%( (-1.0+n)*100.0|round(0.0) ) }}
      {% else %}
        "-80.0"
      {% endif %}
    friendly_name: Reciever Volume Level
    unit_of_measurement: "DB"
5 Likes

hey @petro thanks heaps for this chunk of code. I’ve just discovered home assistant and am trying to setup a bunch of stuff for google assistant.

I’ve got the correct volume appearing in the overview (thanks again) but how are you getting the volume set to a specific dB level via alexa? Do you have config in home assistant to convert the dB number back to a yamaha friendly number or is it all happening on the alexa side?

Cheers

1 Like

I have a Home Assistant bridge setup as an app in alexa and I use the following intents:

  SetVolumeIntent:
    action:
      service: media_player.volume_set
      data_template:
        entity_id: media_player.yamaha_receiver
        volume_level: >-
          {%- if Level|int in range(10,81) -%}
            {%- set n = Level|float -%}
            {{ (1.0-( n / 100.0 )) | round(2) }}
          {%- endif -%}
    speech:
      type: plain
      text: OK

  VolumeUpIntent:
    action:
      service: media_player.volume_set
      data_template:
        entity_id: media_player.yamaha_receiver
        volume_level: >
          {% if is_state('media_player.yamaha_receiver', 'on')  %}
            {% set n = states.media_player.yamaha_receiver.attributes.volume_level | float %}
            {% if n <= 0.85 %}
              {{ n + 0.05 | round(2) }}
            {% endif %}
          {% endif %}
    speech:
      type: plain
      text: OK
      
  VolumeDownIntent:
    action:
      service: media_player.volume_set
      data_template:
        entity_id: media_player.yamaha_receiver
        volume_level: >
          {% if is_state('media_player.yamaha_receiver', 'on')  %}
            {% set n = states.media_player.yamaha_receiver.attributes.volume_level | float %}
            {% if n >= 0.25 %}
              {{ n - 0.05 | round(2) }}
            {% endif %}
          {% endif %}
    speech:
      type: plain
      text: OK
      
  VolumeMuteIntent:
    action:
      service: media_player.volume_mute
      data_template:
        entity_id: media_player.yamaha_receiver
        is_volume_muted: >
          {% if is_state('media_player.yamaha_receiver', 'on')  %}
            {% if DoWhat.lower() in ['mute'] %}
              true
            {% elif DoWhat.lower() in ['unmute'] %}
              false
            {% else %}
              false
            {% endif %}
          {% else %}
            false
          {% endif %}
    speech:
      type: plain
      text: OK
3 Likes

Dear,
can you guide me to make my slider work,
i am using broadlink as me ir blaster.
Please guide