Home Assistant Unofficial Reference 2024.12.1
home_assistant_cast.py
Go to the documentation of this file.
1 """Home Assistant Cast integration for Cast."""
2 
3 from __future__ import annotations
4 
5 import voluptuous as vol
6 
7 from homeassistant import auth, config_entries, core
8 from homeassistant.const import ATTR_ENTITY_ID
9 from homeassistant.exceptions import HomeAssistantError
10 from homeassistant.helpers import config_validation as cv, dispatcher, instance_id
11 from homeassistant.helpers.network import NoURLAvailableError, get_url
12 from homeassistant.helpers.service import async_register_admin_service
13 
14 from .const import DOMAIN, SIGNAL_HASS_CAST_SHOW_VIEW, HomeAssistantControllerData
15 
16 SERVICE_SHOW_VIEW = "show_lovelace_view"
17 ATTR_VIEW_PATH = "view_path"
18 ATTR_URL_PATH = "dashboard_path"
19 CAST_USER_NAME = "Home Assistant Cast"
20 NO_URL_AVAILABLE_ERROR = (
21  "Home Assistant Cast requires your instance to be reachable via HTTPS. Enable Home"
22  " Assistant Cloud or set up an external URL with valid SSL certificates"
23 )
24 
25 
27  hass: core.HomeAssistant, entry: config_entries.ConfigEntry
28 ):
29  """Set up Home Assistant Cast."""
30  user_id: str | None = entry.data.get("user_id")
31  user: auth.models.User | None = None
32 
33  if user_id is not None:
34  user = await hass.auth.async_get_user(user_id)
35 
36  if user is None:
37  user = await hass.auth.async_create_system_user(
38  CAST_USER_NAME, group_ids=[auth.const.GROUP_ID_ADMIN]
39  )
40  hass.config_entries.async_update_entry(
41  entry, data={**entry.data, "user_id": user.id}
42  )
43 
44  if user.refresh_tokens:
45  refresh_token: auth.models.RefreshToken = list(user.refresh_tokens.values())[0]
46  else:
47  refresh_token = await hass.auth.async_create_refresh_token(user)
48 
49  async def handle_show_view(call: core.ServiceCall) -> None:
50  """Handle a Show View service call."""
51  try:
52  hass_url = get_url(hass, require_ssl=True, prefer_external=True)
53  except NoURLAvailableError as err:
54  raise HomeAssistantError(NO_URL_AVAILABLE_ERROR) from err
55 
56  hass_uuid = await instance_id.async_get(hass)
57 
58  controller_data = HomeAssistantControllerData(
59  # If you are developing Home Assistant Cast, uncomment and set to
60  # your dev app id.
61  # app_id="5FE44367",
62  hass_url=hass_url,
63  hass_uuid=hass_uuid,
64  client_id=None,
65  refresh_token=refresh_token.token,
66  )
67 
68  dispatcher.async_dispatcher_send(
69  hass,
70  SIGNAL_HASS_CAST_SHOW_VIEW,
71  controller_data,
72  call.data[ATTR_ENTITY_ID],
73  call.data[ATTR_VIEW_PATH],
74  call.data.get(ATTR_URL_PATH),
75  )
76 
78  hass,
79  DOMAIN,
80  SERVICE_SHOW_VIEW,
81  handle_show_view,
82  vol.Schema(
83  {
84  ATTR_ENTITY_ID: cv.entity_id,
85  ATTR_VIEW_PATH: str,
86  vol.Optional(ATTR_URL_PATH): str,
87  }
88  ),
89  )
90 
91 
93  hass: core.HomeAssistant, entry: config_entries.ConfigEntry
94 ):
95  """Remove Home Assistant Cast user."""
96  user_id: str | None = entry.data.get("user_id")
97 
98  if user_id is not None and (user := await hass.auth.async_get_user(user_id)):
99  await hass.auth.async_remove_user(user)
def async_setup_ha_cast(core.HomeAssistant hass, config_entries.ConfigEntry entry)
def async_remove_user(core.HomeAssistant hass, config_entries.ConfigEntry entry)
str get_url(HomeAssistant hass, *bool require_current_request=False, bool require_ssl=False, bool require_standard_port=False, bool require_cloud=False, bool allow_internal=True, bool allow_external=True, bool allow_cloud=True, bool|None allow_ip=None, bool|None prefer_external=None, bool prefer_cloud=False)
Definition: network.py:131
None async_register_admin_service(HomeAssistant hass, str domain, str service, Callable[[ServiceCall], Awaitable[None]|None] service_func, VolSchemaType schema=vol.Schema({}, extra=vol.PREVENT_EXTRA))
Definition: service.py:1121