Label-based Zone & List Notifications

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

Replaces this, which I cannot yet edit.

This takes a person and device and uses labels to provide app notifications when the person enters a zone that shares a label with a to-do list, e.g., a shopping list at a grocery store. But it’s much more (see comments).

V1 note: Secondary notifications don’t automatically clear, working on that for v1.1, plus adding more control over secondary notifications. It works, but it’s noisier than I’d like.

blueprint:
  name: "Label-Based Zone List Notifications" #v1.0
  description: >
    Notifies a tracked person when they arrive at a zone whose label
    matches a to-do list's label, with a dynamic per-zone dashboard,
    live updates while shopping, and departure/welcome-home reminders.
    The dynamic dashboard feature (level 2) requires auto-entries and browser-mod.
  domain: automation
  homeassistant:
    min_version: "2026.7.0"

  input:
    # --- LEVEL 1: Basics ---
    level_1:
      name: "Level 1: Basic Configuration"
      icon: mdi:numeric-1-box
      collapsed: false
      input:
        person_target:
          name: Target Person
          description: >
            The specific person entity the automation will track.
          selector:
            entity:
              domain: person

        notify_device:
          name: Notification Device
          description: >
            The mobile device for primary notifications.
          selector:
            device:
              integration: mobile_app

        enable_exit_reminders:
          name: Enable Exit & Home Reminders (Optional)
          description: >
            Toggle to enable the 1-item departure prompt and the
            'Welcome Home' reminder.
          default: false
          selector:
            boolean:

    # --- LEVEL 2: Dashboard ---
    level_2:
      name: "Level 2: Dynamic Dashboard"
      icon: mdi:numeric-2-box
      collapsed: true
      description: |
        This automation only sends notifications and populates the Text
        Helper below - the actual dashboard view that displays the list
        is a separate Lovelace view you create yourself, on any
        dashboard you like. Add it as a new view, filling in:
        - `[[YOUR PATH HERE]]` with this view's own path
        - `[[YOUR HELPER HERE]]` with the Text Helper's entity_id
          (without the `input_text.` prefix)
        - `[[YOUR LIST DASHBOARD HERE]]` with a link to wherever you
          keep the full, unfiltered list(s) (shown when nothing matches)

        The Refresh button uses the `browser_mod` HACS integration -
        drop that card if you don't have it installed.

        ```yaml
        views:
          - type: panel
            path: [[YOUR PATH HERE]]
            title: Lists
            icon: mdi:list-box-outline
            cards:
              - type: custom:auto-entities
                card:
                  type: vertical-stack
                card_param: cards
                filter:
                  template: >
                    {% set raw = states('input_text.[[YOUR HELPER HERE]]') %} {% set ns =
                    namespace(cards=[]) %}

                    {% if raw not in ['unknown', 'unavailable', 'none', ''] %}
                      {% for entity in raw.split(',') | map('trim') | reject('eq', '') | list %}
                        {% if entity.startswith('todo.')
                            and states(entity) not in ['unknown', 'unavailable']
                            and states(entity) | int(0) > 0 %}
                          {% set ns.cards = ns.cards + [{
                            'type': 'todo-list',
                            'entity': entity,
                            'hide_completed': true,
                            'hide_section_headers': true
                          }] %}
                        {% endif %}
                      {% endfor %}
                    {% endif %}

                    {{ ns.cards }}
                else:
                  type: vertical-stack
                  cards:
                    - type: markdown
                      content: >
                        You are either not at a labeled area or there is nothing on the
                        list(s). Click <a href="[[YOUR LIST DASHBOARD HERE]]">here</a>
                        to see all the lists available.
                    - type: button
                      name: Refresh
                      icon: mdi:refresh
                      tap_action:
                        action: perform-action
                        perform_action: browser_mod.refresh
                        data:
                          browser_id: this
        ```

        Once created, that view's URL is what goes in "Dynamic List
        Dashboard (Zone-Specific)" below.
      input:
        dashboard_helper:
          name: Dashboard Text Helper (Optional)
          description: >
            To create a dashboard that automatically populates when you
            arrive and clears when you leave, provide a Text Helper
            (input_text).
          default: ""
          selector:
            entity:
              domain: input_text

        dashboard_link:
          name: Dashboard Link (General, Optional)
          description: >
            Used only by the "Welcome Home" reminder after you've left a
            zone: a link to your general/all-lists dashboard, since you're
            no longer at a specific zone by that point.
          default: ""
          selector:
            text:

        dynamic_list_dashboard:
          name: Dynamic List Dashboard (Zone-Specific, Optional)
          description: >
            Used by arrival and live-update notifications while you're
            still at the zone: a link to the dashboard view that shows
            just the list(s) matching your current zone.
          default: ""
          selector:
            text:

    # --- ADVANCED OPTIONS ---
    advanced_options:
      name: "Advanced Options"
      icon: mdi:cog-outline
      collapsed: true
      input:
        zone_label:
          name: Limit to these labels... (Optional)
          description: >
            Optionally select a label to restrict the automation. Leave blank
            to use all labels when zone and list labels match.
          default: ""
          selector:
            label:

        secondary_notify_device:
          name: Secondary Notification Target (Optional)
          description: >
            Optionally notify another person when the tracked person
            arrives at a labeled zone. NOTE: unlike the primary
            notification, this one is a plain message only (no sticky
            persistence, no "Open Lists" button) - the mechanism that
            supports those extras can't safely target an optional
            device without risking a blank value breaking automation
            setup entirely.
          default: ""
          selector:
            entity:
              filter:
                domain: notify
                integration: mobile_app

        live_update_delay:
          name: Live Update Delay (Optional)
          description: >
            Time to wait before batching list updates. If someone else
            (or Alexa) checks off an item while you are at the store, the
            automation waits for this batching window to close, then silently
            updates your lock screen notification with the new list.
          default: 20
          selector:
            number:
              min: 1
              max: 300
              step: 1
              unit_of_measurement: seconds
              mode: box

        zone_departure_timeout:
          name: Zone Departure Timeout (Optional)
          description: >
            Maximum time to wait for departure from the zone.
          default: 4
          selector:
            number:
              min: 1
              max: 24
              step: 1
              unit_of_measurement: hours
              mode: box

        home_arrival_timeout:
          name: Welcome Home Timeout (Optional)
          description: >
            Maximum time after departure to wait for a return home.
          default: 9
          selector:
            number:
              min: 1
              max: 24
              step: 1
              unit_of_measurement: hours
              mode: box

variables:
  person_entity: !input person_target
  person_user_id: "{{ state_attr(person_entity, 'user_id') }}"
  zone_label_input: !input zone_label
  dashboard_helper: !input dashboard_helper
  dashboard_link: !input dashboard_link
  dynamic_list_dashboard: !input dynamic_list_dashboard
  enable_reminders: !input enable_exit_reminders

  # Primary uses !input notify_device directly as a device_id in the
  # device actions below (device: selector, required so it's never
  # blank). Device actions need an explicit `actions: []` on every step
  # that doesn't use real action buttons - HA rejects a step where that
  # key is simply absent.
  #
  # Secondary is deliberately scoped down: being optional, it can't use
  # the device-action format at all (an empty device_id breaks blueprint
  # setup even when guarded by a runtime "if" - the check happens at
  # config-generation time, not runtime). notify.send_message is used
  # instead, since its target.entity_id is evaluated at runtime rather
  # than substituted statically - but that action's schema only accepts
  # message/title, no platform-specific extras (tag/sticky/actionable
  # buttons), so secondary trades those away for reliability. Full
  # parity would need the legacy per-device notify service instead, but
  # that service's name isn't reliably derivable from any selector value
  # (it's fixed at the device's original registration and doesn't track
  # later renames) - only a free-text field can supply it correctly.
  secondary_notify_device: !input secondary_notify_device

  live_update_delay_seconds: !input live_update_delay
  zone_departure_timeout_hours: !input zone_departure_timeout
  home_arrival_timeout_hours: !input home_arrival_timeout

mode: parallel
max: 10

triggers:
  - trigger: state
    entity_id: !input person_target
    not_to:
      - "unknown"
      - "unavailable"
      - "not_home"
      - "home"
    id: "zone_arrival"

  # Leaving home is a natural "fresh start" point: clear any stale
  # notification from a prior visit that's still sitting on the phone
  # (e.g. one whose Path 2 run never got to its own cleanup - departure
  # timeout, HA restart mid-run, etc).
  - trigger: state
    entity_id: !input person_target
    to: "not_home"
    id: "left_home"

  # Only To-do actions which modify a list are monitored.
  - trigger: event
    event_type: call_service
    event_data:
      domain: todo
      service: add_item
    id: "live_update"

  - trigger: event
    event_type: call_service
    event_data:
      domain: todo
      service: update_item
    id: "live_update"

  - trigger: event
    event_type: call_service
    event_data:
      domain: todo
      service: remove_item
    id: "live_update"

  - trigger: event
    event_type: call_service
    event_data:
      domain: todo
      service: remove_completed_items
    id: "live_update"

actions:
  - choose:

      # ==========================================
      # PATH 1: LIVE UPDATES
      # ==========================================
      - conditions:
          - condition: trigger
            id: "live_update"

          # Ignore changes made by the tracked person.
          - condition: template
            value_template: >
              {{ trigger.event.context.user_id != person_user_id }}

          - condition: template
            value_template: >
              {{ dashboard_helper | string | trim != ''
                 and states(dashboard_helper)
                 not in ['unknown', 'unavailable', 'none', ''] }}

        sequence:
          - delay:
              seconds: "{{ live_update_delay_seconds | int(20) }}"

          - condition: template
            value_template: >
              {{ states(dashboard_helper)
                 not in ['unknown', 'unavailable', 'none', ''] }}

          - variables:
              active_lists: >
                {{ states(dashboard_helper).split(',')
                   | map('trim')
                   | reject('eq', '')
                   | list }}

          - condition: template
            value_template: >
              {{ active_lists | length > 0 }}

          - action: todo.get_items
            target:
              entity_id: "{{ active_lists }}"
            data:
              status: "needs_action"
            response_variable: batch_items

          - variables:
              updated_text: >
                {% set ns = namespace(items=[]) %}
                {% for list_id, list_data in batch_items.items() %}
                  {% for item in list_data.get('items', []) %}
                    {% set ns.items = ns.items + ['- ' ~ item.summary] %}
                  {% endfor %}
                {% endfor %}
                Someone updated the list. Here is the updated list:

                {{ ns.items | join('\n') }}

          - choose:
              - conditions:
                  - condition: template
                    value_template: >
                      {{ dynamic_list_dashboard | trim != '' }}
                sequence:
                  - device_id: !input notify_device
                    domain: mobile_app
                    type: notify
                    message: "{{ updated_text }}"
                    data:
                      tag: "zone_list_notification"
                      sticky: true
                      actions:
                        - action: "URI"
                          title: "Open Lists"
                          uri: "{{ dynamic_list_dashboard }}"

            default:
              - device_id: !input notify_device
                domain: mobile_app
                type: notify
                message: "{{ updated_text }}"
                data:
                  tag: "zone_list_notification"
                  sticky: true
                  actions: []

      # ==========================================
      # LEFT HOME: CLEAR ANY STALE NOTIFICATION
      #
      # Catches cases where a prior visit's own cleanup never ran (e.g.
      # the departure wait hit its timeout and gave up, or HA restarted
      # mid-run) - leaving home is a clean, unambiguous point to make
      # sure nothing from this automation is still sitting on the phone.
      # ==========================================
      - conditions:
          - condition: trigger
            id: "left_home"

        sequence:
          - device_id: !input notify_device
            domain: mobile_app
            type: notify
            message: "clear_notification"
            data:
              tag: "zone_list_notification"
              actions: []

      # ==========================================
      # PATH 2: ARRIVAL -> DEPARTURE -> HOME
      # ==========================================
      - conditions:
          - condition: trigger
            id: "zone_arrival"

        sequence:
          - variables:
              arrival_zone_state: "{{ trigger.to_state.state }}"

              # HA 2026 zone tracking exposes the actual zone entity/entities
              # in the Person's in_zones attribute.
              zone_entity: >
                {% set zones = state_attr(person_entity, 'in_zones') %}
                {% if zones and zones | length > 0 %}
                  {{ zones[0] }}
                {% else %}
                  none
                {% endif %}

          - condition: template
            value_template: >
              {{ zone_entity != 'none' }}

          - variables:
              matching_labels: >
                {% set zone_labels = labels(zone_entity) | list %}
                {% if zone_label_input | trim != '' %}
                  {{ [zone_label_input]
                     if zone_label_input in zone_labels
                     else [] }}
                {% else %}
                  {{ zone_labels }}
                {% endif %}

          - condition: template
            value_template: >
              {{ matching_labels | length > 0 }}

          - variables:
              target_lists: >
                {% set ns = namespace(lists=[]) %}
                {% for label in matching_labels %}
                  {% for entity in label_entities(label) %}
                    {% if entity.startswith('todo.')
                        and entity not in ns.lists %}
                      {% set ns.lists = ns.lists + [entity] %}
                    {% endif %}
                  {% endfor %}
                {% endfor %}
                {{ ns.lists }}

          - condition: template
            value_template: >
              {{ target_lists | length > 0 }}

          - action: todo.get_items
            target:
              entity_id: "{{ target_lists }}"
            data:
              status: "needs_action"
            response_variable: initial_items

          - variables:
              active_count: >
                {% set ns = namespace(count=0) %}
                {% for list_id, list_data in initial_items.items() %}
                  {% set ns.count =
                    ns.count + (list_data.get('items', []) | length) %}
                {% endfor %}
                {{ ns.count }}

              list_text: >
                {% set ns = namespace(items=[]) %}
                {% for list_id, list_data in initial_items.items() %}
                  {% for item in list_data.get('items', []) %}
                    {% set ns.items = ns.items + ['- ' ~ item.summary] %}
                  {% endfor %}
                {% endfor %}
                {{ ns.items | join('\n') }}

          - condition: template
            value_template: >
              {{ active_count | int(0) > 0 }}

          - if:
              - condition: template
                value_template: >
                  {{ dashboard_helper | string | trim != '' }}
            then:
              - action: input_text.set_value
                target:
                  entity_id: "{{ dashboard_helper }}"
                data:
                  value: "{{ target_lists | join(',') }}"

          # ==========================================
          # PRIMARY ARRIVAL NOTIFICATION
          # ==========================================
          - choose:
              - conditions:
                  - condition: template
                    value_template: >
                      {{ dynamic_list_dashboard | trim != '' }}
                sequence:
                  - device_id: !input notify_device
                    domain: mobile_app
                    type: notify
                    title: >
                      List for {{ state_attr(zone_entity, 'friendly_name') }}
                    message: >
                      You have {{ active_count }} items:
                      {{ '\n' }}{{ list_text }}
                    data:
                      tag: "zone_list_notification"
                      sticky: true
                      actions:
                        - action: "URI"
                          title: "Open Lists"
                          uri: "{{ dynamic_list_dashboard }}"

            default:
              - device_id: !input notify_device
                domain: mobile_app
                type: notify
                title: >
                  List for {{ state_attr(zone_entity, 'friendly_name') }}
                message: >
                  You have {{ active_count }} items:
                  {{ '\n' }}{{ list_text }}
                data:
                  tag: "zone_list_notification"
                  sticky: true
                  actions: []

          # ==========================================
          # SECONDARY ARRIVAL NOTIFICATION
          #
          # Plain message only - see the variables-block comment above
          # for why (notify.send_message's schema has no room for
          # sticky/tag/actionable-button extras). Guarded by the "if" so
          # it's a no-op, never evaluated, when left blank.
          # ==========================================
          - if:
              - condition: template
                value_template: >
                  {{ secondary_notify_device | string | trim != '' }}
            then:
              - action: notify.send_message
                target:
                  entity_id: "{{ secondary_notify_device }}"
                data:
                  title: >
                    {{ state_attr(person_entity, 'friendly_name') }}
                    is at
                    {{ state_attr(zone_entity, 'friendly_name') }}
                  message: >
                    Here is the current list:
                    {{ '\n' }}{{ list_text }}

          # Wait for actual departure. If the configured maximum wait
          # expires, stop this visit run rather than waiting forever.
          - wait_template: >
              {{ states(person_entity) != arrival_zone_state }}
            timeout:
              hours: "{{ zone_departure_timeout_hours | int(4) }}"
            continue_on_timeout: false

          # Dismiss the sticky "List for <zone>" notification now that
          # we've left — otherwise it just sits on the phone forever.
          # Same race guard as the helper-clear below: if a direct jump
          # into a new labeled zone already repopulated the dashboard
          # helper, a fresh notification for that zone has already
          # replaced this one, so don't clear it out from under it.
          - if:
              - condition: template
                value_template: >
                  {{ dashboard_helper | string | trim == ''
                     or states(dashboard_helper)
                     == (target_lists | join(',')) }}
            then:
              - device_id: !input notify_device
                domain: mobile_app
                type: notify
                message: "clear_notification"
                data:
                  tag: "zone_list_notification"
                  actions: []

          # Snapshot remaining items BEFORE wiping the helper.
          - action: todo.get_items
            target:
              entity_id: "{{ target_lists }}"
            data:
              status: "needs_action"
            response_variable: exit_items

          - variables:
              exit_count: >
                {% set ns = namespace(count=0) %}
                {% for list_id, list_data in exit_items.items() %}
                  {% set ns.count =
                    ns.count + (list_data.get('items', []) | length) %}
                {% endfor %}
                {{ ns.count }}

              last_item_name: >
                {% set ns = namespace(name='') %}
                {% for list_id, list_data in exit_items.items() %}
                  {% for item in list_data.get('items', []) %}
                    {% set ns.name = item.summary %}
                  {% endfor %}
                {% endfor %}
                {{ ns.name }}

              last_item_uid: >
                {% set ns = namespace(uid='') %}
                {% for list_id, list_data in exit_items.items() %}
                  {% for item in list_data.get('items', []) %}
                    {% set ns.uid = item.uid %}
                  {% endfor %}
                {% endfor %}
                {{ ns.uid }}

              last_item_list: >
                {% set ns = namespace(entity='') %}
                {% for list_id, list_data in exit_items.items() %}
                  {% if list_data.get('items', []) | length > 0 %}
                    {% set ns.entity = list_id %}
                  {% endif %}
                {% endfor %}
                {{ ns.entity }}

          # Only clear the helper if it still contains the lists from this
          # visit. This avoids wiping a helper that another parallel zone
          # arrival has already repopulated.
          - if:
              - condition: template
                value_template: >
                  {{ dashboard_helper | string | trim != ''
                     and states(dashboard_helper)
                     == (target_lists | join(',')) }}
            then:
              - action: input_text.set_value
                target:
                  entity_id: "{{ dashboard_helper }}"
                data:
                  value: ""

          # ==========================================
          # SECONDARY DEPARTURE NOTIFICATION
          # ==========================================
          - if:
              - condition: template
                value_template: >
                  {{ secondary_notify_device | string | trim != '' }}
            then:
              - action: notify.send_message
                target:
                  entity_id: "{{ secondary_notify_device }}"
                data:
                  message: >
                    {{ state_attr(person_entity, 'friendly_name') }} has left
                    {{ state_attr(zone_entity, 'friendly_name') }}

          # ==========================================
          # 1-ITEM DEPARTURE PROMPT
          # ==========================================
          - choose:
              - conditions:
                  - condition: template
                    value_template: >
                      {{ enable_reminders
                         and exit_count | int(0) == 1 }}
                sequence:
                  - variables:
                      action_yes: "{{ 'MARK_DONE_' ~ context.id }}"
                      action_no: "{{ 'LEAVE_OPEN_' ~ context.id }}"
                      exit_prompt_tag: >
                        {{ 'zone_exit_prompt_' ~ context.id }}

                  - device_id: !input notify_device
                    domain: mobile_app
                    type: notify
                    message: >
                      Did you get {{ last_item_name }}?
                      I can check it off for you.
                    data:
                      tag: "{{ exit_prompt_tag }}"
                      sticky: true
                      actions:
                        - action: "{{ action_yes }}"
                          title: "Yes"
                        - action: "{{ action_no }}"
                          title: "No"

                  - wait_for_trigger:
                      - trigger: event
                        event_type: mobile_app_notification_action
                        event_data:
                          action: "{{ action_yes }}"
                        id: "yes"

                      - trigger: event
                        event_type: mobile_app_notification_action
                        event_data:
                          action: "{{ action_no }}"
                        id: "no"

                      - trigger: state
                        entity_id: !input person_target
                        to: "home"
                        id: "home"

                    timeout:
                      minutes: 5
                    continue_on_timeout: true

                  # Clear the stale Yes/No prompt after an answer,
                  # arrival home, or expiration.
                  - device_id: !input notify_device
                    domain: mobile_app
                    type: notify
                    message: "clear_notification"
                    data:
                      tag: "{{ exit_prompt_tag }}"
                      actions: []

                  - choose:
                      - conditions:
                          - condition: template
                            value_template: >
                              {{ wait.trigger is not none
                                 and wait.trigger.id == 'yes' }}
                        sequence:
                          - action: todo.update_item
                            target:
                              entity_id: "{{ last_item_list }}"
                            data:
                              item: "{{ last_item_uid }}"
                              status: completed

          # Re-query after the exit prompt.
          - action: todo.get_items
            target:
              entity_id: "{{ target_lists }}"
            data:
              status: "needs_action"
            response_variable: post_prompt_items

          - variables:
              remaining_count: >
                {% set ns = namespace(count=0) %}
                {% for list_id, list_data in post_prompt_items.items() %}
                  {% set ns.count =
                    ns.count + (list_data.get('items', []) | length) %}
                {% endfor %}
                {{ ns.count }}

          # ==========================================
          # WELCOME HOME REMINDER
          # ==========================================
          - choose:
              - conditions:
                  - condition: template
                    value_template: >
                      {{ enable_reminders
                         and remaining_count | int(0) > 0 }}
                sequence:

                  # The Person may already have arrived home during
                  # the 1-item prompt.
                  - if:
                      - condition: template
                        value_template: >
                          {{ states(person_entity) != 'home' }}
                    then:
                      - wait_for_trigger:
                          - trigger: state
                            entity_id: !input person_target
                            to: "home"

                        timeout:
                          hours: >
                            {{ home_arrival_timeout_hours | int(9) }}
                        continue_on_timeout: true

                      - condition: template
                        value_template: >
                          {{ wait.trigger is not none }}

                  - choose:
                      - conditions:
                          - condition: template
                            value_template: >
                              {{ dashboard_link | trim != '' }}
                        sequence:
                          - device_id: !input notify_device
                            domain: mobile_app
                            type: notify
                            title: "Got everything?"
                            message: >
                              Please take a minute and update the lists
                            data:
                              tag: "zone_list_notification"
                              sticky: true
                              actions:
                                - action: "URI"
                                  title: "Open Lists"
                                  uri: "{{ dashboard_link }}"

                    default:
                      - device_id: !input notify_device
                        domain: mobile_app
                        type: notify
                        title: "Got everything?"
                        message: >
                          Please take a minute and update the lists
                        data:
                          tag: "zone_list_notification"
                          sticky: true
                          actions: []
1 Like

Because labels can be applied to multiple zones and lists, when the person enters a labeled zone, the automation consolidates lists with the zone’s label(s) into one list.

For example

  • You shop at any one of a number of grocery stores; the automation triggers at any of the tagged zones.
  • You enter a zone with multiple labels. The automation consolidates all the lists with those labels for you. For example, going to a store labeled both as “groceries” and “pharmacy” will give you all the lists with those labels–the Alexa shopping list tagged “pharmacy”, perhaps a Paprika groceries list, and a local Home Assistant to-do list tagged “groceries”–any lists with those tags.

It works if you only supply one person and one notification device. Everything else is optional. You can:

  • Dynamically generate a list dashboard and include a link with the notifications so in addition to the list in the alert, the link goes to a dynamic list you can check off.
  • If the user in the zone–or anyone–checks off items on lists, the alert on the phone is overwritten.
  • Receive reminders when you leave the store with only one item unchecked, and when you return home in general
  • Notify a second device (i.e., let another household member know)
  • Tweak the timing for various thresholds that affect time in a zone, maximum time to return home, etc.

In addition to the basic shopping list use case:

  • Create labeled lists and zones for people you want to talk to, for example, labeling a building on a college campus and a list of the professors to talk to (or what you want to talk about).
  • Create labeled lists of books to check out at a library, and label all the branches of your library system.
  • The LEGO models you want to check out when you’re at a LEGO store. Just tag the list & zones.
  • Foreign-language phrases to learn when you travel to another country.

You could also forget completely about store-specific lists and organize the lists functionally: produce, groceries, hardware, pharmacy, warehouse, automotive, clothing, music – you name it. Then tag lists for these things and tag as many zones as you want. Farm stands: produce. Big store: produce, groceries, pharmacy, automotive. Warehouse store (e.g., Costco): produce, groceries, hardware, pharmacy, warehouse. And so forth. This is particularly useful if, for example, one location of a chain has a pharmacy or automotive department and another doesn’t.

1 Like

An example of how I filled out section 2

Each instance/use of this blueprint covers one person, so, for example, I have another instance of the blueprint for my spouse with “wife-lists” as a text helper, same Dashboard Link but a different Dynamic List Dashboard link, which is a tab in the same base dashboard I use (“/dashboard-lists/wife” for her). You’d need to add another panel and another helper for each person. (I am making this sound much more complicated than it really is!)

1 Like

Carrying over from the previous iteration:

This blueprint uses labels alone to associate lists with zones. Whent the selected person enters a zone labeled the same as one or more lists, it sends the list(s) to the selected device (running the official app). This might be a shopping list consolidated from a few HA lists sent when you arrive at any one of several grocery stores, for example, or a list of prescriptions to pick up at a specific pharmacy, or a list of books to look for when you arrive at any branch of your local library system.

When the user (one per instance) enters a defined zone (except for home), the automation checks if there are any labels applied to the zone.

If the zone has any labels (or optionally matches only a selected one), the automation checks to see if any lists share the label(s) of the zone. If there’s a match, it will send those lists in a notification to the user (using the device selected). All you have to do is apply labels to zones and lists and the automation takes care of the rest.

  • It’s designed for low maintenance and high flexibility. There can be as many criss-crossed zones, labels, and lists as you want. The automation allows different zones to have multiple lists. For example, grocery store zones might have a “grocery store” label, and BigStore might have a “big store” label. But you can also tag the BigStore locations with the “grocery store” label, so when you go to the grocery store, you only get the grocery-store list, but when you go to BigStore, you see the big store AND grocery items. I have lists/labels/zones for grocery stores (e.g., Wegmans, Giant, ACME, Whole Foods), large stores (e.g., Target or Walmart), warehouse (e.g., Costco), and hardware stores (e.g., Lowe’s). Some locations have multiple labels (large stores usually have grocery departments, for example). The lists could be for shopping, actions, whatever, of course. This design also allows you to do cool things like have a basic HA shopping list (local), a Paprika shopping list (integrated w/ app), an Alexa shopping list (integrated w/ app), but just label them all and they are functionally combined based on the zone you go to.
  • Aggregation. Lists are combined (in the notification) so the device only gets one alert after entering a zone.
  • Limiting conditions. You can add arbitrary conditions such as time of day. This might be particularly helpful, for example, if a person defined works in a zone. Or just to safeguard or manage automations. (I put a “master switch” boolean in most of my automations.) You might be able to use this to exclude zones or labels (untested).
  • Interactive exit reminder. There’s an optional exit reminder. If there was only one item in the notification, it offers to check it off. If more than one item it’s just a reminder to update the list(s).
1 Like

You need to be a trust level ‘member’ to re-edit a post. Understanding Discourse Trust Levels

1 Like

Yep
#lifegoals

1 Like

Do a little reading, add a few likes, it can be done in an hour.

1 Like

Thanks – I’m up against a hard deadline on something else and wanted to share where this was, since I’ll have to focus elsewhere for a few weeks. I’m sure I’ll be “normal” soon. :wink:

1 Like

Find a long thread and scroll thru it…

1 Like

I also integrate this on my basic list dashboard, by providing a list of locations the list applies to, dynamically. I have an expander for each list, and underneath, a list of all the locations (zones) where the list’s labels apply. The shopping-list panel also has buttons for each of the automations using this blueprint, so alerts can be turned on and off. It’s a particularly sweet UX with the Alexa Devices lists integration, so my daughter tells Alexa we need milk, and HA takes it from there and reminds whoever goes to any store in our area to get milk.

Apologies on 1.1 error; reverting shortly, as device selector was dropped.

Status: Frozen until at least August 19th; if I am able to edit then, I’ll provide the latest tested updates.

Open long thread, put something heavy on your keyboard’s down arrow, go cook dinner. You’ll be a normal by the time you’re halfway through cooking :stuck_out_tongue:

2 Likes