<commit_before>"""
Offer template automation rules.

For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation/#template-trigger
"""
import logging

from homeassistant.const import CONF_VALUE_TEMPLATE, EVENT_STATE_CHANGED
from homeassistant.exceptions import TemplateError
from homeassistant.helpers import template

_LOGGER = logging.getLogger(__name__)


def trigger(hass, config, action):
    """Listen for state changes based on configuration."""
    value_template = config.get(CONF_VALUE_TEMPLATE)

    if value_template is None:
        _LOGGER.error("Missing configuration key %s", CONF_VALUE_TEMPLATE)
        return False

    # Local variable to keep track of if the action has already been triggered
    already_triggered = False

    def event_listener(event):
        """Listen for state changes and calls action."""
        nonlocal already_triggered
        template_result = _check_template(hass, value_template)

        # Check to see if template returns true
        if template_result and not already_triggered:
            already_triggered = True
            action()
        elif not template_result:
            already_triggered = False

    hass.bus.listen(EVENT_STATE_CHANGED, event_listener)
    return True


def if_action(hass, config):
    """Wrap action method with state based condition."""
    value_template = config.get(CONF_VALUE_TEMPLATE)

    if value_template is None:
        _LOGGER.error("Missing configuration key %s", CONF_VALUE_TEMPLATE)
        return False

    return lambda: _check_template(hass, value_template)


def _check_template(hass, value_template):
    """Check if result of template is true."""
    try:
        value = template.render(hass, value_template, {})
    except TemplateError:
        _LOGGER.exception('Error parsing template')
        return False

    return value.lower() == 'true'<commit_msg>Catch exception common during startup.<commit_after>"""
Offer template automation rules.

For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation/#template-trigger
"""
import logging

from homeassistant.const import CONF_VALUE_TEMPLATE, EVENT_STATE_CHANGED
from homeassistant.exceptions import TemplateError
from homeassistant.helpers import template

_LOGGER = logging.getLogger(__name__)


def trigger(hass, config, action):
    """Listen for state changes based on configuration."""
    value_template = config.get(CONF_VALUE_TEMPLATE)

    if value_template is None:
        _LOGGER.error("Missing configuration key %s", CONF_VALUE_TEMPLATE)
        return False

    # Local variable to keep track of if the action has already been triggered
    already_triggered = False

    def event_listener(event):
        """Listen for state changes and calls action."""
        nonlocal already_triggered
        template_result = _check_template(hass, value_template)

        # Check to see if template returns true
        if template_result and not already_triggered:
            already_triggered = True
            action()
        elif not template_result:
            already_triggered = False

    hass.bus.listen(EVENT_STATE_CHANGED, event_listener)
    return True


def if_action(hass, config):
    """Wrap action method with state based condition."""
    value_template = config.get(CONF_VALUE_TEMPLATE)

    if value_template is None:
        _LOGGER.error("Missing configuration key %s", CONF_VALUE_TEMPLATE)
        return False

    return lambda: _check_template(hass, value_template)


def _check_template(hass, value_template):
    """Check if result of template is true."""
    try:
        value = template.render(hass, value_template, {})
    except TemplateError as ex:
        if ex.args and ex.args[0].startswith(
                "UndefinedError: 'None' has no attribute"):
            # Common during HA startup - so just a warning
            _LOGGER.warning(ex)
        else:
            _LOGGER.error(ex)
        return False

    return value.lower() == 'true'
{'fraction_non_alphanumeric': 0.07313505607020965, 'fraction_numerical': 0.00024378352023403217, 'mean_word_length': 3.3742004264392325, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3513115', 'n_tokens_mistral': 1107, 'n_tokens_neox': 1094, 'n_words': 350}