Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 57 additions & 17 deletions homeassistant/components/youtube/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
"""Support for YouTube."""

from types import MappingProxyType

from aiohttp.client_exceptions import ClientError

from homeassistant.config_entries import ConfigEntry, ConfigSubentry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import (
Expand All @@ -10,13 +13,20 @@
OAuth2TokenRequestError,
OAuth2TokenRequestReauthError,
)
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers import device_registry as dr, entity_registry as er
from homeassistant.helpers.config_entry_oauth2_flow import (
OAuth2Session,
async_get_config_entry_implementation,
)

from .api import AsyncConfigEntryAuth
from .const import (
ATTR_TITLE,
CONF_CHANNEL_ID,
CONF_CHANNELS,
DOMAIN,
SUBENTRY_TYPE_CHANNEL,
)
from .coordinator import YouTubeConfigEntry, YouTubeDataUpdateCoordinator

PLATFORMS = [Platform.SENSOR]
Expand All @@ -35,13 +45,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: YouTubeConfigEntry) -> b
) from err
except (OAuth2TokenRequestError, ClientError) as err:
raise ConfigEntryNotReady from err
coordinator = YouTubeDataUpdateCoordinator(hass, entry, auth)

await coordinator.async_config_entry_first_refresh()

await delete_devices(hass, entry, coordinator)
entry.runtime_data = {}
for subentry in entry.get_subentries_of_type(SUBENTRY_TYPE_CHANNEL):
coordinator = YouTubeDataUpdateCoordinator(hass, entry, subentry, auth)
await coordinator.async_config_entry_first_refresh()
Comment thread
Hugo1380 marked this conversation as resolved.
Outdated
entry.runtime_data[subentry.subentry_id] = coordinator
if (title := coordinator.data[ATTR_TITLE]) != subentry.title:
hass.config_entries.async_update_subentry(entry, subentry, title=title)

entry.runtime_data = coordinator
entry.async_on_unload(entry.add_update_listener(async_update_listener))
Comment thread
Hugo1380 marked this conversation as resolved.
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

return True
Expand All @@ -52,15 +65,42 @@ async def async_unload_entry(hass: HomeAssistant, entry: YouTubeConfigEntry) ->
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)


async def delete_devices(
hass: HomeAssistant,
entry: YouTubeConfigEntry,
coordinator: YouTubeDataUpdateCoordinator,
) -> None:
"""Delete all devices created by integration."""
channel_ids = list(coordinator.data)
async def async_update_listener(hass: HomeAssistant, entry: YouTubeConfigEntry) -> None:
"""Reload the config entry when it or one of its subentries is updated."""
await hass.config_entries.async_reload(entry.entry_id)


async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Migrate old entries to the subentry structure."""
Comment thread
Hugo1380 marked this conversation as resolved.
device_registry = dr.async_get(hass)
dev_entries = dr.async_entries_for_config_entry(device_registry, entry.entry_id)
for dev_entry in dev_entries:
if any(identifier[1] in channel_ids for identifier in dev_entry.identifiers):
device_registry.async_remove_device(dev_entry.id)
entity_registry = er.async_get(hass)
prefix = f"{entry.entry_id}_"
for channel_id in dict.fromkeys(entry.options.get(CONF_CHANNELS, [])):
Comment thread
Hugo1380 marked this conversation as resolved.
Outdated
subentry = ConfigSubentry(
data=MappingProxyType({CONF_CHANNEL_ID: channel_id}),
subentry_type=SUBENTRY_TYPE_CHANNEL,
title=channel_id,
Comment thread
Hugo1380 marked this conversation as resolved.
Outdated
unique_id=channel_id,
)
hass.config_entries.async_add_subentry(entry, subentry)
device = device_registry.async_get_device_by_identifier(
(DOMAIN, f"{prefix}{channel_id}"), entry.entry_id
)
if device is not None:
device_registry.async_update_device(
device.id,
new_identifiers={(DOMAIN, channel_id)},
new_config_subentry_id=subentry.subentry_id,
)
for entity_entry in er.async_entries_for_config_entry(
entity_registry, entry.entry_id
):
if not entity_entry.unique_id.startswith(f"{prefix}{channel_id}_"):
continue
entity_registry.async_update_entity(
entity_entry.entity_id,
new_unique_id=entity_entry.unique_id.removeprefix(prefix),
config_subentry_id=subentry.subentry_id,
)
hass.config_entries.async_update_entry(entry, version=2, options={})
return True
Loading