Home Assistant’s long-term statistics only work for numeric sensors. There is no native support for discrete data — binary sensors (on/off), or enum states like open/closed/opening/closing,
heating/cooling/idle/off — so their history vanishes when the recorder purges.
I really love how you solved the problem to make it compatible with other statistics and charts, by creating sperate statistics with an appendix for the state.
Well done.
Should also help to avoid problems introduced by HA updates, as these structures have been like that for a long time.
Will definitely play around with that after my holidays.
There are a few entities that I miss history after switching from a dedicated DB with Grafana back to HA internal recorder / charting dashboard cards.
This integration should help to solve this.
It works well with built in statistics graph, but could be a little quicker to configure charts with a little bit of logic that understands how to grab related states statistics. Maybe a custom chart or adaptation of an existing one.
Good news — no code change needed at all. I checked the tool’s actual logic (not just help text): it does zero validation on statistic_ids beyond “not empty,” and passes the string straight through to recorder.get_statistics. So discrete_statistics:binary_sensor_grid_status_on_duration-style IDs will work mechanically as soon as the integration exists and produces them — nothing to “lift.”
The one real update needed is the help text, which currently says “only sensors with a valid state_class and unit_of_measurement are supported” — that becomes actively misleading once this integration is installed, since it’d wrongly discourage querying the new discrete_statistics:* IDs.
So I’ll let you know what Friday thinks. This solves a very specific question my build tomorrow will make people ask… (I basically boil each room down to a sensor… With a room state enum, you may have solved a problem I was running against in automatically building priors for room presence baysean sensors…)
Yes - if you have a single enum you want to track over time, this will work perfectly. You can track the duration in each state and the number of times each state was activated over all history. Use the Statistics Graph card for now, and I’ll likely add a custom one to make config simpler (with Statistics Graph you have to manually add an entry for each state - but if the states don’t change this is a one-time job).
I added a custom card, that’s based on the Statistics Graph card, but makes it much easier to build charts for entities with many states. You only need to select the entity from the list (it will show only configured entities that generate discrete statistics), and it will pull in all states (even new ones as they appear).
v0.4: period sensors — the numbers, not just the charts
The most common workaround people describe in these threads is a handful of history_stats sensors per entity — time and count for today, this month, this year
— which drift or reset once the window reaches past purge_keep_days. The integration can now give you those numbers directly, read from the statistics it
already records, so they have no purge horizon and always agree with the chart.
Open an entry on the integration page and choose Add sensor:
States — one or more (added together), picked from the states the entity has recorded, or typed in.
Measure — time in hours, share of the period as a percentage, or number of changes into the states.
Period — today, yesterday, this/last week, month, year, all time; the last hour, 24 hours, 7, 30 or 365 days; or a custom window from start/end/duration
templates, exactly as history_stats takes them ({{ today_at(‘09:00’) }}, {{ state_attr(‘sun.sun’, ‘next_rising’) }}).
Include the current hour — statistics are compiled hourly; with this on, the sensor follows the entity’s changes since the last compiled hour as they
happen, so “time on today” is live to the second.
Each sensor is an ordinary entity — tiles, automations, templates — with period_start, period_end and compiled_until attributes. Sensors are attached to the
entry, so deleting one deletes it; the entry itself still has no entities of its own.
Reading is cheap at any range. A year-long window is arithmetic on a handful of precompiled rows plus at most a couple of hours of raw history (the hour in
progress, and the hour a window edge falls in) — not a year of state changes every minute.
Exact while the recorder holds the hours, accurate after. Over a window the recorder still has history for, the sensor reads the same rows history_stats
would, to the same result. Once purge has taken the hour a rolling window starts in, that one hour is estimated from its hourly total, and an estimated
attribute says so. Calendar periods start on the hour and are always accurate, and never estimated.
Also in this release:
Time at places — a person or device_tracker entity’s zones are states like any other, so “hours at the office this week” and “trips to the gym this year”
have always worked; the README now has the example.
Download diagnostics on the entry’s menu, for “it isn’t compiling” reports.
I also cannot get my head around the resolution it records by default.
So for heating, I want to see further back than the standard 7 day for when the heating was on and for how long. Will this just show the same entity in history for longer?
You need to do a crtl-shift-r (hard refresh) in your browser after you restart HA with the new integration to refresh the cached javascript.
The history view will not extend past the default 7 recorder days (it looks at raw state changes), but the Discrete Statistics card will look back forever (once the statistics are built).
New release adding an (optional) convenience sensor to give you the mapped, filtered, debounced value of the source sensor - in the same way as the statistics calculator would record it.