Home Assistant Unofficial Reference 2024.12.1
system_info.py
Go to the documentation of this file.
1 """Helper to gather system info."""
2 
3 from __future__ import annotations
4 
5 from functools import cache
6 from getpass import getuser
7 import logging
8 import os
9 import platform
10 from typing import TYPE_CHECKING, Any
11 
12 from homeassistant.const import __version__ as current_version
13 from homeassistant.core import HomeAssistant
14 from homeassistant.loader import bind_hass
15 from homeassistant.util.package import is_docker_env, is_virtual_env
16 
17 from .hassio import is_hassio
18 from .importlib import async_import_module
19 from .singleton import singleton
20 
21 _LOGGER = logging.getLogger(__name__)
22 
23 _DATA_MAC_VER = "system_info_mac_ver"
24 
25 
26 @cache
27 def is_official_image() -> bool:
28  """Return True if Home Assistant is running in an official container."""
29  return os.path.isfile("/OFFICIAL_IMAGE")
30 
31 
32 @singleton(_DATA_MAC_VER)
33 async def async_get_mac_ver(hass: HomeAssistant) -> str:
34  """Return the macOS version."""
35  return (await hass.async_add_executor_job(platform.mac_ver))[0]
36 
37 
38 # Cache the result of getuser() because it can call getpwuid() which
39 # can do blocking I/O to look up the username in /etc/passwd.
40 cached_get_user = cache(getuser)
41 
42 
43 @bind_hass
44 async def async_get_system_info(hass: HomeAssistant) -> dict[str, Any]:
45  """Return info about the system."""
46  # Local import to avoid circular dependencies
47  # We use the import helper because hassio
48  # may not be loaded yet and we don't want to
49  # do blocking I/O in the event loop to import it.
50  if TYPE_CHECKING:
51  # pylint: disable-next=import-outside-toplevel
52  from homeassistant.components import hassio
53  else:
54  hassio = await async_import_module(hass, "homeassistant.components.hassio")
55 
56  is_hassio_ = is_hassio(hass)
57 
58  info_object = {
59  "installation_type": "Unknown",
60  "version": current_version,
61  "dev": "dev" in current_version,
62  "hassio": is_hassio_,
63  "virtualenv": is_virtual_env(),
64  "python_version": platform.python_version(),
65  "docker": False,
66  "arch": platform.machine(),
67  "timezone": str(hass.config.time_zone),
68  "os_name": platform.system(),
69  "os_version": platform.release(),
70  }
71 
72  try:
73  info_object["user"] = cached_get_user()
74  except (KeyError, OSError):
75  # OSError on python >= 3.13, KeyError on python < 3.13
76  # KeyError can be removed when 3.12 support is dropped
77  # see https://docs.python.org/3/whatsnew/3.13.html
78  info_object["user"] = None
79 
80  if platform.system() == "Darwin":
81  info_object["os_version"] = await async_get_mac_ver(hass)
82  elif platform.system() == "Linux":
83  info_object["docker"] = is_docker_env()
84 
85  # Determine installation type on current data
86  if info_object["docker"]:
87  if info_object["user"] == "root" and is_official_image():
88  info_object["installation_type"] = "Home Assistant Container"
89  else:
90  info_object["installation_type"] = "Unsupported Third Party Container"
91 
92  elif is_virtual_env():
93  info_object["installation_type"] = "Home Assistant Core"
94 
95  # Enrich with Supervisor information
96  if is_hassio_:
97  if not (info := hassio.get_info(hass)):
98  _LOGGER.warning("No Home Assistant Supervisor info available")
99  info = {}
100 
101  host = hassio.get_host_info(hass) or {}
102  info_object["supervisor"] = info.get("supervisor")
103  info_object["host_os"] = host.get("operating_system")
104  info_object["docker_version"] = info.get("docker")
105  info_object["chassis"] = host.get("chassis")
106 
107  if info.get("hassos") is not None:
108  info_object["installation_type"] = "Home Assistant OS"
109  else:
110  info_object["installation_type"] = "Home Assistant Supervised"
111 
112  return info_object
bool is_hassio(HomeAssistant hass)
Definition: __init__.py:302
ModuleType async_import_module(HomeAssistant hass, str name)
Definition: importlib.py:30
str async_get_mac_ver(HomeAssistant hass)
Definition: system_info.py:33
dict[str, Any] async_get_system_info(HomeAssistant hass)
Definition: system_info.py:44