Mealie in HA

i get the following fault : TodoStore.init() got an unexpected keyword argument ‘tzinfo’

I will be looking over something simple but i can’t see it :slight_smile:

edit: this error is in my logbook
“Template variable warning: ‘dict object’ has no attribute ‘total’ when rendering ‘{{ value_json[‘total’] }}’”

rest_command.yaml:

mealie_delete_from_shopping_list:
    url: >
      http://http://XXX/api/groups/shopping/items/{{ state_attr('sensor.mealie_shopping_list_items', 'id') }}?group_id=2bcf3b7e-520b-4ff3-beb5-615c80035db1 #group id is the preferred shopping list ID
    method: delete
    headers:
      Authorization: !secret mealie_api_token

rests.yaml:

- 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'] }}

automations:

alias: Mealie - Update Rest Sensors
description: ""
trigger:
  - platform: time_pattern
    seconds: /10
action:
  - service: homeassistant.update_entity
    data:
      entity_id:
        - sensor.mealie_shopping_list_items
initial_state: "on"
alias: Mealie - Transfer Shopping List
description: >-
  When shopping list items are added to the Mealie shopping list, transfer them
  to an alternative list.
trigger:
  - id: regular_trigger
    platform: state
    entity_id: sensor.mealie_shopping_list_items
  - id: fallback_trigger
    platform: time_pattern
    minutes: /1
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: todo.boodschappen
    data:
      item: "{{ states('sensor.mealie_shopping_list_items') }}"
  - alias: Delete shopping list item from Mealie
    service: rest_command.mealie_delete_from_shopping_list
    data:
      url: http://XXX/api/groups/shopping/items
    response_variable: mealie_delete_response
  - alias: Notify if item failed to delete from Mealie
    if:
      - condition: template
        value_template: "{{ 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
mode: queued
max: 10
initial_state: "on"
variables:
  target_shopping_list: todo.boodschappen
  notify_service: notify.mobile_appe_edi

I’m looking too for a method how to updat the todo shopping list in HA with the added items in the shopping list from Mealie

I’ve spent some time creating a Home Assistant integration for Mealie which provides the following

To-do lists
Mirrors your Mealie shopping lists.
Given that Home Assistant To-do items are more simplistic, if you edit a Mealie food item within Home Assistant it will be converted to a note type item within Mealie.

Calendar
Creates a Mealie calendar within Home Assistant, this is read only and creates appropriate time slots for breakfast, lunch and dinner

Sensors
Sensors for today’s breakfast, lunch, dinner and side are created for easy use on dashboards.

This is a very early beta release so looking for feedback (please raise issues within the ha mealie repo rather than here).
Be aware as it’s beta things could go wrong and shopping list items could be lost so use at own risk.

3 Likes

Cool. May I suggest a image entity for the next meal(s)?

1 Like

Nice idea, I’ve added it to the list.

1 Like

I’ve just added Images to the integration in the latest release, the readme gives some hints about using them conditionally.

1 Like

I’ve been using this in place of the sensors above - but adding meals to the meal planner doesn’t covert to the Mealie Shopping List well; one item moves then I get ‘unavailable’. Everything else is working like a dream but being able to auto add recipe items to the HA list (when added to the meal planner) would be a really big thing.

That’s strange, I just tried this myself by choosing a recipe, adding to the meal plan, then from the meal plan adding to a shopping list. HA-Mealie just syncs with Mealie’s list and it worked.
Can you check the list in Mealie is showing the items?
It’s not clear where the unavailable is being shown, is there anything in the HA logs?

1 Like

Ahh I think I was getting confused with another list I had setup - all working fine!

I’m using your integration and it’s working like a charm ! :slight_smile:
Would it be possible to have meal sensors for the next 7 days ?
So i can show the week menus in one lovelace card.

Thanks for your work !

Mealie provides an API for today only, doing a week’s worth of API calls would impact performance.
You can use a week planner card like this though as that doesn’t poll

1 Like

Any chance Mealie self-hosting addon will be added to Home Assistant’s official add-ons soon too?

Noticed still need to self-host it, but nice that integration will make it into next Home Assistant release:

It’s important to stress that my Mealie HACS custom integration is NOT the same as that which is going into the 2024.7 release.
That was developed separately by someone else and only has meal plan calendars.
Now I’ve seen this, I have reached out and am collaborating with the core dev to share what I’ve done and get it feature comparable but no timeline for when that will happen.

I’m also not involved in any Mealie Add-Ons, not my thing.

1 Like

There is an addon here. GitHub - alexbelgium/hassio-addons: My homeassistant addons

I created an (Node-RED) automation to check if I need to get something out of the freezer the evening before.
Maybe someone wants to use this automation also and can convert it to a HA automation, then you can use this as a reference.

1 Like

This is awsome!

