Triggering at the end of a playing track - accurately!

Hi there - I’m new-ish to this world - blown away by the quality of the work available and the power of the platform!

I’m trying to write a trigger that will fire precisely (<=1sec) at the end of any given playing music track. This is initially quite clumsy as there isn’t an end-time exposed by Media Player, but I’ve calculated it with this code:

  {{ (as_timestamp(now()) + state_attr('media_player.thybris', 'media_duration') - (state_attr('media_player.thybris', 'media_position') + as_timestamp(now()) - as_timestamp(state_attr('media_player.thybris', 'media_position_updated_at')))) | timestamp_custom('%H:%M:%S', true) }}

This, when viewed in Developer tools, gives me a great second-accurate timestamp. But where I struggle is the next step. I thought I’d set a helper with this value, using this automation:

alias: Set end of track helper value
description: ""
trigger: []
condition: []
action:
  - service: input_datetime.set_datetime
    metadata: {}
    data:
      time: >-
        {{ now.timestamp(as_timestamp(now()) +
        state_attr('media_player.thybris','media_duration') -
        (state_attr('media_player.thybris', 'media_position') +
        as_timestamp(now()) -
        as_timestamp(state_attr('media_player.thybris','media_position_updated_at'))))
        | timestamp_custom('%H:%M:%S', true) }}
    target:
      entity_id: input_datetime.end_of_current_track_time
mode: single

(for testing, there’s no automation trigger, I’m doing that manually)

Unfortunately this simply doesn’t work. The logs say:

Template variable error: ‘function object’ has no attribute ‘timestamp’ when rendering ‘{{ now.timestamp(as_timestamp(now()) + state_attr(‘media_player.thybris’,‘media_duration’) - (state_attr(‘media_player.thybris’, ‘media_position’) + as_timestamp(now()) - as_timestamp(state_attr(‘media_player.thybris’,‘media_position_updated_at’)))) | timestamp_custom(’%H:%M:%S’, true) }}’

This makes me wonder if I’m using template syntax where I shouldn’t be, perhaps? Can anyone help with what I’m doing wrong? Any and all help gratefully received!

Many thanks,

Kit

Use either a wait_template or wait_for_trigger to detect when the media_player’s state is no longer playing.

I use that technique to detect when a media_player has finished playing a musical tone before proceeding to make it play an announcement. I then use the same technique to detect when the media_player has finished playing the announcement so I can proceed to restore its original volume and grouping.

Thanks - I have one of those too! My concern was the error I was getting.

Happily I’ve now solved it - seems there was some kind of syntax error in the code, I can’t even remember what - it works fine now!

I can confirm that this is invalid:

now.timestamp(as_timestamp(now())

That’s what the error message is identifying.

‘function object’ has no attribute ‘timestamp’

It’s now() not now but that alone won’t fix it because it contains another mistake. Anyways, moot point now given that you have already fixed it.

1 Like

Thank you! One of those errors where I’d looked at it so many times I missed the obvious… thanks for your help!
I also realised that with no track playing it returns an error - this doesn’t matter as the function is only called when a track is playing - but I ought to tighten up my defaults anyway, so I’ll go RTM and improve those…

1 Like