'str object' has no attribute 'mealplan_id' when using list of dicts

Hi. I’m using action mealie.get_mealplan to receive a list of dictionaries (as I assume). From this List I want to find the dict with a certain attribute (entityType=‘breakfast’). But as it seems, the dict is only received as a string, so I can’t access the key/value pairs.

Ultimately I want to iterate over the meals and list them on the dashboard.

This is how I’ve defined my sensor:

  - trigger:
      - trigger: time_pattern
        minutes: /1
      - trigger: event
        event_type: event_template_reloaded
    action:
      - delay: 00:00:01
      - action: mealie.get_mealplan
        data:
          config_entry_id: 01JGTP41YN3DKGY7QMSWP6BZH5
          start_date: "2025-01-20"
          end_date: "2025-01-20"
        response_variable: todays_meals
    sensor:
      - name: Todays breakfast
        unique_id: todays_breakfast
        state: "Test"
        attributes:
          meals: "{{ todays_meals.mealplan }}"

And here is my access:

This is what the action returns:

mealplan:
  - mealplan_id: 657
    user_id: 7a7f246d-4521-4467-9028-5ab6cda17b73
    group_id: 41c84375-650e-4a88-b56a-f99cd4f0b34d
    entry_type: side
    mealplan_date: "2025-01-20"
    title: null
    description: null
    recipe:
      recipe_id: cfe59f13-3cb0-486b-a635-b0c6e3384203
      ...
    household_id: 8658fc76-cf4b-4bd9-afc5-98b605445ad5
  - mealplan_id: 656
    ...

Any ideas how to get it working?

Pretty please do not post screenshots. Always post code, input, output, etc. as properly marked up text.

Your sensor attribute appears to be neither a list nor a dict, it is a string. When you are accessing index 1, you get the second character of the string which is the { in your template results. When you attempt to access item “mealplan_id”, well that obviously won’t work.

Either you need to fix your sensor so that it outputs a list or dict depending on what you want to achieve further down the line (I have no idea), or process the current value as-is through the from_json filter.

It’s because your output ({{ todays_meals.mealplan }}) has an enum in it, which means it won’t validate as a dictionary and | as_json will not work. You either need to reject that attribute (entry_type) or come up with a different plan.
image


this template should work to turn it into a usable dictionary while retaining entry_type:

  - trigger:
      - trigger: time_pattern
        minutes: /1
      - trigger: event
        event_type: event_template_reloaded
    action:
      - delay: 00:00:01
      - action: mealie.get_mealplan
        data:
          config_entry_id: 01JGTP41YN3DKGY7QMSWP6BZH5
          start_date: "2025-01-20"
          end_date: "2025-01-20"
        response_variable: todays_meals
    sensor:
      - name: Todays breakfast
        unique_id: todays_breakfast
        state: "Test"
        attributes:
          meals: >
            {% set ns = namespace(meals=[]) %}
            {% for meal in todays_meals.mealplan %}
              {% set items = meal.items() | list | rejectattr('0', 'eq', 'entry_type') | list + [('entry_type', meal.entry_type.value)] %}
              {% set ns.meals = ns.meals + [dict.from_keys(items)] %}
            {% endfor %}
            {{ ns.meals }}
1 Like

Thanks for the quick reply. I had to filter out mealplan_date, too, now it works :slight_smile: . Heres the complete sensor:

  - trigger:
      - trigger: time_pattern
        minutes: /1
      - trigger: event
        event_type: event_template_reloaded
    action:
      - delay: 00:00:01
      - action: mealie.get_mealplan
        data:
          config_entry_id: 01JGTP41YN3DKGY7QMSWP6BZH5
          start_date: "2025-01-20"
          end_date: "2025-01-20"
        response_variable: todays_meals
    sensor:
      - name: Todays mealplan
        unique_id: todays_mealplan
        state: "Todays Mealplan"
        attributes:
          meals: >
            {% set entry_type_sort_map = { 'dinner': 3, 'breakfast': 1, 'lunch': 2, 'side': 4 } %}
            {% set ns = namespace(meals=[]) %}
            {% for meal in todays_meals.mealplan %}
              {% set items = meal.items() | list
                | rejectattr('0', 'eq', 'mealplan_date')
                | rejectattr('0', 'eq', 'entry_type')
                | list + [('entry_type', meal.entry_type.value)]
                | list + [('sort',entry_type_sort_map.get( meal.entry_type.value ))] %}
              {% set ns.meals = ns.meals + [dict.from_keys(items)] %}
            {% endfor %}
            {{ ns.meals }}

And the markdown for showing the meals:

{% set entry_type_map = {
'dinner': 'Abendessen',
'breakfast': 'Frühstück',
'lunch': 'Mittagessen',
'side': 'Beilage'
} %}

{% set meals = state_attr('sensor.todays_mealplan','meals')|sort(attribute='sort') %}
{% for meal in meals %}
{{ entry_type_map.get( meal['entry_type'] ) }}: {{ meal['recipe']['name'] }}
{% endfor %}

Thanks

Ah, yep, see that now. Missed it before