diff --git a/homeassistant/helpers/service.py b/homeassistant/helpers/service.py index 20f7aa2d2d7..d03fb8c91c6 100644 --- a/homeassistant/helpers/service.py +++ b/homeassistant/helpers/service.py @@ -38,7 +38,7 @@ from homeassistant.helpers import template import homeassistant.helpers.config_validation as cv from homeassistant.helpers.template import Template from homeassistant.helpers.typing import ConfigType, HomeAssistantType, TemplateVarsType -from homeassistant.loader import async_get_integration, bind_hass +from homeassistant.loader import Integration, async_get_integration, bind_hass from homeassistant.util.yaml import load_yaml from homeassistant.util.yaml.loader import JSON_TYPE @@ -252,21 +252,29 @@ async def async_extract_entity_ids( return extracted -async def _load_services_file(hass: HomeAssistantType, domain: str) -> JSON_TYPE: +def _load_services_file(hass: HomeAssistantType, integration: Integration) -> JSON_TYPE: """Load services file for an integration.""" - integration = await async_get_integration(hass, domain) try: - return await hass.async_add_executor_job( - load_yaml, str(integration.file_path / "services.yaml") - ) + return load_yaml(str(integration.file_path / "services.yaml")) except FileNotFoundError: - _LOGGER.warning("Unable to find services.yaml for the %s integration", domain) + _LOGGER.warning( + "Unable to find services.yaml for the %s integration", integration.domain + ) return {} except HomeAssistantError: - _LOGGER.warning("Unable to parse services.yaml for the %s integration", domain) + _LOGGER.warning( + "Unable to parse services.yaml for the %s integration", integration.domain + ) return {} +def _load_services_files( + hass: HomeAssistantType, integrations: Iterable[Integration] +) -> List[JSON_TYPE]: + """Load service files for multiple intergrations.""" + return [_load_services_file(hass, integration) for integration in integrations] + + @bind_hass async def async_get_all_descriptions( hass: HomeAssistantType, @@ -289,8 +297,12 @@ async def async_get_all_descriptions( loaded = {} if missing: - contents = await asyncio.gather( - *(_load_services_file(hass, domain) for domain in missing) + integrations = await asyncio.gather( + *(async_get_integration(hass, domain) for domain in missing) + ) + + contents = await hass.async_add_executor_job( + _load_services_files, hass, integrations ) for domain, content in zip(missing, contents): @@ -308,7 +320,7 @@ async def async_get_all_descriptions( # Cache missing descriptions if description is None: domain_yaml = loaded[domain] - yaml_description = domain_yaml.get(service, {}) + yaml_description = domain_yaml.get(service, {}) # type: ignore # Don't warn for missing services, because it triggers false # positives for things like scripts, that register as a service