From b28fda2433cf911ff64b761f7490d50e3ae386bf Mon Sep 17 00:00:00 2001 From: Jan-Philipp Benecke Date: Wed, 6 Sep 2023 08:54:25 +0200 Subject: [PATCH] Move template coordinator to its own file (#99419) * Move template update coordinator to its own file * Add coordinator.py to .coveragerc * Remove coordinator.py to .coveragerc * Apply suggestions from code review * Update homeassistant/components/template/coordinator.py * Copy over fixes from upstream --------- Co-authored-by: Erik Montnemery Co-authored-by: G Johansson --- homeassistant/components/template/__init__.py | 99 +------------------ .../components/template/coordinator.py | 94 ++++++++++++++++++ 2 files changed, 99 insertions(+), 94 deletions(-) create mode 100644 homeassistant/components/template/coordinator.py diff --git a/homeassistant/components/template/__init__.py b/homeassistant/components/template/__init__.py index c4ba7081f5a..22919ac9e70 100644 --- a/homeassistant/components/template/__init__.py +++ b/homeassistant/components/template/__init__.py @@ -2,30 +2,21 @@ from __future__ import annotations import asyncio -from collections.abc import Callable import logging from homeassistant import config as conf_util from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ( - CONF_UNIQUE_ID, - EVENT_HOMEASSISTANT_START, - SERVICE_RELOAD, -) -from homeassistant.core import CoreState, Event, HomeAssistant, ServiceCall, callback +from homeassistant.const import CONF_UNIQUE_ID, SERVICE_RELOAD +from homeassistant.core import Event, HomeAssistant, ServiceCall from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers import ( - discovery, - trigger as trigger_helper, - update_coordinator, -) +from homeassistant.helpers import discovery from homeassistant.helpers.reload import async_reload_integration_platforms -from homeassistant.helpers.script import Script from homeassistant.helpers.service import async_register_admin_service from homeassistant.helpers.typing import ConfigType from homeassistant.loader import async_get_integration -from .const import CONF_ACTION, CONF_TRIGGER, DOMAIN, PLATFORMS +from .const import CONF_TRIGGER, DOMAIN, PLATFORMS +from .coordinator import TriggerUpdateCoordinator _LOGGER = logging.getLogger(__name__) @@ -121,83 +112,3 @@ async def _process_config(hass: HomeAssistant, hass_config: ConfigType) -> None: if coordinator_tasks: hass.data[DOMAIN] = await asyncio.gather(*coordinator_tasks) - - -class TriggerUpdateCoordinator(update_coordinator.DataUpdateCoordinator): - """Class to handle incoming data.""" - - REMOVE_TRIGGER = object() - - def __init__(self, hass, config): - """Instantiate trigger data.""" - super().__init__(hass, _LOGGER, name="Trigger Update Coordinator") - self.config = config - self._unsub_start: Callable[[], None] | None = None - self._unsub_trigger: Callable[[], None] | None = None - self._script: Script | None = None - - @property - def unique_id(self) -> str | None: - """Return unique ID for the entity.""" - return self.config.get("unique_id") - - @callback - def async_remove(self): - """Signal that the entities need to remove themselves.""" - if self._unsub_start: - self._unsub_start() - if self._unsub_trigger: - self._unsub_trigger() - - async def async_setup(self, hass_config: ConfigType) -> None: - """Set up the trigger and create entities.""" - if self.hass.state == CoreState.running: - await self._attach_triggers() - else: - self._unsub_start = self.hass.bus.async_listen_once( - EVENT_HOMEASSISTANT_START, self._attach_triggers - ) - - for platform_domain in PLATFORMS: - if platform_domain in self.config: - self.hass.async_create_task( - discovery.async_load_platform( - self.hass, - platform_domain, - DOMAIN, - {"coordinator": self, "entities": self.config[platform_domain]}, - hass_config, - ) - ) - - async def _attach_triggers(self, start_event=None) -> None: - """Attach the triggers.""" - if CONF_ACTION in self.config: - self._script = Script( - self.hass, - self.config[CONF_ACTION], - self.name, - DOMAIN, - ) - - if start_event is not None: - self._unsub_start = None - - self._unsub_trigger = await trigger_helper.async_initialize_triggers( - self.hass, - self.config[CONF_TRIGGER], - self._handle_triggered, - DOMAIN, - self.name, - self.logger.log, - start_event is not None, - ) - - async def _handle_triggered(self, run_variables, context=None): - if self._script: - script_result = await self._script.async_run(run_variables, context) - if script_result: - run_variables = script_result.variables - self.async_set_updated_data( - {"run_variables": run_variables, "context": context} - ) diff --git a/homeassistant/components/template/coordinator.py b/homeassistant/components/template/coordinator.py new file mode 100644 index 00000000000..7f24fe731cc --- /dev/null +++ b/homeassistant/components/template/coordinator.py @@ -0,0 +1,94 @@ +"""Data update coordinator for trigger based template entities.""" +from collections.abc import Callable +import logging + +from homeassistant.const import EVENT_HOMEASSISTANT_START +from homeassistant.core import CoreState, callback +from homeassistant.helpers import discovery, trigger as trigger_helper +from homeassistant.helpers.script import Script +from homeassistant.helpers.typing import ConfigType +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator + +from .const import CONF_ACTION, CONF_TRIGGER, DOMAIN, PLATFORMS + +_LOGGER = logging.getLogger(__name__) + + +class TriggerUpdateCoordinator(DataUpdateCoordinator): + """Data update coordinator for trigger based template entities.""" + + REMOVE_TRIGGER = object() + + def __init__(self, hass, config): + """Instantiate trigger data.""" + super().__init__(hass, _LOGGER, name="Trigger Update Coordinator") + self.config = config + self._unsub_start: Callable[[], None] | None = None + self._unsub_trigger: Callable[[], None] | None = None + self._script: Script | None = None + + @property + def unique_id(self) -> str | None: + """Return unique ID for the entity.""" + return self.config.get("unique_id") + + @callback + def async_remove(self): + """Signal that the entities need to remove themselves.""" + if self._unsub_start: + self._unsub_start() + if self._unsub_trigger: + self._unsub_trigger() + + async def async_setup(self, hass_config: ConfigType) -> None: + """Set up the trigger and create entities.""" + if self.hass.state == CoreState.running: + await self._attach_triggers() + else: + self._unsub_start = self.hass.bus.async_listen_once( + EVENT_HOMEASSISTANT_START, self._attach_triggers + ) + + for platform_domain in PLATFORMS: + if platform_domain in self.config: + self.hass.async_create_task( + discovery.async_load_platform( + self.hass, + platform_domain, + DOMAIN, + {"coordinator": self, "entities": self.config[platform_domain]}, + hass_config, + ) + ) + + async def _attach_triggers(self, start_event=None) -> None: + """Attach the triggers.""" + if CONF_ACTION in self.config: + self._script = Script( + self.hass, + self.config[CONF_ACTION], + self.name, + DOMAIN, + ) + + if start_event is not None: + self._unsub_start = None + + self._unsub_trigger = await trigger_helper.async_initialize_triggers( + self.hass, + self.config[CONF_TRIGGER], + self._handle_triggered, + DOMAIN, + self.name, + self.logger.log, + start_event is not None, + ) + + async def _handle_triggered(self, run_variables, context=None): + if self._script: + script_result = await self._script.async_run(run_variables, context) + if script_result: + run_variables = script_result.variables + self.async_set_updated_data( + {"run_variables": run_variables, "context": context} + )