Add for each item support to repeat action (#70093)

This commit is contained in:
Franck Nijhof 2022-04-15 19:10:25 +02:00 committed by GitHub
parent 4a950f06e2
commit 1b48d7eda1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 268 additions and 3 deletions

View file

@ -41,6 +41,7 @@ from homeassistant.const import (
CONF_EVENT,
CONF_EVENT_DATA,
CONF_EVENT_DATA_TEMPLATE,
CONF_FOR_EACH,
CONF_IF,
CONF_MODE,
CONF_PARALLEL,
@ -744,17 +745,21 @@ class _ScriptRun:
return result
@async_trace_path("repeat")
async def _async_repeat_step(self):
async def _async_repeat_step(self): # noqa: C901
"""Repeat a sequence."""
description = self._action.get(CONF_ALIAS, "sequence")
repeat = self._action[CONF_REPEAT]
saved_repeat_vars = self._variables.get("repeat")
def set_repeat_var(iteration, count=None):
def set_repeat_var(
iteration: int, count: int | None = None, item: Any = None
) -> None:
repeat_vars = {"first": iteration == 1, "index": iteration}
if count:
repeat_vars["last"] = iteration == count
if item is not None:
repeat_vars["item"] = item
self._variables["repeat"] = repeat_vars
# pylint: disable=protected-access
@ -785,6 +790,35 @@ class _ScriptRun:
if self._stop.is_set():
break
elif CONF_FOR_EACH in repeat:
try:
items = template.render_complex(repeat[CONF_FOR_EACH], self._variables)
except (exceptions.TemplateError, ValueError) as ex:
self._log(
"Error rendering %s repeat for each items template: %s",
self._script.name,
ex,
level=logging.ERROR,
)
raise _AbortScript from ex
if not isinstance(items, list):
self._log(
"Repeat 'for_each' must be a list of items in %s, got: %s",
self._script.name,
items,
level=logging.ERROR,
)
raise _AbortScript("Repeat 'for_each' must be a list of items")
count = len(items)
for iteration, item in enumerate(items, 1):
set_repeat_var(iteration, count, item)
extra_msg = f" of {count} with item: {repr(item)}"
if self._stop.is_set():
break
await async_run_sequence(iteration, extra_msg)
elif CONF_WHILE in repeat:
conditions = [
await self._async_get_condition(config) for config in repeat[CONF_WHILE]