2020-08-25 22:25:15 +00:00
|
|
|
"""Class to reload platforms."""
|
|
|
|
|
2020-08-25 23:13:43 +00:00
|
|
|
import asyncio
|
2020-08-25 22:25:15 +00:00
|
|
|
import logging
|
2020-08-25 23:13:43 +00:00
|
|
|
from typing import Iterable, Optional
|
2020-08-25 22:25:15 +00:00
|
|
|
|
|
|
|
from homeassistant import config as conf_util
|
2020-08-25 23:13:43 +00:00
|
|
|
from homeassistant.const import SERVICE_RELOAD
|
|
|
|
from homeassistant.core import Event, callback
|
2020-08-25 22:25:15 +00:00
|
|
|
from homeassistant.exceptions import HomeAssistantError
|
|
|
|
from homeassistant.helpers import config_per_platform
|
|
|
|
from homeassistant.helpers.entity_platform import DATA_ENTITY_PLATFORM, EntityPlatform
|
|
|
|
from homeassistant.helpers.typing import HomeAssistantType
|
|
|
|
from homeassistant.loader import async_get_integration
|
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
async def async_reload_integration_platforms(
|
2020-08-25 23:13:43 +00:00
|
|
|
hass: HomeAssistantType, integration_name: str, integration_platforms: Iterable
|
2020-08-25 22:25:15 +00:00
|
|
|
) -> None:
|
|
|
|
"""Reload an integration's platforms.
|
|
|
|
|
|
|
|
The platform must support being re-setup.
|
|
|
|
|
|
|
|
This functionality is only intended to be used for integrations that process
|
|
|
|
Home Assistant data and make this available to other integrations.
|
|
|
|
|
|
|
|
Examples are template, stats, derivative, utility meter.
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
unprocessed_conf = await conf_util.async_hass_config_yaml(hass)
|
|
|
|
except HomeAssistantError as err:
|
|
|
|
_LOGGER.error(err)
|
|
|
|
return
|
|
|
|
|
|
|
|
for integration_platform in integration_platforms:
|
|
|
|
platform = async_get_platform(hass, integration_name, integration_platform)
|
|
|
|
|
|
|
|
if not platform:
|
|
|
|
continue
|
|
|
|
|
|
|
|
integration = await async_get_integration(hass, integration_platform)
|
|
|
|
|
|
|
|
conf = await conf_util.async_process_component_config(
|
|
|
|
hass, unprocessed_conf, integration
|
|
|
|
)
|
|
|
|
|
|
|
|
if not conf:
|
|
|
|
continue
|
|
|
|
|
|
|
|
await platform.async_reset()
|
|
|
|
|
|
|
|
# Extract only the config for template, ignore the rest.
|
|
|
|
for p_type, p_config in config_per_platform(conf, integration_platform):
|
|
|
|
if p_type != integration_name:
|
|
|
|
continue
|
|
|
|
|
|
|
|
await platform.async_setup(p_config) # type: ignore
|
|
|
|
|
|
|
|
|
|
|
|
@callback
|
|
|
|
def async_get_platform(
|
|
|
|
hass: HomeAssistantType, integration_name: str, integration_platform_name: str
|
|
|
|
) -> Optional[EntityPlatform]:
|
|
|
|
"""Find an existing platform."""
|
|
|
|
for integration_platform in hass.data[DATA_ENTITY_PLATFORM][integration_name]:
|
|
|
|
if integration_platform.domain == integration_platform_name:
|
|
|
|
platform: EntityPlatform = integration_platform
|
|
|
|
return platform
|
|
|
|
|
|
|
|
return None
|
2020-08-25 23:13:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def async_setup_reload_service(
|
|
|
|
hass: HomeAssistantType, domain: str, platforms: Iterable
|
|
|
|
) -> None:
|
|
|
|
"""Create the reload service for the domain."""
|
|
|
|
|
|
|
|
if hass.services.has_service(domain, SERVICE_RELOAD):
|
|
|
|
return
|
|
|
|
|
|
|
|
async def _reload_config(call: Event) -> None:
|
|
|
|
"""Reload the platforms."""
|
|
|
|
|
|
|
|
await async_reload_integration_platforms(hass, domain, platforms)
|
|
|
|
hass.bus.async_fire(f"event_{domain}_reloaded", context=call.context)
|
|
|
|
|
|
|
|
hass.helpers.service.async_register_admin_service(
|
|
|
|
domain, SERVICE_RELOAD, _reload_config
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def setup_reload_service(
|
|
|
|
hass: HomeAssistantType, domain: str, platforms: Iterable
|
|
|
|
) -> None:
|
|
|
|
"""Sync version of async_setup_reload_service."""
|
|
|
|
|
|
|
|
asyncio.run_coroutine_threadsafe(
|
|
|
|
async_setup_reload_service(hass, domain, platforms), hass.loop,
|
|
|
|
).result()
|