Volume transition feature for media_player

I’ve implemented a volume_transition service for the media_player platform, that, as the name suggests, provides a service to transition to a given volume level over a given duration. This makes for a nice and easy to use feature in an alarm clock, by slowly fading in music in the morning.
Here’s my branch on github.
I declared the service in the media_player __init__.py and implemented the specific transition method(s) in mpd.py. The transition works as follows. We are given the desired duration and volume level and compute the interval after which we would change the volume by 1%. If the interval is smaller than a given lower bound, we take the lower bound instead to avoid excessive calling of set_volume. Then we create a threading.Timer that calls a helper function which sets the new volume and calls starts another Timer if the target volume hasn’t been reached yet.
Now this could easily be done completely in __init__.py, but the way I’m doing it is by having the Timer object as a class property, so I would need to declare that in the constructor, which is not defined in __init__.py, and have the platforms all call super().

What would be the right way to do this if I were to submit my code as a pull request? And would people be interested in this feature?

14 Likes

Yeah - I’d be interested. I use meda_player for my Yamaha amplifier (and others) - always quite a shock to the system when the amp jumps up 200% in volume!

Guessing this is not gonna happen :frowning:

Definetely I’m interested!

Interested in this too, perfect for my radio alarm.

1 Like

+1 interested in this feature. Must-have for morning alarm/radio. Why don’t you try submitting a PR?

EDIT: Looks like a PR was submitted but rejected with suggestion to create a custom component or script.

@petepriority Thanks for your work. Are you still using this as-is? If so, how? I’m trying to figure out how to make it work with the latest version of HASS. A git install of the commit every time you upgrade HASS? :thinking:

Some alternatives to achieve this:
Create a script that calls set volume with incremental volumes.
Create a custom component that calls the services for you
Add an optional transition parameter to async_set_volume_level. It is then up to the platforms to implement transition. They can choose to do this with a generic volume helper transition method. That way we leave the power to the platforms to create this the way they want it.

Here’s my workaround python script (based on another community member’s work on light fade in):

entity_id  = data.get('entity_id')
sleep_delay = int(data.get('delay_in_sec'))
start_level = float(data.get('start_level'))
end_level = float(data.get('end_level'))
step  = float(data.get('step_in_level'))

new_level = start_level
while new_level < end_level :
  states = hass.states.get(entity_id)
  current_level = states.attributes.get('volume_level') or 0
  if (current_level > new_level) :
    logger.info('Exiting Fade In')
    break;
  else :
    logger.info('Setting volume of ' + str(entity_id) + ' from ' + str(current_level) + ' to ' + str(new_level))
    data = { "entity_id" : entity_id, "volume_level" : new_level }
    hass.services.call('media_player', 'volume_set', data)
    new_level = new_level + step
    time.sleep(sleep_delay)
2 Likes