Weekly Dinner menu choices, auto-rotating, with random selection
I got extremely tired of the mental load of picking menu options for my family’s dinners, creating a grocery list, and then repeating this for every evening until i perish.
I am using Home Assistant’s capabilities for a to-do list to create a grocery list, as well as menu for each week.
I chose to create 4 dinners here, but you can certainly add more.
I have yet to figure out how to create a list to avoid weekly repeats, but will update when I’ve solved that portion.
Here is a list of the steps I performed, with examples below of each step:
- Create input_select sensors for each recipe I’ll use in the menu options list.
- Create a menu list from each of the recipe input_select sensors.
- Create a menu selection from random picks of the menu list.
- Create a schedule for the menu selection to update.
- Create a script to clear previous ingredient lists from the prior week, and create new entries based off the new menu selections after they’ve been updated.
- Create an entry into your configuration.yaml, as well as a custom folder for the python script to properly function.
- Create an automation based off the schedule trigger in step 4, that uses the script in step 5 targeting the grocery list entity.
- Create the following input_select entries:
in input_select.yaml:
##recipe input selects##
recipe_menu_name:
name: This is The Menu Item Name
options:
- "ingredient 1"
- "ingredient 2"
- "ingredient 3"
example:
recipe_tuna_salad:
name: Tuna salad
options:
- "2 cans tuna"
- "6 eggs"
- "mayonnaise"
- "yellow mustard"
- "sweet relish"
- "onion powder"
- "garlic powder"
- "smoked paprika"
- "black pepper"
recipe_shepherds_pie:
name: Shepherds pie
options:
- "2 lbs ground beef"
- "1 bag frozen mixed vegetables"
- "mushroom broth"
- "cascade mushroom mix"
- "6 russet potatoes"
- "4 tbsp butter"
- Once all recipes are added into unique input select items, create a new input select sensor with the following options:
##menu options for dinners##
menu_options:
name: Weekly Dinner Menu Items
icon: mdi:silverware
options:
- "Name exactly as the friendly name is displayed for each input_select"
example:
##menu options for dinners##
menu_options:
name: Weekly Dinner Menu Items
icon: mdi:silverware
options:
- "Tuna salad"
- "Shepherd's pie"
- "Chicken pot pie"
- Then, create a sensor under template.yaml to randomly select the menu options from your initially created input_selects:
##Dinner Menu Items
- name: updated_dinner_menu
unique_id: updated_dinner_menu
state: "OK"
attributes:
Monday: >
{% set menu = state_attr('input_select.menu_options','options')|list |random %}
{{menu}}
Tuesday: >
{% set menu2 = state_attr('input_select.menu_options','options')|list |random %}
{% for menu2 in 'attributes.sensor.updated_dinner_menu' |rejectattr(menu) %}
{%endfor%}
{{menu2}}
Wednesday: >
{% set menu3 = state_attr('input_select.menu_options','options')|list |random %}
{% for menu3 in 'attributes.sensor.updated_dinner_menu' |rejectattr(menu) |rejectattr(menu2) %}
{%endfor%}
{{menu3}}
Thursday: >
{% set menu4 = state_attr('input_select.menu_options','options')|list |random %}
{% for menu4 in 'attributes.sensor.updated_dinner_menu' |rejectattr(menu) | rejectattr(menu2) | rejectattr(menu3) %}
{%endfor%}
{{menu4}}
-
Navigate to Settings>Devices & Services>Helpers, and create a Schedule Helper:
Name: Dinner Menu Update
Entity ID: schedule.dinner_menu_update
Event is set to reset every Saturday at 12:00AM. You can customize this portion to refresh whenever you need. -
Create an entry in scripts.yaml with the below details. You’ll need to customize days and entities to add your specific entries:
Example:
add_to_shopping_list:
alias: Shopping List additions
sequence:
- variables:
days: ['add your day options here from your updated menu selection options','each entry will be a unique single quotation']
item_counts: {}
- repeat:
count: "{{ days | length }}"
sequence:
- variables:
day: "{{ days[repeat.index - 1] }}"
menu: "{{ state_attr('sensor.updated_dinner_menu', day) }}"
entity_id: >
{% set entities = 'comma separated values for each recipe input_select entity' %}
{% set entityList = entities.split(",") %}
{% set querymatch = entityList | map('state_attr', 'friendly_name') | list %}
{% set matchers = querymatch | select('search', menu) | list %}
{% if matchers %}
{{ entityList[querymatch.index(matchers[0])] }}
{% else %}
none
{% endif %}
options: >
{% if entity_id != 'none' %}
{{ state_attr(entity_id, 'options') }}
{% else %}
[]
{% endif %}
- repeat:
count: "{{ options | length }}"
sequence:
- variables:
item: "{{ options[repeat.index - 1] }}"
count: "{{ item_counts[item] | default(0) + 1 }}"
- service: python_script.update_item_counts
data:
item: "{{ item }}"
count: "{{ count }}"
- service: shopping_list.add_item
data:
name: >
{% if count > 1 %}
{{ count }}x {{ item }}
{% else %}
{{ item }}
{% endif %}
`
` ##Query to add ingredients from dynamic menu items, to grocery list. automation clears all items and adds refreshed items##
add_to_shopping_list:
alias: Shopping List additions
sequence:
- variables:
days: ['Monday', 'Tuesday', 'Wednesday', 'Thursday']
item_counts: {}
- repeat:
count: "{{ days | length }}"
sequence:
- variables:
day: "{{ days[repeat.index - 1] }}"
menu: "{{ state_attr('sensor.updated_dinner_menu', day) }}"
entity_id: >
{% set entities = 'input_select.recipe_tuna_salad,input_select.recipe_shepherds_pie,input_select.recipe_chicken_pot_pie,input_select.recipe_enchilada_casserole,input_select.recipe_spaghetti,input_select.recipe_sausage_and_cabbage,input_select.recipe_breakfast_burrito,input_select.recipe_steak_fingers,input_select.recipe_chicken_nuggets,input_select.recipe_waffles,input_select.recipe_fried_rice,input_select.recipe_pork_chops,input_select.recipe_stroganoff,input_select.recipe_risotto,input_select.recipe_butternut_squash_soup,input_select.recipe_chicken_and_dumplings,input_select.recipe_hamburgers,input_select.recipe_chili,input_select.recipe_taco_salad,input_select.recipe_pot_roast,input_select.recipe_chicken_fried_steak,input_select.recipe_loaded_nachos,input_select.recipe_eggs_biscuits_and_gravy,input_select.recipe_ravioli,input_select.recipe_quesadillas,input_select.recipe_pizza,input_select.recipe_parmesan_chicken,input_select.recipe_salmon_caesar_salad,input_select.recipe_manicotti,input_select.recipe_pan_fried_chicken_thighs,input_select.recipe_meatloaf,input_select.recipe_green_pea_falafel,input_select.recipe_baked_potatoes,input_select.recipe_pulled_pork,input_select.recipe_pork_tenderloin,input_select.recipe_teriyaki_steak' %}
{% set entityList = entities.split(",") %}
{% set querymatch = entityList | map('state_attr', 'friendly_name') | list %}
{% set matchers = querymatch | select('search', menu) | list %}
{% if matchers %}
{{ entityList[querymatch.index(matchers[0])] }}
{% else %}
none
{% endif %}
options: >
{% if entity_id != 'none' %}
{{ state_attr(entity_id, 'options') }}
{% else %}
[]
{% endif %}
- repeat:
count: "{{ options | length }}"
sequence:
- variables:
item: "{{ options[repeat.index - 1] }}"
count: "{{ item_counts[item] | default(0) + 1 }}"
- service: python_script.update_item_counts
data:
item: "{{ item }}"
count: "{{ count }}"
- service: shopping_list.add_item
data:
name: >
{% if count > 1 %}
{{ count }}x {{ item }}
{% else %}
{{ item }}
{% endif %}
- Create the following entry into your configuration.yaml:
python_script:
Then, create a folder under HASS’s root config folder, named python_scripts. Add a file named update_item_counts.py with the following contents:
item = data.get('item')
count = data.get('count')
item_counts = hass.states.get('script.add_to_shopping_list').attributes.get('item_counts')
item_counts[item] = count
hass.states.set('script.add_to_shopping_list', 'running', {'item_counts': item_counts})
- Finally, create an automation based off all these components with the following config. Navigate to Settings>Automations & Scenes>Automations. Create:
Event Trigger: Entity: Dinner Menu Update
Attribute Next Event changes
Then Do:
Shopping List"Complete All"
Shopping List “Clear completed Items”
Script ‘Shopping list additions’
Save and name your automation.
For my instance, I created a page view in the dashboard to centralize my outputted dinner items, as well as my ingredients added to the list.
Entities Card Congifuration:
entity: sensor.updated_dinner_menu
type: attribute
attribute: Monday
entity: sensor.updated_dinner_menu
type: attribute
attribute: Tuesday
entity: sensor.updated_dinner_menu
type: attribute
attribute: Wednesday
entity: sensor.updated_dinner_menu
type: attribute
attribute: Thursday
To-Do List card configuration:
Entity: Shopping List
And, that’s all! I’ve found a good amount of success here.
Known limitations in this config:
I haven’t yet created a “re-roll” button in case there’s a duplicate of last week’s menu items. More to come, there.
I have not integrated this to any additional automations to add grocery list ingredients to external add-ins. YMMV here.