Average Between Sensor Dates

I have searched all over but can’t find exactly what I am looking for here. I have an input helper for a single date. Let’s call it lastDate. So input_datetime.lastDate. I manually update this field. I would like to have another sensor that is the average time between the date values. For example, if the current value is 3/21/24 and the previous value was 3/19/24 and before that 3/15/24. I would want the AverageLength sensor to have the value of 3. Every time a new value is set for lastDate. I would want the average length to update. For example, if the next value is 3/30/24, then the new AverageLength would be 7.

I have tried several things but everything is either based on the date of the value change or is not an available statistic. Any help would be appreciated!

I think you’re going to need to break it into two parts. First, log the date difference, then get the average of logged values.

template:
  - trigger:
        - platform: state
          entity_id: input_datetime.lastdate
          not_from:
            - unknown
            - unavailable
          for: "00:01:00"
    sensor:
       - name: Last Date Difference
         unit_of_measurement: days
         state_class: measurement
         state: "{{ (trigger.to_state.state | as_datetime - trigger.from_state.state | as_datetime).days }}"

You can do this all in a single template sensor, but first you have to clarify what math you want to use.

Here’s a comparison of different options

Date Difference from Last Running Average Avg of New + Prev
3/15 N/A N/A N/A
3/19 4 (4)/1 = 4 4
3/21 2 (4+2)/2 = 3 (4+2)/2 = 3
3/30 9 (4+2+9)/3 = 5 (9+3)/2 = 6
3/31 1 (4+2+9+1)/4 = 4 (1+6)/2 = 3.5

If you want a true running average, you could do this:

template:
  - trigger:
      - platform: state
        entity_id: input_datetime.lastdate
        not_from:
          - unknown
          - unavailable
    sensor:
      - name: Last Date Running Average Difference
        unit_of_measurement: days
        state_class: measurement
        state: >
          {% set diff = (trigger.to_state.state | as_datetime - trigger.from_state.state | as_datetime).days %}
          {% set weight = this.attributes.weight | default(0) %}
          {% set old_state = this.state | float(0) %}
          {{ (old_state * weight + diff) / (weight + 1) }}
        attributes:
          weight: "{{ this.attributes.weight | default(0) + 1 }}"