Create a template sensor which outputs a list?

I have a template sensor that creates a text string with a description and a time to help me do things in time. The generated string is based on the current time and various sensors upon which I create some logic.
A short example of the template sensor:

{# States #}
{% set ts_now = as_timestamp(now()) %}
{% set asleep = states('input_boolean.is_asleep') %}

{# Event times #}
{% set leftbedtime = states('input_datetime.left_bed')|as_timestamp %}
{% set most_recent_med_time = states('input_datetime.latest_medicine')|as_timestamp %}
{% set most_recent_food_time = states('input_datetime.latest_food')|as_timestamp %}

{# Relative times #}
{% set timesincebed = (now()|as_timestamp)-leftbedtime %}
{% set timesincemedicine = (now()|as_timestamp)-most_recent_med_time %}
{% set timesincefood = (now()|as_timestamp)-most_recent_food_time %}

{% if asleep == "on" %} Wake up! (06:30)
{% elif timesincemedicine > 6*3600 %}
                Take medicine! ({{leftbedtime+10*60|timestamp_custom('%H:%M:%S')}})
{% elif timesincefood > 6*3600 %}
                Eat! ({{most_recent_food_time +8*3600|timestamp_custom('%H:%M:%S')}})
{% endif %}

So when I am asleep, the sensor will always tell me to wake up at 6:30.
If I left bed at 6:45, it will tell me to take medicine at 6:55.
After having taken the medicine, it will tell me to eat, and a time 8 hours after previous meal.

Now, I would want to separate the description (“wake up”, “eat”, “take medicine”) from the suggested time, into two sensors. My idea is to let this template sensor deliver a list entry and then create two other sensors that just present the first or the second part of that list as its sensor value.
Problem is, I tried to generate a list in the template editor, but it only worked with static strings, not with variables. Can you suggest a way to change the template above so that it returns a list instead of a text?

I suspect that if you shared more information about why you want to take this specific approach, it would be possible to suggest a different, cleaner way.

For example, logic of this nature is often more naturally handled in an automation.

It’s possible to store lists and dictionaries in sensor attributes, but a sensor state is typically a single value with an associated device class and measurement unit. One way to do it close to how you want to do it is to put your dictionary/list in an attribute of the sensor. The code complexity gets high very fast with such an approach.

Please show your expected output.

A jinja2 list looks like …

['a', 'b', 'c', 'x', 'k']

You are not building anything like that. So I am wondering what a ‘list’ looks like to you.

My template sensor has looked like the current one for long time. I have only used to look at it to remember what to do. It is a string describing what my next suggested action to do is, and at what time I have to do it at latest.

What’s new for now is that I wanted to extract the time part of the string, and use that one in an automation using tts to repeat the phrase every x mins if I am overdue.

I wanted a list with the current action.
So if I am asleep, the list should be:
[‘Wake up!’, ‘06:30’]

(Until now, it has created a text string that says “Wake up! (06:30)”)

However, I think I can manage this by letting it continue to generate text strings.
I will just modify the formatting in a csv style so it for example creates the text “Wake Up!;06:30;”.

Then I will create another template sensor that extracts the time.

The time template sensor:

{% set theevent = states('sensor.nextevent') %}
{{theevent.split(';')[1]}}

For something this limited, extracting the string in your TTS automation is a way more practical approach than resorting to lists in sensors. The advice might be different if you had something way more complex.

You can keep your old format (with the time in parens) and extract the string using a regular expression; that’s one step up from split.

Also, it feels to me that a more natural way to approach this—if you want to build it out in the future to cover more kinds of actions—is with a calendar or todo list, rather than a template sensor.

The full template sensor has about 30 different conditions to generate different strings.
I only want to manage that logic in one place, hence the desire to split the output from the sensor.

Ah, gotcha.

You could certainly put any symbol in there you want and do the split. Or, make a list. Or, whatever.

{% if asleep == "on" %} Wake up!|06:30
{% elif timesincemedicine > 6*3600 %}
                Take medicine!|{{leftbedtime+10*60|timestamp_custom('%H:%M:%S')}}
{% elif timesincefood > 6*3600 %}
                Eat!|{{most_recent_food_time +8*3600|timestamp_custom('%H:%M:%S')}}
{% endif %}

The above example would split on the pipe character (‘|’)

The calendar/todo list sounds promising.

1 Like

I am not sure how a todo list/calendar would benefit me with the sensor part…? I dont think it can be so flexible as I want it.