Yamaha receivers (and probably others these days) don’t use 1-10 or 1-100 for volume. Instead, they use a range displayed in dB (max depends on the receiver and the zone) that can be a positive or negative value.
The media_player integration is able to interface with them, and control things like power, source, and volume - sort of. The max value for the media_player integration for volume is 1. This works fine if the scale is 1-10 or 1-100, just do whatever math is necessary. However, for the Yamaha receivers, this max value equates to 0.0dB - which means you can never adjust the volume to the “positive” side of the equation. On my RX-V681, for example, the main zone goes to +16.5dB. Since dB is logarithmic, that’s a pretty considerable amount of volume left on the table. I don’t often use settings that high, but it annoyed me that it wasn’t possible. So, I set about to make it possible. The results are below.
First, create a file in /config/scripts called yamahavolume.sh. Paste this code into it:
#!/bin/sh
curl_cmd="curl --silent --output /dev/null"
volume() {
${curl_cmd} http://${1}/YamahaRemoteControl/ctrl --data-binary "'<YAMAHA_AV cmd=\"PUT\"><${2}><Volume><Lvl><Val>${3}</Val><Exp>1</Exp><Unit>dB</Unit></Lvl></Volume></${2}></YAMAHA_AV>'"
}
"$@"
Then, add the following lines to your configuration.yaml:
shell_command:
yamaha_vol: /bin/bash /config/scripts/yamahavolume.sh volume {{ ip }} {{ zone }} {{ vol }}
You’ll also need to define an input slider in your configuration.yaml: (note that the max should be adjusted to match the zone. On my RX-V681, Main_Zone has a max of +16.5, while Zone_2 has a max of +10)
input_number:
main_volume:
icon: mdi:volume-medium
name: Volume
initial: -35
min: -80
max: 16.5
step: 1
mode: slider
Then, in your automations.yaml: (make sure the “- id” is unique, and enter the IP for your receiver. possible zones values are Main_Zone or Zone_2)
- id: '1111111111112'
alias: Main Volume Set
description: ''
trigger:
- platform: state
entity_id: input_number.main_volume
condition: []
action:
- service: shell_command.yamaha_vol
data:
ip: IP.OF.YOUR.RECEIVER
zone: Main_Zone
vol: '{{ (trigger.to_state.state) | int * 10 }}
'
mode: single
Then simply add a custom:slider-entity-row (from HACS) to an entities card in your front end and bob’s your uncle!
- type: entities
entities:
- type: section
label: Volume dB
- type: custom:slider-entity-row
entity: input_number.main_volume
full_row: true
This has been confirmed to work with my RX-V681 which is OLD, and also with my TSR-700, which is the Costco version of the RX-V6A, and is less than a year old. I suspect it will also work with anything in between there, but have no way of verifying.