History stats - ValueError: day is out of range for month

I have several history_stats sensors that I’m using to track my irrigation usage in order to calculate the cost of irrigating. Everything has been working great until today, they all went unavailable and I’m getting an error in my logs

Log error

Logger: homeassistant.components.history_stats.coordinator
Source: helpers/update_coordinator.py:223
Integration: history_stats ([documentation](https://www.home-assistant.io/integrations/history_stats), [issues](https://github.com/home-assistant/home-assistant/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+history_stats%22))
First occurred: 8:59:00 AM (4 occurrences)
Last logged: 8:59:00 AM

* Error fetching Both Drips Cumulative Runtime data: ValueError: day is out of range for month
* Error fetching Zone 2to14 Cumulative Runtime data: ValueError: day is out of range for month
* Error fetching Zone 15 Cumulative Runtime data: ValueError: day is out of range for month
* Error fetching Zone 1 Cumulative Runtime data: ValueError: day is out of range for month

My code

  - platform: history_stats
    name: Zone 1 Cumulative Runtime
    entity_id: switch.zone_1
    state: "on"
    type: time
    start: "{{ now().replace(day=22).replace(hour=0).replace(minute=0).replace(second=0).replace(microsecond=0) }}"
    end: "{{ now().replace(month=(now().month+1)).replace(day=22).replace(hour=0).replace(minute=0).replace(second=0).replace(microsecond=0) }}"

Today is the 31st of May, I’m wondering if it being the 31st has something to do with it as it looks like the problem started at midnight. If so, how would I fix this?

Not sure but this will give you trouble in December:

month=(now().month+1)

What is the actual time range you want?

Also, do you keep that much data in your recorder?

The default is only 10 days.

My water bill runs from the 22nd of one month to the 22nd of the next, so I want it to reset every month on the 22nd.

I have my recorder set to 60 days.

#set the number of days logbook entries are kept
recorder:
  purge_keep_days: 60

You’re changing month first.
So the first replace is done and the date becomes 2022-06-31.... which is not valid so the rest of the replaces stops.
Move the replace month to last and it will work.

And as Tom pointed out, December won’t work.
Make it (now().month+1)%12 and it should work.

That fixed it. Thanks!

Well, now I have another problem. It’s now June 1st and my history_stats are showing “0”. The template is trying to calculate between the dates of 06/22/22 and 07/22/22. I want it to calculate the current stats between the 22nd of each month. So, currently 05/22/22 through 06/22/22. What am I doing wrong here?

  - platform: history_stats
    name: Both Drips Cumulative Runtime
    entity_id: script.drip_irrigation_run
    state: "on"
    type: time
    start: "{{ now().replace(day=22).replace(hour=0).replace(minute=0).replace(second=0).replace(microsecond=0) }}"
    end: "{{ now().replace(day=22).replace(month=(now().month+1)%12).replace(hour=0).replace(minute=0).replace(second=0).replace(microsecond=0) }}"

You have to set the start month to the previous month if the day is less than 22, and this month if the day is equal to or greater than 22.

You have to set the end month to this month if the day is less than 22, and next month if the day is greater than or equal to 22.

Be careful selecting the previous month in January.

If I do that then the stat will be incorrect for the 22-31st of each month but correct for the 1st to the 22nd of the month, right?

If I use this code:

  - platform: history_stats
    name: Both Drips Cumulative Runtime
    entity_id: script.drip_irrigation_run
    state: "on"
    type: time
    start: "{{ now().replace(day=22).replace(month=(now().month-1)%12).replace(hour=0).replace(minute=0).replace(second=0).replace(microsecond=0) }}"
    end: "{{ now().replace(day=22).replace(hour=0).replace(minute=0).replace(second=0).replace(microsecond=0) }}"

From 06/01 to 06/22 it will correctly show me the stats from 05/22 to 06/22. But, from 06/23 through 06/30 it will incorrectly still show me the stats from 05/22 to 06/22 when I want it to show me the stats from 06/22 to 07/22

No. It will be from the 22nd of this month to the 22nd of the next month. That’s what you said you wanted.

Test if the day is before or after the 22nd and set the start months as I indicated above.

I want it to show me the 22nd of last month until the 22nd of this month. Ongoing, I want it to show me the stats between the 22nd of each month.

The code in post 8 shows the correct value when viewed from the 1st to the 22nd of each month, but the code in post 6 shows the correct value between the 22nd and the last day of the month. I’m using this to calculate my irrigation costs and not run the irrigation if I’ve gone over budget. So I need the stat to be correct on every day.

Perhaps something like this?

start: > 
{% if now().day >= 22 %}
  {{ now().replace(day=22).replace(hour=0).replace(minute=0).replace(second=0).replace(microsecond=0) }}
{% else %}
  {% if now().month >= 2 %}
    {{ now().replace(day=22).replace(hour=0).replace(minute=0).replace(second=0).replace(microsecond=0).replace(month=now().month-1) }}
  {% else %}
    {{ now().replace(day=22).replace(hour=0).replace(minute=0).replace(second=0).replace(microsecond=0).replace(month=12) }}
  {% endif %}
{% endif %}
end: >
{% if now().day >= 22 %}
  {{ now().replace(day=22).replace(hour=0).replace(minute=0).replace(second=0).replace(microsecond=0).replace(month=(now().month+1)%12) }}
{% else %}
  {{ now().replace(day=22).replace(hour=0).replace(minute=0).replace(second=0).replace(microsecond=0) }}
{% endif %}

image

Wouldn’t this count the 22 twice in each period ? i would have had 22>21 … thou im kind of totally unable to compose a template, without “copying” and modify :slight_smile:
Edit: never mind, just “remembered” a day starts at 00.01 :slight_smile:

Thanks! That seems to work when I test it on the template test page. But I’m getting a bunch of errors in my config.yaml.

You did not use “tab” in yaml ? … always space, no matter how far you have to “intend”

I think you just need to indent it further out

Thank you! That worked!!