Home Assistant Unofficial Reference 2024.12.1
__init__.py
Go to the documentation of this file.
1 """Provide info to system health."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 from urllib.parse import urlparse
7 
8 from homeassistant.components import system_health
9 from homeassistant.core import HomeAssistant, callback
10 
11 from .. import get_instance
12 from ..const import SupportedDialect
13 from ..core import Recorder
14 from ..util import session_scope
15 from .mysql import db_size_bytes as mysql_db_size_bytes
16 from .postgresql import db_size_bytes as postgresql_db_size_bytes
17 from .sqlite import db_size_bytes as sqlite_db_size_bytes
18 
19 DIALECT_TO_GET_SIZE = {
20  SupportedDialect.SQLITE: sqlite_db_size_bytes,
21  SupportedDialect.MYSQL: mysql_db_size_bytes,
22  SupportedDialect.POSTGRESQL: postgresql_db_size_bytes,
23 }
24 
25 
26 @callback
28  hass: HomeAssistant, register: system_health.SystemHealthRegistration
29 ) -> None:
30  """Register system health callbacks."""
31  register.async_register_info(system_health_info)
32 
33 
34 def _get_db_stats(instance: Recorder, database_name: str) -> dict[str, Any]:
35  """Get the stats about the database."""
36  db_stats: dict[str, Any] = {}
37  with session_scope(session=instance.get_session(), read_only=True) as session:
38  if (
39  (dialect_name := instance.dialect_name)
40  and (get_size := DIALECT_TO_GET_SIZE.get(dialect_name))
41  and (db_bytes := get_size(session, database_name))
42  ):
43  db_stats["estimated_db_size"] = f"{db_bytes/1024/1024:.2f} MiB"
44  return db_stats
45 
46 
47 @callback
48 def _async_get_db_engine_info(instance: Recorder) -> dict[str, Any]:
49  """Get database engine info."""
50  db_engine_info: dict[str, Any] = {}
51  if dialect_name := instance.dialect_name:
52  db_engine_info["database_engine"] = dialect_name.value
53  if database_engine := instance.database_engine:
54  db_engine_info["database_version"] = str(database_engine.version)
55  return db_engine_info
56 
57 
58 async def system_health_info(hass: HomeAssistant) -> dict[str, Any]:
59  """Get info for the info page."""
60  instance = get_instance(hass)
61 
62  recorder_runs_manager = instance.recorder_runs_manager
63  database_name = urlparse(instance.db_url).path.lstrip("/")
64  db_engine_info = _async_get_db_engine_info(instance)
65  db_stats: dict[str, Any] = {}
66 
67  if instance.async_db_ready.done():
68  db_stats = await instance.async_add_executor_job(
69  _get_db_stats, instance, database_name
70  )
71  db_runs = {
72  "oldest_recorder_run": recorder_runs_manager.first.start,
73  "current_recorder_run": recorder_runs_manager.current.start,
74  }
75  return db_runs | db_stats | db_engine_info
int get_size(list[str] files_list)
Definition: sensor.py:45
dict[str, Any] _async_get_db_engine_info(Recorder instance)
Definition: __init__.py:48
None async_register(HomeAssistant hass, system_health.SystemHealthRegistration register)
Definition: __init__.py:29
dict[str, Any] _get_db_stats(Recorder instance, str database_name)
Definition: __init__.py:34
dict[str, Any] system_health_info(HomeAssistant hass)
Definition: __init__.py:58
Recorder get_instance(HomeAssistant hass)
Definition: recorder.py:74
Generator[Session] session_scope(*HomeAssistant|None hass=None, Session|None session=None, Callable[[Exception], bool]|None exception_filter=None, bool read_only=False)
Definition: recorder.py:86