Optimize template 2 (#3521)

* Enforce compiling templates

* Refactor templates

* Add template validator to Logbook service

* Some more fixes

* Lint

* Allow easy skipping of rfxtrx tests

* Fix template bug in AND & OR conditions

* add entities extractor

Conflicts:
	tests/helpers/test_template.py

* fix unittest

* Convert template to be async

* Fix Farcy

* Lint fix

* Limit template updates to related entities

* Make template automation async
This commit is contained in:
Paulus Schoutsen 2016-09-27 21:29:55 -07:00 committed by GitHub
parent 6694b0470e
commit 00e298206e
52 changed files with 841 additions and 562 deletions

View file

@ -16,8 +16,8 @@ from homeassistant.const import (
CONF_BELOW, CONF_ABOVE)
from homeassistant.exceptions import TemplateError, HomeAssistantError
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.template import render, compile_template
import homeassistant.util.dt as dt_util
from homeassistant.util.async import run_callback_threadsafe
FROM_CONFIG_FORMAT = '{}_from_config'
@ -41,7 +41,7 @@ def and_from_config(config: ConfigType, config_validation: bool=True):
"""Create multi condition matcher using 'AND'."""
if config_validation:
config = cv.AND_CONDITION_SCHEMA(config)
checks = [from_config(entry) for entry in config['conditions']]
checks = [from_config(entry, False) for entry in config['conditions']]
def if_and_condition(hass: HomeAssistant,
variables=None) -> bool:
@ -63,7 +63,7 @@ def or_from_config(config: ConfigType, config_validation: bool=True):
"""Create multi condition matcher using 'OR'."""
if config_validation:
config = cv.OR_CONDITION_SCHEMA(config)
checks = [from_config(entry) for entry in config['conditions']]
checks = [from_config(entry, False) for entry in config['conditions']]
def if_or_condition(hass: HomeAssistant,
variables=None) -> bool:
@ -96,7 +96,7 @@ def numeric_state(hass: HomeAssistant, entity, below=None, above=None,
variables = dict(variables or {})
variables['state'] = entity
try:
value = render(hass, value_template, variables)
value = value_template.render(variables)
except TemplateError as ex:
_LOGGER.error("Template error: %s", ex)
return False
@ -125,18 +125,12 @@ def numeric_state_from_config(config, config_validation=True):
above = config.get(CONF_ABOVE)
value_template = config.get(CONF_VALUE_TEMPLATE)
cache = {}
def if_numeric_state(hass, variables=None):
"""Test numeric state condition."""
if value_template is None:
tmpl = None
elif hass in cache:
tmpl = cache[hass]
else:
cache[hass] = tmpl = compile_template(hass, value_template)
if value_template is not None:
value_template.hass = hass
return numeric_state(hass, entity_id, below, above, tmpl,
return numeric_state(hass, entity_id, below, above, value_template,
variables)
return if_numeric_state
@ -215,9 +209,16 @@ def sun_from_config(config, config_validation=True):
def template(hass, value_template, variables=None):
"""Test if template condition matches."""
return run_callback_threadsafe(
hass.loop, async_template, hass, value_template, variables,
).result()
def async_template(hass, value_template, variables=None):
"""Test if template condition matches."""
try:
value = render(hass, value_template, variables)
value = value_template.async_render(variables)
except TemplateError as ex:
_LOGGER.error('Error duriong template condition: %s', ex)
return False
@ -231,16 +232,11 @@ def template_from_config(config, config_validation=True):
config = cv.TEMPLATE_CONDITION_SCHEMA(config)
value_template = config.get(CONF_VALUE_TEMPLATE)
cache = {}
def template_if(hass, variables=None):
"""Validate template based if-condition."""
if hass in cache:
tmpl = cache[hass]
else:
cache[hass] = tmpl = compile_template(hass, value_template)
value_template.hass = hass
return template(hass, tmpl, variables)
return template(hass, value_template, variables)
return template_if