Trying to get it to work except the sensors are not working there for i get the following error in node-red: “TypeError: Cannot read properties of undefined (reading ‘length’)”

This is what i see in the message box from that node:

if (msg.payload.items.length>0) {
    msg.recipeId = msg.payload.items[0].recipeId;
}
return msg;

This is what i have in my configuration.yaml

rest:
  - scan_interval: 3600
    resource: "http://192.168.****:9001/api/groups/mealplans?orderBy=date&orderDirection=asc"
    headers:
      Authorization: !secret mealie_bearer
    params:
      start_date: >
        {{ now().strftime('%Y-%m-%d') }}
    sensor:
      - name: "Mealie day0 name"
        value_template: "{{ value_json['items'][0].recipe.name }}"
        force_update: true
      - name: "Mealie day0 date"
        value_template: "{{ value_json['items'][0].date }}"
        force_update: true
      - name: "Mealie day1 name"
        value_template: "{{ value_json['items'][1].recipe.name }}"
        force_update: true
      - name: "Mealie day1 date"
        value_template: "{{ value_json['items'][1].date }}"
        force_update: true
      - name: "Mealie day2 name"
        value_template: "{{ value_json['items'][2].recipe.name }}"
        force_update: true
      - name: "Mealie day2 date"
        value_template: "{{ value_json['items'][2].date }}"
        force_update: true
      - name: "Mealie day3 name"
        value_template: "{{ value_json['items'][3].recipe.name }}"
        force_update: true
      - name: "Mealie day3 date"
        value_template: "{{ value_json['items'][3].date }}"
        force_update: true
      - name: "Mealie day4 name"
        value_template: "{{ value_json['items'][4].recipe.name }}"
        force_update: true
      - name: "Mealie day4 date"
        value_template: "{{ value_json['items'][4].date }}"
        force_update: true
      - name: "Mealie day5 name"
        value_template: "{{ value_json['items'][5].recipe.name }}"
        force_update: true
      - name: "Mealie day5 date"
        value_template: "{{ value_json['items'][5].date }}"
        force_update: true    
      - name: "Mealie day6 date"
        value_template: "{{ value_json['items'][6].date }}"
        force_update: true
      - name: "Mealie day6 name"
        value_template: "{{ value_json['items'][6].recipe.name }}"
        force_update: true

Are both flows not working at all. You need to setup in Home Assistant AND Node-RED the api properties right if you want to use both functionalities. HA to show it on your dashboard and Node-RED is only for the freezer check.

I tested myself first the api with Postman to find out if the ip-address, portnumber, token and response just works.
I had some issues with storing the token in the HA secret file so I moved that to the configuration.yaml

For Node-RED add debug-nodes behind each node to debug if it gives correct response or an error which you can use to solve it.

This is the first time a start up node red, so i have alot of learning to do, but will dive in heads first.
when i disable that node, i get the notification on my phone, so that part works :slight_smile:

As you suggested i placed the bearer token in de config file instead of the secret.yaml, but stil the sensors won’t show info, first will try to fix that.

Thank you for your reply :slight_smile:

edit: put a node in the mix and see onde error on the : get mealplan after now.
the error is : “{“detail”:“Could not validate credentials”}”.
so i have a direction to look

Hello,

Started to get this integration set up and have a question. While trying to get the weekly colander going, is there a way to change the calendar’s time for the meals? I don’t plan on using breakfast or lunch and only dinner and want that to show up as an all day event instead of a time slot. If not I can make due, but was wondering if there was a way. Thank and awesome job on this integration.

1 Like

Your suggestion to remove the !secret and put it the token directly into the config file got the rest sensors working and i can see what is planned this week.

Except for the nod-red part i’am using the debug nodes but i cannot figure out what they mean with the “TypeError: Cannot read properties of undefined (reading ‘length’)”.

I have no faults till the node “find tag from ingredients”

var recipe = msg.payload;

msg.payload = {};
msg.payload.recipe_name = recipe.name;
msg.payload.fridge = null;

var keyword = "freezer";
var tag = "[" + keyword +"]";
var freezerIngredients = Array(0);
for (let i = 0; i < recipe.recipeIngredient.length; i++) {
    var ingredient = recipe.recipeIngredient[i];
    if (ingredient.display.includes(tag)) {
        // remove tag and add to the array
         freezerIngredients.push(ingredient.display.replace(' '+ tag, ''));
    }
}
if (freezerIngredients.length > 0) {
    msg.payload.fridge = freezerIngredients.join(" and ");
}
return msg;

Edit: i figured it out.the second node “get mealplans after now” i got the same text as the first node with the same name, so in the second node i put in “api/recipes/{{{recipeId}}}” instead of “api/groups/mealplans?orderBy=date&orderDirection=asc&perPage=1&start_date={{{start_date}}}”

i looked at the link posted above and saw the flow explaination and decided to open a new flow and saw there was a difference :slight_smile:

1 Like