History of listening time to music

I’m trying to implement a history graph, that tells me for how long I listened to music
this year (in my case: how long spotify is in “playing” state).

To do this I wrote the following sensor in my config yaml:

- platform: history_stats
  name: Time playing Spotify (this year only)
  unique_id: xxx
  entity_id: media_player.spotify_xxx
  state: "playing"
  type: time
  start: '{{ as_timestamp( now().replace(hour=0).replace(minute=0).replace(second=0) ) - now().year }}'
  end: '{{ now() }}'

My problem with this code is, that it resets quite randomly at midnight to 0.

Does anyone have a solution to this or could me provide some help?

Your start template doesn’t make sense… it essentially says “Start counting at 33.7 minutes before midnight.”

But the long term problem is that History Stats is limited to the amount of time the Recorder holds history. This defaults to 10 days. For a year-long value you need to aggregate the value from the History stats to another sensor like a Utility Meter or properly configured trigger-based template sensor.

So it would run into calculation problems when the 10 day quota is reached?

Do you have a usable template sensor template?
Because the Utility Meter does not support media_player or binary_sensor entities, at least I can’t figure out how.

IIRC, at the start of every day after the 10th day the oldest day’s hours are subtracted from the running total. So on Day 11, Day 1’s hours are subtracted… and so on. Instead of the value going up continuously your graph shows a saw tooth line.

In both cases you would set the History stats to collect the hours/day, then the Utility Meter aggregates that number value.

History Stats:

- platform: history_stats
  name: Time Playing Spotify Daily
  unique_id: xxx
  entity_id: media_player.spotify_xxx
  state: "playing"
  type: time
  start: '{{ today_at() }}'
  end: '{{ now() }}'

The trigger-based template sensor would look something like the following, but I would recommend using a Utility Meter. The one benefit of the template sensor is that you could add a custom event trigger so that you can capture the values you have collected since the first.

template:
  - trigger:
      - platform: state
        entity_id: sensor.time_playing_spotify_daily
        to:
          - 0
          - 0.0
      - platform: template
        value_template:  "{{ now().month == 1 }}"
        id: reset
    sensor:
      - name: Yearly Spotify Listening
        state_class: measurement
        unit_of_measurement: hours
        state: |  
          {% set current = this.state | float(0) if this is defined and this.state is defined else 0 %}
          {% if trigger.id == 'reset' %}
          0
          {% else %} {{ current + trigger.from_state.state | float(0) }}
          {% endif %}

Thank you soo much!

One final question:
I already have a sensor that collects the weekly time.
Can I also use this one for the Utility Meter, instead of having two History Stats sensor?

- platform: history_stats
  name: Time playing Spotify (this week only)
  unique_id: xxx
  entity_id: media_player.spotify_xxx
  state: "playing"
  type: time
  start: '{{ as_timestamp( now().replace(hour=0).replace(minute=0).replace(second=0) ) - now().weekday() * 86400 }}'
  end: '{{ now() }}'

Otherwise the daily one is okay to have it too.

I’ve never tried doing it that way, but I think it should work.

1 Like

Okay to make it easier in the future I also reconfigured my weekly stats to the Utility Meter with the daily History Stats measurement.

That is way less complicated code to handle with.