My use case is as follows: I often listen (and fall asleep) to podcasts at night, and at least in my native Sweden, they have an annoying custom of ending with some sort of loud outro. So, I have added a template sensor to calculate what currently remains of the episode in seconds, to use that in an automation, where if the result is less than 90 seconds after 11PM in the evening, the media player is turned off.
My sensor looks like this (it’s rather clumsy, I imagine):
It takes the current media duration and subtracts the media position, as well as the time elapsed between the last update of the media position and now. Then, at the end of it all, I gathered that I couldn’t get it to update based on sensor.time just by adding the entity_id, so instead I added the sensor and a subtraction that nullifies the result of adding it in the first place.
Partly, I wanted to publish this as a suggestion/example for anyone looking to achieve the same thing, it works quite well now, but I also wanted to ask two things:
Is there any less clumsy way of achieving the same thing?
The sensor currently updates once a minute, with the update of sensor.date_time – what would be the easiest way to achieve a more precise timing, i.e. once every 10 seconds or so?
As of v0.117 you can use now() in templates and they will update every minute. So you no longer need to fall back on sensor.time to update the template.
This will trigger as soon as there is only 90 seconds left (or less if the sensor takes a bit to update) and if it is after 11pm it will pass the condition and you can turn off your media player in the actions.
Oh, cool, I hadn’t updated to 0.117 yet, thanks for the heads up!
However, unless I am somehow misinformed, media_position does not update continuously, only with other media_player state changes, so I would still need my code to continuously calculate the actual media position, right?
No worries, please let me know if it works. It’s all untested. I’ve never used the update entity service to update a media player. Hopefully it updates the media_position attribute.
I have a similar use case: in my case I need a sensor that updates with the time left of the currently active Apple TV. I defined it as follows, works like a charm:
- trigger:
- platform: time_pattern
seconds: "/1"
sensor:
- name: Time left in current player
device_class: duration
state_class: measurement
unit_of_measurement: s
state: >
{% set player = ['media_player.appletv_airplay', 'media_player.appletv_living_room'] | select('is_state', 'playing') | first %}
{% if player is defined %}
{{ state_attr(player, 'media_duration') - (state_attr(player, 'media_position') + as_timestamp(now()) - as_timestamp(state_attr(player, 'media_position_updated_at'))) }}
{% else %}
{{ 0 }}
{% endif %}
I’m sorry to bring up this old topic again. Unfortunately, it is the only one that follows a reasonable solution. Unfortunately, the last proposed solution (which works fine in itself, by the way) still has a major flaw. It only works reliably if no one makes any change after position_updatet_at. Sure, on play/pause in the music app (Sonos for me) the position is updated, but when an automation triggers a pause, it doesn’t.
In my situation, I have a button that triggers play/pause, which messes up the timestamp quite a bit. The timestamp keeps running because it was triggered by Homeassistant. If I then later want to query the position, only nonsense comes as an answer, because the whole time the media position has fictitiously continued to run.
Is there another way to update the media_position manually?
This is my current automation. As I said, works fine as long as both actions are not used in one song.
When the button is pressed once, the song is either paused or played (with a rewind of 0.5 seconds).
If the button is pressed twice, it first checks if the song has been playing for more than 10 seconds. If this is not the case, a rewind of 10 seconds is not possible. Therefore, the title jumps to position 0. However, if the title has already been running for longer than 10 seconds, it is rewound by 10 seconds.
hey there, reviving this as I am trying to calculate the time remaining from a video using the media card attributes that are used above. I’m not interested in any automation, more I would like to display the time remaining on an ink screen. I have tried messing with the various codes above (using my specific entity id’s), but do not seem to be able to get it to work. Would there be a way to adopt this a say a simple sensor that just displays the time remaining?