Multi-year Home Assistant dashboards from long-term statistics
You can chart years of sensor data (e.g. a weather station’s daily min/mean/max temperature and rainfall) in Home Assistant without an external database. The data is already in HA’s long-term statistics. This page covers the pattern: a year-picker dashboard on top of those statistics, generated by a script instead of being built in the UI.
How it works
- Long-term statistics. HA stores hourly aggregates (mean/min/max, or sum for totals) for
every sensor that has a
state_class(measurement,total,total_increasing). These are kept forever, independent of the recorder’spurge_keep_days. You don’t need InfluxDB or a custom archive for yearly charts. - Cards.
apexcharts-cardreads statistics directly (statistics:withtype: mean|min|max|sumandperiod: day).config-template-cardinjects the chosen year into the chart’sspan/offset.button-cardbuilds the year-picker buttons.
- Year picker. An
input_numberhelper holds the selected year. The template card turns it into the chart’s time window, and the buttons change the helper. - Drill-down. A click handler on a data point opens the history of that day.
- Dashboard as code. A Python script generates the whole dashboard config and pushes it via
the HA WebSocket API (
lovelace/config/save). To change the dashboard, you edit the script and re-run it. No restart is needed, and the result is reproducible and versioned in the config repo.
Porting to another instance
Because the dashboard is generated, porting it is mostly remapping entities:
- Make a table from each source entity to the equivalent target entity (for example a different
weather-station brand with other entity IDs). Every sensor needs a
state_class, or it has no long-term statistics. - Install missing custom cards. If they are not in the target’s HACS, copy them from the source
instance’s
www/community/and register them as local Lovelace resources (/local/community/...). - Create the
input_numberyear helper and the dashboard registration (sidebar title, icon, URL path) to match. - Run the generator against the target instance.
Pitfalls
- A sensor without
state_classhas no long-term statistics, so there is nothing to chart beyond the recorder window. - Statistics exist only from the time the
state_classwas set. Earlier years stay empty. apexcharts-card’sspanand offset behave in non-obvious ways with calendar years. Test across a year boundary.- Editing
.storage/files directly (e.g. dashboard registration) can hit file-ownership problems in Docker setups. Prefer the WebSocket API, or fix ownership after editing. - Hand edits in the UI are overwritten the next time the generator runs.
Sources
- Legacy wiki.js: Home Assistant instance and Statistik dashboard — private source
- Legacy wiki.js: second Home Assistant instance and Statistik dashboard port — private source