To-Do list and Jinja

With the new To-Do list feature in Home Assistant I was trying to extract the individual To Do’s though Jinja. In the Developer Template tried the following but it’s showing “KeyError”.

{% for todo in states.todo.shopping_list -%}
  {{ todo }}
{%- endfor %}

Then tried an alternative by using the string variant:

{% for todo in states("todo.shopping_list") -%}
  {{ todo }}
{%- endfor %}

But that one is only showing a 0 as output (I have 2 items in the list).

Due to lack of documentation I am either missing something or support for this has not yet been implemented. Any idea?

The items of the list aren’t held in the states machine. My understanding is that they will be available via a service call that returns a response variable, like calendar and weather entities now do. However, the listing service has not yet been implemented.

7 Likes

Your understanding is correct

1 Like

It looks like it is already merged, coming soon I guess

todo.get_items is already available in beta

It looks like that the API node must be used to get the list in node red. For todo.chores entity it looks like this :

{
   "type": "execute_script",
   "sequence": [
       {
           "service": "todo.get_items",
           "target": {
               "entity_id": [
                   "todo.chores"
                ]
            },
           "response_variable": "service_result"
        },
       {
           "stop": "done",
           "response_variable": "service_result"
        }
    ]
}

I format payload as
payload.response."todo.chores".items[].summary
to get only the texts of items for tts

2 Likes

It’s in the beta currently.

This does not seem to work for me. In an automation, after saving the data from todo.shopping_list to the response_variable, I can’t seem to get the data out again.
This is the 2 steps I use:
Setting the variable:

service: todo.get_items
target:
  entity_id: todo.shopping_list
response_variable: service_result

Reading the variable data (As an example in an input text helper, but does not work anywhere):

service: input_text.set_value
target:
  entity_id: input_text.shopping_list_content
data_template:
  value: >
    {{ service_result['todo.shopping_list']['items'] | map(attribute='summary') | list }}

What am I doing wrong?

1 Like

That will only work if the number of items in your list is less that 255 characters.

You can summarize a todo list using the service call above. You just can’t put it into the main state of an entity.

This explains why all scripts processing the items have stopped working.

Prior to the update, I had a script checking if the name of the item included a store name pre-defined in a variable containing all “zone.X” friendly_id’s, so when a mobile_app entered the zone, they would be sent a notification of the todo/shopping items bound to the store.

So when entering a zone named as an example “SHOP: Aldi”, all Shopping list items with the name “Aldi” would be sent as a notification to the app.

Is there no longer a way to summarize a todo list in a script?

Thank you - Yes, I can confirm it works if the total list is below 255 characters.

But how would I get each item to process, say, in a for-loop or similar?

Yes, you can use a for loop or a generator/filter

Thank you so much for helping.

I may be a fool to ask, but, say I have 15 items in the todo list, how would I write the code to request the (preferably) item name and item state (finished/need action)?

Right now, I can only call the entire list, of course resulting in more than 255 characters:

Executed: 11. december 2023 kl. 14.09.30
Result:
params:
  domain: input_text
  service: set_value
  service_data:
    value:
      - Red Wine
      - White Wine
      - (LIST SHORTENED FOR EASY READING)
    entity_id:
      - input_text.shopping_list_content
  target:
    entity_id:
      - input_text.shopping_list_content

How or where do I define the array item [1], [2], [3] and so on?

Somewhere in this code?

{{ service_result['todo.shopping_list']['items'] | map(attribute='summary') | list }}

Can you clarify the question? Are you looking to just output items that need action? Or, do you want to check if a specific item is on the list and needs action?

If you only want to get items that need action, you can specify status as part of the service data:

- service: todo.get_items
  data:
    status: needs_action
  target:
    entity_id: todo.shopping_list
  response_variable: service_result

Here is a working automation which might help people…

automation:
- id: Addtojobs
  alias: Add to Jobs
  trigger:
  - platform: numeric_state
    entity_id: sensor.dishwasher_power
    below: 5
    for:
      minutes: 1
  - platform: numeric_state
    entity_id: sensor.drier_power
    below: 1
    for:
      minutes: 1
  - platform: numeric_state
    entity_id: sensor.washingmachine_current_power
    below: 2
    for:
      minutes: 1
  action:
  - service: todo.get_items
    target:
      entity_id: todo.home_list
    data:
      status: needs_action
    response_variable: mylist
  - variables:
      machine: >
        {{trigger.entity_id[7:].capitalize().split("_")[0]}}    

  - condition: template
    value_template: >
        {{'Empty '~ machine not in mylist['todo.home_list']['items'] | map(attribute='summary') | list}}    
  - service: todo.add_item
    target:
      entity_id: todo.home_list
    data:
      item: >
        {{"Empty " ~ machine }}
      description: >
        Ready to be emptied at {{as_timestamp(now())|timestamp_custom(" %H:%M",true)}}
      # invisible at present !!

  - service: notify.mobile_app_ian
    data:
      message: >
        {{ machine ~ " needs emptying" }}
      data:
        sticky: "true"        
        actions:
          - action: >
              {{ machine ~ "_emptied"}}
            title: >
              {{ machine ~ " Emptied?"}}

  - alias: "Wait for a response"
    wait_for_trigger:
      - platform: event
        event_type: mobile_app_notification_action
        event_data:
          action: >
            {{ machine ~ "_emptied" }}
      - platform: event
        event_type: mobile_app_notification_action
        event_data:
          action: "snooze"
  - alias: "Perform the action"
    choose:       
      - conditions: "{{ wait.trigger.event.data.action == machine ~ '_emptied' }}"
        sequence:
        - service: todo.remove_item
          target:
            entity_id: todo.home_list
          data:
            item: >
              {{"Empty " ~ machine }}

  mode: parallel

Also, if you want to filter on partial matches, or other fields like description, you could try this:

        {{'string to match' in mylist['todo.home_list']['items'] | map(attribute='summary') | list | string}} 
5 Likes

Not sure if this is the right location to post this but thought I would try.
Is there a way to export the To-Do list to another format that could be consumed by another system? JSON, CSV, TXT, ??

I am recently also thinking about to use this todo list for collecting and saving some events (e.g. windows is open, humidity is high, wash machine finished…)
This post is really helpful!

One more thing I want to do is save the items with additional categorization (e.g. Info / Warning), depends on the different categorization it trigger different action. Because the todo list has limit attributes, I plan to save this in “description” attribute. My question is
How can I use template to filter out a list of “summary” which “description” is “Info” from the output of todo.get_items? Could someone help with the template? Thanks a lot!