Template rest sensor attributes list

I have a mealie instance that I’m trying to pull the shopping list items from into a rest sensor via template. My ultimate end goal is to get this data into a to-do list with an automation so I can sync the to-do list with Google Keep. I’m not sure you can do a template to-do object so I’m starting with a sensor. I’m getting hung up on a few things and I can’t seem to get past how to get the items into an array inside of the attributes list of the sensor.

Something like this is what I’m after:

items:
  - item: "1x Soy Sauce"
  - item: "2x Milk"
  - item: "5x Bread"

The rest api outputs something like the following in json format:

{
    "listname":"Costco"
    "listItems":[
        {
           "id":1,
           "display":"1x Soy Sauce",
        }
        {
           "id":1,
           "display":"2x Milk",
        }
        {
           "id":1,
           "display":"5x Bread",
        }
    ]
}

I’m trying to get the value of display for each item in the listItems variable into the sensors attributes. My sensor entity looks like this so far:

  - platform: rest
    resource: "http://ip:port/api/groups/shopping/lists/id"
    method: GET
    name: Mealie shopping list
    headers:
      Authorization: "Bearer tokenhere"
    value_template: "None"
    attribute_templates: >
      {% set ns = namespace(bl=[]) %}
      {% for i in value_json['listItems'] %}
        {% set ns.bl = ns.bl + [i['display']}] %}
      {% endfor %}
      {{ ns.bl }}
    force_update: true
    scan_interval: 15

My only issue is that I’m unsure how to get the data into the attributes as a list. Thank you for the help you can provide.

You can’t template the entire field in the rest platform.

Make a rest sensor that has all the items, then make a template sensor from that.

  - platform: rest
    resource: "http://ip:port/api/groups/shopping/lists/id"
    method: GET
    name: Mealie shopping list
    headers:
      Authorization: "Bearer tokenhere"
    value_template: "OK"
    json_attributes:
    - listname
    - listItems

If you want to make a todo list from these items, you can do that. Otherwise you can make a select entity that has a dropdwon of all the items. Or just a sensor with an attribute that has all the items.

e.g.

template:
- sensor:
  - name: Items
    state: >
      {{ state_attr('mealie_shopping_list', 'listItems') | default([], True) | count }}
    attributes:
      items: >
       {{ state_attr('mealie_shopping_list', 'listItems') | default([], True) | map(attribute='display') | list }}
1 Like

Thank you for the help. The examples worked great. The last thing that is throwing me for a loop is deduping the data that is going to go into the todo list. For some reason it’s still being added into the todo list each time. I’m trying to compare between two lists and it’s not working. Not sure what I’m doing wrong here as I’ve not done comparison between a list and a todo list. There really isn’t many examples out there either.

alias: Mealie Shopping List Sync
description: ""
trigger:
  - platform: state
    entity_id:
      - sensor.mealie_shopping_list
    attribute: listItems
condition: []
action:
  - service: todo.get_items
    metadata: {}
    data: {}
    response_variable: existinglist
    target:
      entity_id: todo.shopping_list
  - repeat:
      for_each: >-
        {{state_attr('sensor.mealie_shopping_list', 'listItems') | default([],
        True) | map(attribute='display') | list }} 
      sequence:
        - if:
            - condition: template
              value_template: >-
                {% set existing = (existinglist.values() | list)[0]['items'] |
                map(attribute='summary') | list %}

                {% if repeat.item not in existing %}
                  true
                {% endif %}
          then:
            - service: todo.add_item
              metadata: {}
              data:
                item: "{{ repeat.item }}"
              target:
                entity_id: todo.shopping_list
              enabled: true
mode: single

1 Like

It looks like I got it. Changed the if statement to this:

                {% if repeat.item in existing %}
                  false
                {% else %}
                  true
                {% endif %}
1 Like