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 decided to use technology to make my life easier and help bring some efficiency to managing our household.
a quick note: I use separate files for my configuration.yaml to reference each of template, input_text, input_select, etc.
this means that my references will be in separate files entirely, rather than in my config.yaml. the entries in my config.yaml are:
input_select: !include input_selects.yaml
input_text: !include input_texts.yaml
script: !include scripts.yaml
sensor: !include sensors.yaml
template: !include templates.yaml
- Create the following input_select entries for each recipe you need:
##recipe input selects##
recipe_menu_name:
name: This is The Menu Item Name
options:
- "ingredient 1"
- "ingredient 2"
- "ingredient 3"
example:
Summary
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"
- Create a separate input_select to collate each recipe name, as a list to reference in all our next steps:
menu_options:
name: Weekly Dinner Menu Items
icon: mdi:silverware
options:
- "Initial"
- Create the following input_texts:
Summary
monday_menu:
name: Monday Menu
tuesday_menu:
name: Tuesday Menu
wednesday_menu:
name: Wednesday Menu
thursday_menu:
name: Thursday Menu
friday_menu:
name: Friday Menu
previous_monday_menu:
name: Previous Monday Menu
previous_tuesday_menu:
name: Previous Tuesday Menu
previous_wednesday_menu:
name: Previous Wednesday Menu
previous_thursday_menu:
name: Previous Thursday Menu
previous_friday_menu:
name: Previous Friday Menu
- Now that the baselines are created, we need scripts and automations to handle the updates. Create the following script entries, to allow both menu_options updates, as well as create a new menu each week:
Summary
update_menu_options:
sequence:
- service: input_select.set_options
target:
entity_id: input_select.menu_options
data:
options: >
{% set entities = states.input_select | selectattr('entity_id', 'search', 'input_select.recipe_') | list %}
{% set friendly_names = entities | map(attribute='attributes.friendly_name') | list %}
{{ friendly_names }}
assign_weekly_menu:
sequence:
# Update previous menu values
- service: input_text.set_value
target:
entity_id: input_text.previous_monday_menu
data:
value: '{{ states(''input_text.monday_menu'') }}'
- service: input_text.set_value
target:
entity_id: input_text.previous_tuesday_menu
data:
value: '{{ states(''input_text.tuesday_menu'') }}'
- service: input_text.set_value
target:
entity_id: input_text.previous_wednesday_menu
data:
value: '{{ states(''input_text.wednesday_menu'') }}'
- service: input_text.set_value
target:
entity_id: input_text.previous_thursday_menu
data:
value: '{{ states(''input_text.thursday_menu'') }}'
- service: input_text.set_value
target:
entity_id: input_text.previous_friday_menu
data:
value: '{{ states(''input_text.friday_menu'') }}'
# Assign new unique menu options
- variables:
options: '{{ state_attr(''input_select.menu_options'', ''options'') | list }}'
used_options: []
- service: input_text.set_value
target:
entity_id: input_text.monday_menu
data:
value: >-
{% set options = options | reject('equalto', states('input_text.previous_monday_menu')) | list %}
{% set monday_menu = options | random %}
{% set used_options = used_options + [monday_menu] %}
{{ monday_menu }}
- service: input_text.set_value
target:
entity_id: input_text.tuesday_menu
data:
value: >-
{% set options = options | reject('equalto', states('input_text.previous_tuesday_menu')) | reject('in', used_options) | list %}
{% set tuesday_menu = options | random %}
{% set used_options = used_options + [tuesday_menu] %}
{{ tuesday_menu }}
- service: input_text.set_value
target:
entity_id: input_text.wednesday_menu
data:
value: >-
{% set options = options | reject('equalto', states('input_text.previous_wednesday_menu')) | reject('in', used_options) | list %}
{% set wednesday_menu = options | random %}
{% set used_options = used_options + [wednesday_menu] %}
{{ wednesday_menu }}
- service: input_text.set_value
target:
entity_id: input_text.thursday_menu
data:
value: >-
{% set options = options | reject('equalto', states('input_text.previous_thursday_menu')) | reject('in', used_options) | list %}
{% set thursday_menu = options | random %}
{% set used_options = used_options + [thursday_menu] %}
{{ thursday_menu }}
- service: input_text.set_value
target:
entity_id: input_text.friday_menu
data:
value: >-
{% set options = options | reject('equalto', states('input_text.previous_friday_menu')) | reject('in', used_options) | list %}
{% set friday_menu = options | random %}
{{ friday_menu }}
- Next up, 2 entries in template.yaml:
Summary
- name: "Rotating Dinner Menu"
unique_id: updated_dinner_menu
state: "OK"
attributes:
Monday: >-
{% set mon = states('input_text.monday_menu') %}
{% set selection = states('input_select.monday_menu_manual') %}
{{ mon if selection == 'Placeholder' else selection }}
Tuesday: >-
{% set tue = states('input_text.tuesday_menu') %}
{% set selection = states('input_select.tuesday_menu_manual') %}
{{ tue if selection == 'Placeholder' else selection }}
Wednesday: >-
{% set wed = states('input_text.wednesday_menu') %}
{% set selection = states('input_select.wednesday_menu_manual') %}
{{ wed if selection == 'Placeholder' else selection }}
Thursday: >-
{% set thur = states('input_text.thursday_menu') %}
{% set selection = states('input_select.thursday_menu_manual') %}
{{ thur if selection == 'Placeholder' else selection }}
Friday: >-
{% set fri = states('input_text.friday_menu') %}
{% set selection = states('input_select.friday_menu_manual') %}
{{ fri if selection == 'Placeholder' else selection }}
- name: "Last Week's Dinner Menu"
unique_id: last_week_menu
state: "OK"
attributes:
Monday: "{{states('input_text.previous_monday_menu')}}"
Tuesday: "{{states('input_text.previous_tuesday_menu')}}"
Wednesday: "{{states('input_text.previous_wednesday_menu')}}"
Thursday: "{{states('input_text.previous_thursday_menu')}}"
Friday: "{{states('input_text.previous_friday_menu')}}"
- Finally, create an automation to update the menu items each week, as well as reflect the week change each iteration.
With all these configurations, you are able to work with an auto-update menu.
Next section to tackle: the grocery list based off each menu item.
scripts.yaml entry:
Summary
add_to_shopping_list:
alias: Shopping List additions
sequence:
- variables:
days: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday']
item_counts: {}
- repeat:
count: "{{ days | length }}"
sequence:
- variables:
day: "{{ days[repeat.index - 1] }}"
menu: "{{ state_attr('sensor.rotating_dinner_menu', day) }}"
entity_id: >
{% set entities = states.input_select | selectattr('entity_id', 'search', 'input_select.recipe_') | list %}
{% set entity = entities | selectattr('attributes.friendly_name', 'equalto', menu) | first %}
{{ entity.entity_id if entity else 'none' }}
options: >
{% if entity_id != 'none' %}
{{ state_attr(entity_id, 'options') | list }}
{% 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 %}
Modify your automation to perform the script action after the menu is updated each weekly iteration.
I’m currently working out the learning curve on creation of a blueprint. More to come!