Add context to scripts and automations (#16415)
* Add context to script helper * Update script component * Add context to automations * Lint
This commit is contained in:
parent
e1501c83f8
commit
746f4ac158
17 changed files with 164 additions and 144 deletions
|
@ -6,7 +6,7 @@ from typing import Optional, Sequence
|
|||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.core import HomeAssistant, Context, callback
|
||||
from homeassistant.const import CONF_CONDITION, CONF_TIMEOUT
|
||||
from homeassistant.exceptions import TemplateError
|
||||
from homeassistant.helpers import (
|
||||
|
@ -34,9 +34,10 @@ CONF_CONTINUE = 'continue_on_timeout'
|
|||
|
||||
|
||||
def call_from_config(hass: HomeAssistant, config: ConfigType,
|
||||
variables: Optional[Sequence] = None) -> None:
|
||||
variables: Optional[Sequence] = None,
|
||||
context: Optional[Context] = None) -> None:
|
||||
"""Call a script based on a config entry."""
|
||||
Script(hass, cv.SCRIPT_SCHEMA(config)).run(variables)
|
||||
Script(hass, cv.SCRIPT_SCHEMA(config)).run(variables, context)
|
||||
|
||||
|
||||
class Script():
|
||||
|
@ -64,12 +65,13 @@ class Script():
|
|||
"""Return true if script is on."""
|
||||
return self._cur != -1
|
||||
|
||||
def run(self, variables=None):
|
||||
def run(self, variables=None, context=None):
|
||||
"""Run script."""
|
||||
run_coroutine_threadsafe(
|
||||
self.async_run(variables), self.hass.loop).result()
|
||||
self.async_run(variables, context), self.hass.loop).result()
|
||||
|
||||
async def async_run(self, variables: Optional[Sequence] = None) -> None:
|
||||
async def async_run(self, variables: Optional[Sequence] = None,
|
||||
context: Optional[Context] = None) -> None:
|
||||
"""Run script.
|
||||
|
||||
This method is a coroutine.
|
||||
|
@ -94,7 +96,8 @@ class Script():
|
|||
"""Handle delay."""
|
||||
# pylint: disable=cell-var-from-loop
|
||||
self._async_listener.remove(unsub)
|
||||
self.hass.async_add_job(self.async_run(variables))
|
||||
self.hass.async_create_task(
|
||||
self.async_run(variables, context))
|
||||
|
||||
delay = action[CONF_DELAY]
|
||||
|
||||
|
@ -134,7 +137,8 @@ class Script():
|
|||
def async_script_wait(entity_id, from_s, to_s):
|
||||
"""Handle script after template condition is true."""
|
||||
self._async_remove_listener()
|
||||
self.hass.async_add_job(self.async_run(variables))
|
||||
self.hass.async_create_task(
|
||||
self.async_run(variables, context))
|
||||
|
||||
self._async_listener.append(async_track_template(
|
||||
self.hass, wait_template, async_script_wait, variables))
|
||||
|
@ -145,7 +149,8 @@ class Script():
|
|||
|
||||
if CONF_TIMEOUT in action:
|
||||
self._async_set_timeout(
|
||||
action, variables, action.get(CONF_CONTINUE, True))
|
||||
action, variables, context,
|
||||
action.get(CONF_CONTINUE, True))
|
||||
|
||||
return
|
||||
|
||||
|
@ -154,10 +159,10 @@ class Script():
|
|||
break
|
||||
|
||||
elif CONF_EVENT in action:
|
||||
self._async_fire_event(action, variables)
|
||||
self._async_fire_event(action, variables, context)
|
||||
|
||||
else:
|
||||
await self._async_call_service(action, variables)
|
||||
await self._async_call_service(action, variables, context)
|
||||
|
||||
self._cur = -1
|
||||
self.last_action = None
|
||||
|
@ -178,7 +183,7 @@ class Script():
|
|||
if self._change_listener:
|
||||
self.hass.async_add_job(self._change_listener)
|
||||
|
||||
async def _async_call_service(self, action, variables):
|
||||
async def _async_call_service(self, action, variables, context):
|
||||
"""Call the service specified in the action.
|
||||
|
||||
This method is a coroutine.
|
||||
|
@ -186,9 +191,14 @@ class Script():
|
|||
self.last_action = action.get(CONF_ALIAS, 'call service')
|
||||
self._log("Executing step %s" % self.last_action)
|
||||
await service.async_call_from_config(
|
||||
self.hass, action, True, variables, validate_config=False)
|
||||
self.hass, action,
|
||||
blocking=True,
|
||||
variables=variables,
|
||||
validate_config=False,
|
||||
context=context
|
||||
)
|
||||
|
||||
def _async_fire_event(self, action, variables):
|
||||
def _async_fire_event(self, action, variables, context):
|
||||
"""Fire an event."""
|
||||
self.last_action = action.get(CONF_ALIAS, action[CONF_EVENT])
|
||||
self._log("Executing step %s" % self.last_action)
|
||||
|
@ -201,7 +211,7 @@ class Script():
|
|||
_LOGGER.error('Error rendering event data template: %s', ex)
|
||||
|
||||
self.hass.bus.async_fire(action[CONF_EVENT],
|
||||
event_data)
|
||||
event_data, context=context)
|
||||
|
||||
def _async_check_condition(self, action, variables):
|
||||
"""Test if condition is matching."""
|
||||
|
@ -216,7 +226,8 @@ class Script():
|
|||
self._log("Test condition {}: {}".format(self.last_action, check))
|
||||
return check
|
||||
|
||||
def _async_set_timeout(self, action, variables, continue_on_timeout=True):
|
||||
def _async_set_timeout(self, action, variables, context,
|
||||
continue_on_timeout):
|
||||
"""Schedule a timeout to abort or continue script."""
|
||||
timeout = action[CONF_TIMEOUT]
|
||||
unsub = None
|
||||
|
@ -229,7 +240,8 @@ class Script():
|
|||
# Check if we want to continue to execute
|
||||
# the script after the timeout
|
||||
if continue_on_timeout:
|
||||
self.hass.async_add_job(self.async_run(variables))
|
||||
self.hass.async_create_task(
|
||||
self.async_run(variables, context))
|
||||
else:
|
||||
self._log("Timeout reached, abort script.")
|
||||
self.async_stop()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue