UPDATE AUGUST 2024
Home Assistant 2024.7 introduced an official Mealie integration, so I’d recommend using that to get the data into Home Assistant rather than my custom rest sensor based solution below.
ORIGINAL POST:
I noticed this in my logs as well the other day, I didn’t realise it was from this Mealie setup! I’ll have a play around with it and let you know if I can prevent those log messages. I’m sure I’m doing something dodgy somewhere.
EDIT: I think it’s the json_attributes_path in the rest sensor that’s causing it. Not sure how to work around that yet.
EDIT 2:
I got this resolved, but it required a fair few changes, essentially to avoid using the rest sensor and instead use the restful platform to extract the ingredient ID and the item name in different sensors. This way I can use a jinja template to handle the null scenario where item[0] in the array doesn’t exist, which occurs when there’s nothing on the Mealie shopping list.
TLDR with complete config at bottom of this post.
First, you need to replace the entire sensor
section with this rest
section instead:
rest:
- resource_template: !secret mealie_shopping_items_api_endpoint
headers:
Authorization: !secret mealie_api_token
params:
perPage: 1
queryFilter: checked=false
orderBy: food.name
orderDirection: asc
sensor:
- name: Mealie Shopping List Items
availability: >
{{ value_json['total'] }}
#Sensor to view items which are on any Mealie shopping list
#Extract the ingredient data in the following format: "food - quantity unit" eg. "apples - 1.5 kilogram", or "Empty List" if no items are left in the list
value_template: >
{# If no items in list, return "Empty List" #}
{% if value_json['total'] == 0 %}
Empty List
{# If distinct food is not defined use display name instead #}
{% elif value_json['items'][0]['food'] == none %}
{{ value_json['items'][0]['display'] }}
{# If quantity is available, include it in the output #}
{% elif value_json['items'][0]['quantity'] > 0 %}
{{ value_json['items'][0]['food']['name'] }} - {{ (value_json['items'][0]['quantity'] | round(3) | string).rstrip('0').rstrip('.') }} {{ value_json['items'][0]['unit']['name'] if value_json['items'][0]['unit'] is not none }}
{# Otherwise, print just the food name #}
{% else %}
{{ value_json['items'][0]['food']['name'] }}
{% endif %}
- name: Mealie Shopping List Item To Delete
availability: >
{{ value_json['total'] }}
#Extract the ingredient's ID. Required to delete through the API later on.
value_template: >
{{ value_json['items'][0]['id'] }}
Then you need to update the mealie_delete_from_shopping_list
rest command to refer to the new sensor’s state, rather than the old sensor’s attribute:
rest_command:
#Command to delete a Mealing shopping list item
mealie_delete_from_shopping_list:
url: >
{{ url }}/{{ states('sensor.mealie_shopping_list_item_to_delete') }}
method: delete
headers:
Authorization: !secret mealie_api_token
And finally, update automation.mealie_update_rest_sensors
to include the new sensor in the homeassistant.update_entity
step:
automation:
#Automation to regularly refresh the "Mealie Shopping List Items" sensor
- id: mealie_update_rest_sensors
alias: "Mealie - Update Rest Sensors"
initial_state: "on"
trigger:
- platform: time_pattern
seconds: "/10" #How often do you want to check for updates in Mealie?
action:
- service: homeassistant.update_entity
data:
entity_id:
- sensor.mealie_shopping_list_items
- sensor.mealie_shopping_list_item_to_delete
Looks like this has done the trick for me to remove that log statement - hopefully it does the same for you!
TLDR - here’s the final complete configuration, which fixes the “JSON result was not a dictionary or list with 0th element a dictionary” log statement:
rest:
- resource_template: !secret mealie_shopping_items_api_endpoint
headers:
Authorization: !secret mealie_api_token
params:
perPage: 1
queryFilter: checked=false
orderBy: food.name
orderDirection: asc
sensor:
- name: Mealie Shopping List Items
availability: >
{{ value_json['total'] }}
#Sensor to view items which are on any Mealie shopping list
#Extract the ingredient data in the following format: "food - quantity unit" eg. "apples - 1.5 kilogram", or "Empty List" if no items are left in the list
value_template: >
{# If no items in list, return "Empty List" #}
{% if value_json['total'] == 0 %}
Empty List
{# If distinct food is not defined use display name instead #}
{% elif value_json['items'][0]['food'] == none %}
{{ value_json['items'][0]['display'] }}
{# If quantity is available, include it in the output #}
{% elif value_json['items'][0]['quantity'] > 0 %}
{{ value_json['items'][0]['food']['name'] }} - {{ (value_json['items'][0]['quantity'] | round(3) | string).rstrip('0').rstrip('.') }} {{ value_json['items'][0]['unit']['name'] if value_json['items'][0]['unit'] is not none }}
{# Otherwise, print just the food name #}
{% else %}
{{ value_json['items'][0]['food']['name'] }}
{% endif %}
- name: Mealie Shopping List Item To Delete
availability: >
{{ value_json['total'] }}
#Extract the ingredient's ID. Required to delete through the API later on.
value_template: >
{{ value_json['items'][0]['id'] }}
rest_command:
#Command to delete a Mealing shopping list item
mealie_delete_from_shopping_list:
url: >
{{ url }}/{{ states('sensor.mealie_shopping_list_item_to_delete') }}
method: delete
headers:
Authorization: !secret mealie_api_token
automation:
#Automation to regularly refresh the "Mealie Shopping List Items" sensor
- id: mealie_update_rest_sensors
alias: "Mealie - Update Rest Sensors"
initial_state: "on"
trigger:
- platform: time_pattern
seconds: "/10" #How often do you want to check for updates in Mealie?
action:
- service: homeassistant.update_entity
data:
entity_id:
- sensor.mealie_shopping_list_items
- sensor.mealie_shopping_list_item_to_delete
#Automation to transfer items from the Mealie shopping list to another list of your choice
- id: mealie_transfer_shopping_list
alias: "Mealie - Transfer Shopping List"
description: "When shopping list items are added to the Mealie shopping list, transfer them to an alternative list."
mode: queued
max: 10
initial_state: "on"
variables:
target_shopping_list: todo.groceries_list #CHANGEME: entity ID of your shopping list
notify_service: notify.mobile_app_michael_s_galaxy_s10 #CHANGEME: where to be notified if items fail to delete from Mealie shopping list
trigger:
- id: "regular_trigger"
platform: state
entity_id: sensor.mealie_shopping_list_items
- id: "fallback_trigger"
platform: time_pattern
minutes: "/10"
condition:
- condition: not
conditions:
- condition: state
entity_id: sensor.mealie_shopping_list_items
state: "Empty List"
action:
- alias: "Ensure shopping list item isn't now 'Empty List'"
condition: not
conditions:
- condition: state
entity_id: sensor.mealie_shopping_list_items
state: "Empty List"
- alias: "Add shopping list item to target list"
service: todo.add_item
target:
entity_id: "{{ target_shopping_list }}"
data:
item: "{{ states('sensor.mealie_shopping_list_items') }}"
description: Imported From Mealie
- alias: "Delete shopping list item from Mealie"
service: rest_command.mealie_delete_from_shopping_list
data:
url: !secret mealie_shopping_items_api_endpoint
response_variable: mealie_delete_response
- alias: "Notify if item failed to delete from Mealie"
if: "{{ mealie_delete_response['status'] != 200 }}"
then:
- service: "{{ notify_service }}"
data:
title: "Failed to delete item from Mealie list"
message: "{{ mealie_delete_response['content'] }}"
data:
notification_icon: "mdi:food-off"
- alias: "Refresh Mealie shopping list items sensor, in case more items need processing"
service: homeassistant.update_entity
data:
entity_id:
- sensor.mealie_shopping_list_items