| name | ha-recorder |
| description | Work with the Home Assistant recorder and statistics. Use when asked about history, statistics, long-term stats, database, recorder exclusion, or historical data. |
Home Assistant Recorder Integration
Guide for integrations that work with historical data, statistics, and the recorder.
When to Use Recorder Features
- Statistics: Energy monitoring, long-term trends
- History exclusion: High-frequency sensors, diagnostic entities
- Custom statistics: External data sources
- History queries: Historical analysis features
Excluding from Recorder
Exclude noisy entities from history to reduce database size:
class MyDiagnosticSensor(SensorEntity):
"""Sensor that shouldn't be recorded."""
_attr_entity_registry_enabled_default = False
_attr_entity_registry_visible_default = False
_attr_should_poll = True
Or use recorder configuration in the user's config:
recorder:
exclude:
entity_globs:
- sensor.my_integration_debug_*
domains:
- sensor
Long-Term Statistics
For sensors that should appear in energy dashboard or statistics graphs:
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorStateClass,
)
class MyEnergySensor(SensorEntity):
"""Energy sensor with long-term statistics."""
_attr_device_class = SensorDeviceClass.ENERGY
_attr_state_class = SensorStateClass.TOTAL_INCREASING
_attr_native_unit_of_measurement = "kWh"
State Classes
| State Class | Use Case | Example |
|---|
MEASUREMENT | Instantaneous value | Temperature |
TOTAL | Resettable counter | Trip odometer |
TOTAL_INCREASING | Monotonic counter | Energy meter |
Statistics-Compatible Device Classes
Measurement-type classes (state_class: MEASUREMENT) produce mean/min/max statistics — set mean_type (e.g. StatisticMeanType.ARITHMETIC), leave has_sum=False:
TEMPERATURE (°C, °F)
POWER (W, kW)
Cumulative/sum-type classes (state_class: TOTAL / TOTAL_INCREASING) produce sum statistics — set has_sum=True, leave mean_type=StatisticMeanType.NONE:
ENERGY (kWh, Wh, MWh)
GAS (m³, ft³)
WATER (L, gal, m³)
MONETARY (currency) — sum-based, but no unit conversion is applied
Importing External Statistics
For integrations that provide historical data from external sources:
"""Statistics support for {Name}."""
from __future__ import annotations
from datetime import datetime
from typing import TYPE_CHECKING
from homeassistant.components.recorder import get_instance
from homeassistant.components.recorder.models import (
StatisticData,
StatisticMeanType,
StatisticMetaData,
)
from homeassistant.components.recorder.statistics import (
async_add_external_statistics,
async_import_statistics,
get_last_statistics,
)
from homeassistant.const import UnitOfEnergy
from homeassistant.core import HomeAssistant
from homeassistant.util import dt as dt_util
from .const import DOMAIN
if TYPE_CHECKING:
from . import MyConfigEntry
async def async_import_historical_data(
hass: HomeAssistant,
entry: MyConfigEntry,
) -> None:
"""Import historical statistics from external source."""
coordinator = entry.runtime_data
statistic_id = f"{DOMAIN}:energy_{entry.entry_id}"
metadata = StatisticMetaData(
mean_type=StatisticMeanType.NONE,
has_sum=True,
name="Energy Consumption",
source=DOMAIN,
statistic_id=statistic_id,
unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
)
last_stats = await get_instance(hass).async_add_executor_job(
get_last_statistics, hass, 1, statistic_id, True, {"sum"}
)
if statistic_id in last_stats:
last_time = last_stats[statistic_id][0]["start"]
else:
last_time = None
historical_data = await coordinator.client.async_get_history(since=last_time)
statistics: list[StatisticData] = []
for record in historical_data:
statistics.append(
StatisticData(
start=record["timestamp"],
sum=record["total_energy"],
)
)
async_add_external_statistics(hass, metadata, statistics)
Recorder statistics API change (2025-10-16): StatisticMetaData now takes mean_type (a StatisticMeanType: NONE / ARITHMETIC / CIRCULAR) instead of has_mean, and async_import_statistics / async_add_external_statistics accept an optional unit_class. Re-validate any statistics calls against the breaking-change blog.
Querying History
For features that need historical data:
from datetime import timedelta
from homeassistant.components.recorder import get_instance, history
from homeassistant.util import dt as dt_util
async def get_entity_history(
hass: HomeAssistant,
entity_id: str,
hours: int = 24,
) -> list[dict]:
"""Get historical states for an entity."""
start_time = dt_util.utcnow() - timedelta(hours=hours)
end_time = dt_util.utcnow()
instance = get_instance(hass)
states = await instance.async_add_executor_job(
history.state_changes_during_period,
hass,
start_time,
end_time,
entity_id,
)
return [
{"state": state.state, "last_changed": state.last_changed}
for state in states.get(entity_id, [])
]
Statistics Queries
from datetime import timedelta
from homeassistant.components.recorder.statistics import (
statistics_during_period,
)
from homeassistant.util import dt as dt_util
async def get_energy_statistics(
hass: HomeAssistant,
statistic_id: str,
days: int = 30,
) -> dict:
"""Get energy statistics for the past N days."""
start_time = dt_util.utcnow() - timedelta(days=days)
instance = get_instance(hass)
stats = await instance.async_add_executor_job(
statistics_during_period,
hass,
start_time,
None,
{statistic_id},
"day",
None,
{"sum"},
)
return stats.get(statistic_id, [])
Best Practices
- Use appropriate state_class: Enables automatic statistics
- Use standard units: Allows unit conversion
- Exclude diagnostic data: Reduces database bloat
- Import history incrementally: Track last import time
- Handle recorder unavailable: May be disabled by user
Checking Recorder Availability
from homeassistant.components.recorder import DOMAIN as RECORDER_DOMAIN
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up integration."""
if RECORDER_DOMAIN not in hass.config.components:
_LOGGER.warning("Recorder not available, statistics disabled")
return True
await async_import_historical_data(hass, entry)
return True
Related Skills
- Entity platforms →
ha-entity-platforms
- Coordinator →
ha-coordinator
- Diagnostics →
ha-diagnostics