Interactive Shopping List using the new ask_question action

Hi All,

I have created a interactive shopping list automation that uses the new ask_question action. This is my first attempt at the shopping list. I think this will work for any satellite device. But, I’m using faster whisper via a GPU. There are some restrictions, one Voice PE per area is supported and if you remove any item from the shopping list that does not exist, the automation aborts. First create your stores using the todo entities. I have created mine using the "our groceries " integration. For example, todo.walmart, todo.kroger.

You start by saying either:

  • Edit store_name shopping list
  • Manage store_name shopping list
  • update store_name shopping list

For example, edit kroger shopping list.

You can interactively say the following, until you quit:
add item
remove or delete item
list or list the items or read the list
exit or done or quit

For example, add apples, delete pizza, list

alias: Shopping List Conversation
description: >-
  Uses a refined conversational flow to manage a store-specific shopping list
  from any voice satellite, with responses sent to the originating device.
triggers:
  - command:
      - update {store_name} shopping list
      - edit {store_name} shopping list
      - manage {store_name} shopping list
    trigger: conversation
actions:
  - variables:
      store_name: "{{ trigger.slots.store_name | lower }}"
      shopping_list_entity: todo.{{ store_name }}
      user_action: not_done
  - action: assist_satellite.ask_question
    data:
      question: >-
        You can Add, remove, or list items? from the {{ store_name }} shopping
        list. What would you like to do
      answers:
        - id: add
          sentences:
            - add {item}
            - and {item}
            - add an item {item}
        - id: remove
          sentences:
            - remove {item}
            - delete {item}
        - id: list
          sentences:
            - list the items
            - what's on the list
            - read the list
            - list
        - id: done
          sentences:
            - done
            - I'm done
            - quit
            - that's it
            - exit
            - get me out of here
      preannounce: false
      entity_id: >-
        {{ expand(states.assist_satellite) |selectattr('entity_id', 'in',
        area_entities(area_name(trigger.device_id))) 
        |map(attribute='entity_id')    |list| join(',') }}
    response_variable: user_action
  - repeat:
      sequence:
        - choose:
            - conditions:
                - condition: template
                  value_template: "{{ user_action.id == 'add' }}"
              sequence:
                - target:
                    device_id: "{{ trigger.device_id }}"
                  data:
                    message: Added {{ user_action.slots.item }}.
                    preannounce: false
                  action: assist_satellite.announce
                - target:
                    entity_id: "{{ shopping_list_entity }}"
                  data:
                    item: "{{ user_action.slots.item }}"
                  action: todo.add_item
            - conditions:
                - condition: template
                  value_template: "{{ user_action.id == 'remove' }}"
              sequence:
                - target:
                    device_id: "{{ trigger.device_id }}"
                  data:
                    message: Removed {{ user_action.slots.item }}.
                    preannounce: false
                  action: assist_satellite.announce
                - target:
                    entity_id: "{{ shopping_list_entity }}"
                  data:
                    item: "{{ user_action.slots.item }}"
                  action: todo.remove_item
            - conditions:
                - condition: template
                  value_template: "{{ user_action.id == 'list' }}"
              sequence:
                - target:
                    entity_id: "{{ shopping_list_entity }}"
                  response_variable: shopping_list_items
                  action: todo.get_items
                  data:
                    status: needs_action
                - choose:
                    - conditions:
                        - condition: template
                          value_template: >-
                            {% set items =
                            shopping_list_items[shopping_list_entity]['items'] |
                            map(attribute='summary') | list %} {{ items | count
                            > 0 }}
                      sequence:
                        - target:
                            device_id: "{{ trigger.device_id }}"
                          data:
                            message: "On the {{ store_name }} list, you have:"
                            preannounce: false
                          action: assist_satellite.announce
                        - delay:
                            milliseconds: 80
                        - repeat:
                            for_each: >-
                              {% set items =
                              shopping_list_items[shopping_list_entity]['items']
                              | map(attribute='summary') | list  %} {{ items }}
                            sequence:
                              - target:
                                  device_id: "{{ trigger.device_id }}"
                                data:
                                  message: "{{ repeat.item }}"
                                  preannounce: false
                                action: assist_satellite.announce
                              - delay:
                                  milliseconds: 80
                  default:
                    - target:
                        device_id: "{{ trigger.device_id }}"
                      data:
                        message: The {{ store_name }} shopping list is empty.
                        preannounce: false
                      action: assist_satellite.announce
        - action: assist_satellite.ask_question
          data:
            question: Next Item?
            answers:
              - id: add
                sentences:
                  - add {item}
                  - and {item}
                  - add an item {item}
              - id: remove
                sentences:
                  - remove {item}
                  - delete {item}
              - id: list
                sentences:
                  - list the items
                  - what's on the list
                  - read the list
                  - list
              - id: done
                sentences:
                  - done
                  - I'm done
                  - quit
                  - that's it
                  - exit
                  - get me out of here
            preannounce: false
            entity_id: >-
              {{ expand(states.assist_satellite) |selectattr('entity_id', 'in',
              area_entities(area_name(trigger.device_id))) 
              |map(attribute='entity_id')    |list| join(',')
              }}                  
          response_variable: user_action
      while:
        - condition: template
          value_template: "{{ user_action.id != 'done' }}"
  - target:
      device_id: "{{ trigger.device_id }}"
    data:
      message: Okay, your {{ store_name }} shopping list is all set.
      preannounce: false
    action: assist_satellite.announce
