History Stats for toggling state

I have a switchbot, which I toggle to press a button. I want to count every time that button is pressed overnight, which per Home Assistant would just mean the switchbot state is toggled, as on → off or off → on are both just pressing the button.

I thought I could do this with a History Stats sensor…count all the on’s plus all the off’s (knowing this is going to be one higher than the actual). However, the value is of my sensor is always 1. Am I doing something wrong or does History Stats not work like this?

  - platform: history_stats
    name: Button Count
    entity_id: switch.switchbot
    state: 
      - "on"
      - "off"
    type: count
    end: "{{ (now().replace(minute=0, second=0, microsecond=0) + timedelta(hours=5)).replace(hour=19) }}"
    duration:
        hours: 24

I can’t even understand your formula, sorry.
You take the hour part of now() if I understand, then add 5 hours
The result will be one "o’clock’ time that can be anything, today, or tomorrow if it is already past 7pm.
But you replace this new “hour only” time by 7pm o’clock.
Therefore, it is either 7pm today, or 7pm tomorrow that will come out of your formula, am I right?

I can’t test right now, my HA is under maintenance because of new index on states table.
But have a look at Developer Tools > Template to validate the outcome of your template.

At the end, whatever the outcome, it will take the previous 24 hours from that computed time.
Isn’t it easier to set the start/end based on a fixed time?
Or, the attributes of the sun entity, providing the next sunset/sunrise ?

I copied from the example here, except yes I tried to change from 4 pm until 7 pm (since I’m mostly interested in the overnight)

Next 4 pm: 24 hours, from the last 4 pm till the next 4 pm. If it hasn’t been 4 pm today, that would be 4 pm yesterday until 4 pm today. If it is already past 4 pm today, it will be 4 pm today until 4 pm tomorrow. When changing the start time, then add or subtract to the 8-hour buffer to match the next midnight.

end: "{{ (now().replace(minute=0, second=0, microsecond=0) + timedelta(hours=8)).replace(hour=16) }}"
duration:
    hours: 24

You don’t need to do that…

end: "{{ today_at('16:00:00') }}"
duration:
    hours: 24

Agree with @Didgeridrew, you’re over-complicating the template.

  end: >
    {% set offset = 0 %}
    {% if int(now().strftime("%H")) >= 16 %}
    {%   set offset = 24 %}
    {% endif %}
    {{ today_at("16:00") + timedelta(hours=offset) }}
  duration:
    hours: 24

This one could be simplified but it is readable.

  1. First, assume that there will be no need to add 24 hours.
  2. Then, if it is already past 4pm, change this assumption to offset by 24 hours
  3. Finally take today at 4pm as end time but offset if needed

So, before 4pm, it will be yesterday 4pm to today 4pm, otherwise today 4pm to tomorrow 4pm.
I believe it is what you tried to achieve.

Again, it wasn’t my code, just the example. :slight_smile: Which, I agree, is confusing.

So I tried @Didgeridrew’s suggestion, but thought it might be better to use 7 a.m. so I have last night’s count. But still the sensor just has the value 1. I can see overnight last night it should show 4. Unless it is just now starting to count (since I changed the sensor yaml)?

    end: "{{ today_at('07:00:00') }}"
    duration:
        hours: 24

I’m also confused by that but it might be ok as I don’t know switchbot.
How do you know that it should show 4?
I’ve such a sensor in my configuration, and here it is for reference:

  - platform: history_stats
    name: chambre enfants
    entity_id: light.chambre_enfants
    state: "on"
    type: count
    start: "{{ today_at() }}"
    end: "{{ now() }}"

From the history I can see that it should be 7 and it is.

From the history. It was turned on twice and off once, plus it started off. So I’d expect it to show 4. (I’d love for it to show 3, but I can live)

I switched it from the state array to just “on” like you had it. And now it shows 2. The documentation shows that you can pass a list but it doesn’t seem to be working. I guess I can do two history sensors and a template to add plus subtract one. Minor pain, but that should work.

Looking at this, it seems like it is doing +1 for on -1 for off and you get your 1
EDIT by pure curiosity, if you switch on and off, do you get -1 by any chance?

No, I got 2 if I did on or off. No idea how it comes up with 1. But now that I know the cause, seems multiple states hasn’t worked for a while, searching other posts in the community.