1 """Support for recording details."""
3 from __future__
import annotations
8 import voluptuous
as vol
12 EVENT_RECORDER_5MIN_STATISTICS_GENERATED,
13 EVENT_RECORDER_HOURLY_STATISTICS_GENERATED,
19 INCLUDE_EXCLUDE_BASE_FILTER_SCHEMA,
20 INCLUDE_EXCLUDE_FILTER_SCHEMA_INNER,
21 convert_include_exclude_filter,
24 async_process_integration_platforms,
31 from .
import entity_registry, websocket_api
33 CONF_DB_INTEGRITY_CHECK,
35 INTEGRATION_PLATFORM_COMPILE_STATISTICS,
36 INTEGRATION_PLATFORM_METHODS,
40 from .core
import Recorder
41 from .services
import async_register_services
42 from .tasks
import AddRecorderPlatformTask
43 from .util
import get_instance
45 _LOGGER = logging.getLogger(__name__)
48 DEFAULT_URL =
"sqlite:///{hass_config_path}"
49 DEFAULT_DB_FILE =
"home-assistant_v2.db"
50 DEFAULT_DB_INTEGRITY_CHECK =
True
51 DEFAULT_DB_MAX_RETRIES = 10
52 DEFAULT_DB_RETRY_WAIT = 3
53 DEFAULT_COMMIT_INTERVAL = 5
55 CONF_AUTO_PURGE =
"auto_purge"
56 CONF_AUTO_REPACK =
"auto_repack"
57 CONF_DB_URL =
"db_url"
58 CONF_DB_MAX_RETRIES =
"db_max_retries"
59 CONF_DB_RETRY_WAIT =
"db_retry_wait"
60 CONF_PURGE_KEEP_DAYS =
"purge_keep_days"
61 CONF_PURGE_INTERVAL =
"purge_interval"
62 CONF_EVENT_TYPES =
"event_types"
63 CONF_COMMIT_INTERVAL =
"commit_interval"
66 EXCLUDE_SCHEMA = INCLUDE_EXCLUDE_FILTER_SCHEMA_INNER.extend(
67 {vol.Optional(CONF_EVENT_TYPES): vol.All(cv.ensure_list, [cv.string])}
70 FILTER_SCHEMA = INCLUDE_EXCLUDE_BASE_FILTER_SCHEMA.extend(
75 ALLOW_IN_MEMORY_DB =
False
79 """Validate database URL."""
82 db_url == SQLITE_URL_PREFIX
83 or (db_url.startswith(SQLITE_URL_PREFIX)
and ":memory:" in db_url)
84 )
and not ALLOW_IN_MEMORY_DB:
85 raise vol.Invalid(
"In-memory SQLite database is not supported")
90 CONFIG_SCHEMA = vol.Schema(
92 vol.Optional(DOMAIN, default=dict): vol.All(
93 cv.deprecated(CONF_PURGE_INTERVAL),
94 cv.deprecated(CONF_DB_INTEGRITY_CHECK),
97 vol.Optional(CONF_AUTO_PURGE, default=
True): cv.boolean,
98 vol.Optional(CONF_AUTO_REPACK, default=
True): cv.boolean,
99 vol.Optional(CONF_PURGE_KEEP_DAYS, default=10): vol.All(
100 vol.Coerce(int), vol.Range(min=1)
102 vol.Optional(CONF_PURGE_INTERVAL, default=1): cv.positive_int,
103 vol.Optional(CONF_DB_URL): vol.All(cv.string, validate_db_url),
105 CONF_COMMIT_INTERVAL, default=DEFAULT_COMMIT_INTERVAL
108 CONF_DB_MAX_RETRIES, default=DEFAULT_DB_MAX_RETRIES
111 CONF_DB_RETRY_WAIT, default=DEFAULT_DB_RETRY_WAIT
114 CONF_DB_INTEGRITY_CHECK, default=DEFAULT_DB_INTEGRITY_CHECK
120 extra=vol.ALLOW_EXTRA,
126 """Check if an entity is being recorded.
131 return instance.entity_filter
is None or instance.entity_filter(entity_id)
134 async
def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
135 """Set up the recorder."""
136 conf = config[DOMAIN]
138 entity_filter =
None if _filter.empty_filter
else _filter.get_filter()
139 auto_purge = conf[CONF_AUTO_PURGE]
140 auto_repack = conf[CONF_AUTO_REPACK]
141 keep_days = conf[CONF_PURGE_KEEP_DAYS]
142 commit_interval = conf[CONF_COMMIT_INTERVAL]
143 db_max_retries = conf[CONF_DB_MAX_RETRIES]
144 db_retry_wait = conf[CONF_DB_RETRY_WAIT]
145 db_url = conf.get(CONF_DB_URL)
or DEFAULT_URL.format(
146 hass_config_path=hass.config.path(DEFAULT_DB_FILE)
148 exclude = conf[CONF_EXCLUDE]
149 exclude_event_types: set[EventType[Any] | str] = set(
150 exclude.get(CONF_EVENT_TYPES, [])
152 if EVENT_STATE_CHANGED
in exclude_event_types:
153 _LOGGER.error(
"State change events cannot be excluded, use a filter instead")
154 exclude_event_types.remove(EVENT_STATE_CHANGED)
155 instance = hass.data[DATA_INSTANCE] =
Recorder(
157 auto_purge=auto_purge,
158 auto_repack=auto_repack,
160 commit_interval=commit_interval,
162 db_max_retries=db_max_retries,
163 db_retry_wait=db_retry_wait,
164 entity_filter=entity_filter,
165 exclude_event_types=exclude_event_types,
167 get_instance.cache_clear()
168 instance.async_initialize()
169 instance.async_register()
172 websocket_api.async_setup(hass)
173 entity_registry.async_setup(hass)
177 return await instance.async_db_ready
181 hass: HomeAssistant, instance: Recorder
183 """Set up a recorder integration platform."""
186 def _process_recorder_platform(
187 hass: HomeAssistant, domain: str, platform: Any
189 """Process a recorder platform."""
192 if any(hasattr(platform, _attr)
for _attr
in INTEGRATION_PLATFORM_METHODS):
None async_register_services(HomeAssistant hass)
Any validate_db_url(str db_url)
None _async_setup_integration_platform(HomeAssistant hass, Recorder instance)
bool async_setup(HomeAssistant hass, ConfigType config)
bool is_entity_recorded(HomeAssistant hass, str entity_id)
EntityFilter convert_include_exclude_filter(dict[str, dict[str, list[str]]] config)
Recorder get_instance(HomeAssistant hass)