Evaluating a template stored in an entity

I’ve implemented a recurring todo system that syncs an HA todo list with a Google Tasks todo list, repeating a completed task “X” days after completiong, where “X” is embedded within the task summary, e.g. “Clean guest bathroom [3]”, representing my desire to clean the guest bathroom every 3 days.

What I want to do next is to enhance this so that if a guest is present, the todo gets skipped and rescheduled for the following day. To do this, I want to embed a condition within the todo description, essentially a template, e.g. “{{ person.guest == ‘not_home’ }}”. My vision is that the script that handles the todo recurrence would evaluate this template and adjust the due date accordingly, but it seems that in order to do that, I need to embed a template within a template, and I can’t find a way to evaluate a nested template.

Note that I’m using cleaning the guest bathroom only as an example. I’d like to be able to embed any template in a todo description and have it processed as described above. Evaluating a nested template doesn’t seem to be possible however, so what else can I try?

Could you post your code (using the ‘Preformatted Text’ option)? Very hard to suggest anything without that.

Sure, here’s a prototype that I’m using for testing. Looping through a todo list, looking at each item on the list, writing a log entry for each item that has a non-empty description (assuming it contains a template) and the template contained within that description evaluates to true (e.g. {{ person.guest == ‘not_home’ }}). It’s the evaluation of the template that I’m trying to find a way to do.

sequence:
  - action: todo.get_items
    data:
      status:
        - needs_action
    response_variable: mylist
    target:
      entity_id: todo.recurring
  - repeat:
      sequence:
        - if:
            - condition: template
              value_template: >-
                {{ 

                {# Due today or overdue #}

                (as_timestamp(now()) - as_timestamp(repeat.item.due)) / 3600 >
                0 

                and 
                  (
                    {# Todo description is not empty #}
                    repeat.item.description > ''
                    and
                    {# Evaluate template stored in description #}
                    {{ repeat.item.description }}
                  ) 
                }}
          then:
            - action: logbook.log
              metadata: {}
              data:
                name: Conditional todo test
                message: "{{ repeat.item.summary }}"
      for_each: "{{ mylist['todo.recurring']['items'] }}"
alias: Recurring todo test
description: ""

I see. It sounds like the solution you’re currently thinking about would essentially pull some Jinja template code from an external source (the description in the ToDo item) and execute that code. Unfortunately, I don’t know of a way to do this. I think it’s deliberately impossible because of security concerns (e.g., risk of code injection). If I’m wrong about this, I’m sure someone on the forum will correct me.

Consider a less raw approach. For example, you could parse the description for special text like “[no_guest]” and if it’s present, your value_template code can understand what that means and what condition to actually resort to.

Not sure about the ToDo list functionality in HA or in Google Tasks, but if there is a way to add custom tags in Google Tasks and access them in HA, that’s an even cleaner way to do it since you wouldn’t have to pollute your ToDo item’s description with robotspeak.

The main limitation here is that you have to code a finite set of conditions in your template that are correlated with elements associated with the ToDo list. You can’t put the actual code outside of your YAML.

1 Like

It can’t “evaluate template stored in description”.

All that will be accomplished by this template is that it will display the contents of repeat.item.description.

{{ repeat.item.description }}

What you want is to instruct the Jinja2 processor to evaluate the contents of repeat.item.description and then display the result. Some languages have an eval() function but Jinja2’s Built-in Filters don’t have one.

1 Like

Thanks @123 and @d921 for confirming - I assumed this wasn’t possible, but wanted to confirm. An alternative to an “eval()” function is what I was hoping to find.

Why does HASS not provide such a function itself? The template selector seems fairly useless without it, since you cannot use !input within existing templates either…

My two guesses:

  • No one has ever volunteered their time to implement it.

  • Someone did submit a PR but it was rejected.