mode: single

2 Likes

I have found a problem with the interactive shopping list. If I used a shopping list with two words, like Home Depot. It does not wok, investigating. I can use lists under the custom_sentences folder, but I would have to convert the automation above to a script.
For example, home depot, would be:

lists:
  store_name:
    values:
      - in: "(home depot)"
        out: "todo.home_depot"

Any ideas?

Wow!? No response to my issue. I guess there’s little interest to the shopping.

So, I figure out how to fix the issue where the store name is two words, like home depot. replace any spaces, to “_”.

Change the variable line, store name, to the following:

store_name: “{{ trigger.slots.store_name | lower | replace(’ ', ‘_’) }}”

Hey Kevin,
just spent 1 hour building something similar using the Anylist antegration to bulk add items. Just found your post afterwards :smiley:

I’m still having some weird delay issues after the last item before the final announcement, I will try to check with your script, maybe I can find the bug in my version. Thanks for posting!

Updated the shopping list automation to announce if you said a command that the Voice Entity did not understand.

alias: Shopping List Conversation
description: >-
  Uses a refined conversational flow to manage a store-specific shopping list
  from any voice satellite, with responses sent to the originating device.
triggers:
  - command:
      - update {store_name} shopping list
      - updated {store_name} shopping list
      - edit {store_name} shopping list
      - manage {store_name} shopping list
      - update {store_name} list
      - updated {store_name} list
      - edit {store_name} list
      - manage {store_name} list
    trigger: conversation
actions:
  - variables:
      store_name: "{{ trigger.slots.store_name | lower | replace(' ', '_') }}"
      shopping_list_entity: todo.{{ store_name }}
      user_action: not_done
  - action: assist_satellite.ask_question
    data:
      question: >-
        You can Add, remove, or list items? from the {{ store_name }} shopping
        list. What would you like to do
      answers:
        - id: add
          sentences:
            - add {item}
            - and {item}
            - add an item {item}
        - id: remove
          sentences:
            - remove {item}
            - delete {item}
        - id: list
          sentences:
            - list the items
            - what's on the list
            - read the list
            - list
        - id: done
          sentences:
            - done
            - I'm done
            - quit
            - that's it
            - exit
            - get me out of here
            - stop
      preannounce: false
      entity_id: >-
        {{ expand(states.assist_satellite) |selectattr('entity_id', 'in',
        area_entities(area_name(trigger.device_id))) 
        |map(attribute='entity_id')    |list| join(',') }}
    response_variable: user_action
  - repeat:
      sequence:
        - choose:     
            - conditions:
                - condition: template
                  value_template: "{{ user_action.id == 'add' }}"
              sequence:
                - target:
                    device_id: "{{ trigger.device_id }}"
                  data:
                    message: Added {{ user_action.slots.item }}.
                    preannounce: false
                  action: assist_satellite.announce
                - target:
                    entity_id: "{{ shopping_list_entity }}"
                  data:
                    item: "{{ user_action.slots.item }}"
                  action: todo.add_item
            - conditions:
                - condition: template
                  value_template: "{{ user_action.id == 'remove' }}"
              sequence:
                - target:
                    device_id: "{{ trigger.device_id }}"
                  data:
                    message: Removed {{ user_action.slots.item }}.
                    preannounce: false
                  action: assist_satellite.announce
                - target:
                    entity_id: "{{ shopping_list_entity }}"
                  data:
                    item: "{{ user_action.slots.item }}"
                  action: todo.remove_item

            - conditions:
                - condition: template
                  value_template: "{{ user_action.id == 'list' }}"
              sequence:
                - target:
                    entity_id: "{{ shopping_list_entity }}"
                  response_variable: shopping_list_items
                  action: todo.get_items
                  data:
                    status: needs_action
                - choose:
                    - conditions:
                        - condition: template
                          value_template: >-
                            {% set items =
                            shopping_list_items[shopping_list_entity]['items'] |
                            map(attribute='summary') | list %} {{ items | count
                            > 0 }}
                      sequence:
                        - target:
                            device_id: "{{ trigger.device_id }}"
                          data:
                            message: "On the {{ store_name }} list, you have:"
                            preannounce: false
                          action: assist_satellite.announce
                        - delay:
                            milliseconds: 80
                        - repeat:
                            for_each: >-
                              {% set items =
                              shopping_list_items[shopping_list_entity]['items']
                              | map(attribute='summary') | list  %} {{ items }}
                            sequence:
                              - target:
                                  device_id: "{{ trigger.device_id }}"
                                data:
                                  message: "{{ repeat.item }}"
                                  preannounce: false
                                action: assist_satellite.announce
                              - delay:
                                  milliseconds: 80
                  default:
                    - target:
                        device_id: "{{ trigger.device_id }}"
                      data:
                        message: The {{ store_name }} shopping list is empty.
                        preannounce: false
                      action: assist_satellite.announce
          default:
            - action: assist_satellite.announce
              target:
                device_id: "{{ trigger.device_id }}"
              metadata: {}
              data:
                message: I didn't understand, use commands add, remove, list, or quit
                preannounce: false
        - action: assist_satellite.ask_question
          data:
            question: Next Item?
            answers:
              - id: add
                sentences:
                  - add {item}
                  - and {item}
                  - add an item {item}
              - id: remove
                sentences:
                  - remove {item}
                  - delete {item}
              - id: list
                sentences:
                  - list the items
                  - what's on the list
                  - read the list
                  - list
              - id: done
                sentences:
                  - done
                  - I'm done
                  - quit
                  - that's it
                  - exit
                  - stop
                  - get me outta here
            preannounce: false
            entity_id: >-
              {{ expand(states.assist_satellite) |selectattr('entity_id', 'in',
              area_entities(area_name(trigger.device_id))) 
              |map(attribute='entity_id')    |list| join(',')
              }}                  
          response_variable: user_action
      while:
        - condition: template
          value_template: "{{ user_action.id != 'done' }}"
  - target:
      device_id: "{{ trigger.device_id }}"
    data:
      message: Okay, your {{ store_name }} shopping list is all set.
      preannounce: false
    action: assist_satellite.announce
mode: single

Hi,

Thxs for the reply!!! I have made updates to the interactive shopping list.
I hope some folks find it useful, and make improvements.

I don’t see the anylist integration. Where can I find it?

Kevin