Hoy vamos a ver cómo domotizar tu lista de la compra para que puedas alimentarla de una forma sencilla e incluir algunas automatizaciones.
Índice
Antes de empezar
Si llevas un tiempo con nosotros, es posible que ya hayas usado alguna de las versiones de nuestra lista de la compra. Con cada actualización intento añadir alguna funcionalidad, mejorar la experiencia de instalación y adaptar el código de las tarjetas.
Para evitar errores y acumular «basura» en tu instancia, si quieres aplicar esta versión, te recomiendo que empieces desde cero. No obstante, si eres un experto avanzado, puedes modificar únicamente aquellas partes que te interesen.
Integración de listas
Para domotizar tu lista de la compra vamos a utilizar dos tipos de listas:
- Una lista principal, que va a ser la lista de referencia a la que acudir para hacer la compra, crear automatizaciones o notificaciones, obtener información de sensores.
- Listas «pasarela» (tantas como quieras), que vamos a utilizar con el objetivo de añadir objetos a tu lista de la compra desde otros dispositivos (por ejemplo, asistentes de voz).
Elige tu lista principal
Lo primero que tenemos que hacer es elegir cuál queremos que sea nuestra lista de referencia. Lo más intuitivo es pensar que lo lógico es elegir la integración oficial de HA (y así lo hacíamos hasta ahora), pero no tiene por qué.
Por ejemplo, en mi caso llevo años utilizando la aplicación de Bring! Además de gustarme mucho su aplicación, es más fácil de usar para usuarios que se pierden en Home Assistant. Esto la ha convertido hace mucho en la lista de referencia en casa (y de ahí no les saques), por lo que tiene más sentido usarla como lista principal que como una entidad «espejo».

Esto mismo sería aplicable si, por ejemplo, tú y tu familia sois usuarios del ecosistema de Google, utilizáis los asistentes de voz y la aplicación de listas Google Keep. En este caso tendría sentido usar esa integración como lista principal.
Elijas la opción que elijas, al terminar ya podrás acceder en el menú lateral al apartado «Lista de tareas pendientes» para visualizarla. También puedes localizar la entidad correspondiente en Herramientas para desarrolladores > Estados, cuyo estado es el número de elementos en la lista.

Sincroniza listas pasarela
Dicho lo anterior, en muchas ocasiones he comentado que (personalmente) una de las funciones más útiles que encuentro a domotizar tu lista de la compra es poder añadir productos a la lista con la voz, mientras estoy cocinando o manipulando alimentos (que es cuando me acuerdo).
En mi caso lo hago aprovechando una tablet Android que tengo en la cocina, con el asistente de Google. Más allá de esto, nunca utilizo el asistente de Google (aunque potencialmente podría añadir productos desde el coche o desde mi Android TV).
Para ello solo he tenido que hacer lo siguiente:
- Integrar Google Keep, que es donde se almacenan los productos cuando le pides al asistente que apunte algo en tu lista de la compra. No obstante, esto serviría para cualquier otra lista integrable en HA (como, por ejemplo, todoist).
- Esto habrá generado una entidad (por ejemplo, ‘todo.lista_de_la_compra_google’), que contiene la lista anterior y la misma estructura que nuestra lista principal.

- Ahora voy a crear una sencilla automatización que se va a encargar de detectar cuando he añadido un objeto a la lista de Google, para añadirlo a la lista principal. Para ello utiliza este ‘blueprint’ que he preparado, pulsando en el siguiente botón.
- Luego solo tienes que crear una automatización usando el plano, seleccionar tu lista principal en el primer campo, tu lista pasarela en el segundo y pulsar en «Guardar».

- Puedes probar que funciona de una forma sencilla. Desde el menú lateral, accede a «Listas de tareas pendientes» y accede a tu «Lista pasarela». Añade manualmente un objeto, y observa como desaparece de ella y reaparece en tu lista principal.
Esto mismo sucederá cuando añadas un objeto desde tu asistente de voz, o lista complementaria!
Gestiona la lista desde el reloj
Una de las principales ventajas que encuentro a domotizar tu lista de la compra es que, cuando estás en el supermercado, puedes consultarla desde tu smartwatch e ir marcando los productos que has cogido.
Para ello no tienes que hacer nada más, simplemente instalar la aplicación de Home Assistant y añadirla entre las entidades que expones al reloj.

Ya sabes que en mi caso utilizo un Amazfit Active 2 NFC, por lo que además puedo añadir productos usando el asistente de voz, añadir mis tarjetas de puntos (Carrefour, LIDL, Ikea, etc.) y pagar directamente con el reloj, por lo que puedo hacer la compra de principio a fin sin sacar el teléfono o la cartera del bolsillo.
Creación de sensores
Creación de sensores de la lista
El siguiente paso para domotizar tu lista de la compra es crear unos sensores que nos permitan extraer los productos de la lista. Esto nos servirá para construir la tarjeta del panel de control y crear automatizaciones.
Vamos a incluir estos sensores dentro del fichero ‘templates.yaml‘ copiando el siguiente código. Recuerda reiniciar Home Assistant para que aparezcan los sensores.
- trigger:
- trigger: state
entity_id: todo.shopping_list
not_to:
- unavailable
- unknown
- trigger: homeassistant
event: start
- trigger: time_pattern
seconds: /1
action:
- action: todo.get_items
target:
entity_id: todo.shopping_list
data:
status: needs_action
response_variable: items_to_buy
sensor:
- name: "Shopping list (items to buy)"
unique_id: shopping_list_uncomplete_items
state: >
{{ items_to_buy['todo.shopping_list']['items'] | count() }}
attributes:
list: >
{{ items_to_buy['todo.shopping_list']['items'] | list }}
- trigger:
- trigger: state
entity_id: todo.shopping_list
not_to:
- unavailable
- unknown
- trigger: homeassistant
event: start
- trigger: time_pattern
minutes: /10
action:
- action: todo.get_items
target:
entity_id: todo.shopping_list
data:
status: completed
response_variable: bought_items
sensor:
- name: "Shopping list (bought items)"
unique_id: shopping_list_complete_items
state: >
{{ bought_items['todo.shopping_list']['items'] | count() }}
attributes:
list: >
{{ bought_items['todo.shopping_list']['items'] | list }}
Esto creará las siguientes entidades:
- La entidad ‘sensor.shopping_list_items_to_buy’ tiene como valor el número de productos en la lista de la compra, y el listado en su atributo ‘list’.
- La entidad ‘sensor.shopping_list_bought_items’ tiene como valor el número de productos comprados recientemente, y el listado en su atributo ‘list’.

Creación del catálogo de productos
Ahora vamos a crear nuestro catálogo de productos, que va a contener aquellos que más compramos y sus características. Esto nos va a permitir crear una interfaz personalizada, automatizaciones avanzadas, notificaciones…
Y lo mejor de todo, es que lo vamos a hacer cómodamente desde una hoja de cálculo de Google Sheets integrada en HA, que se va a encargar de crear y actualizar automáticamente nuestro catálogo.
- En Home Assistant, ve a Configuración > Dispositivos y servicios > Añadir integración > Google > Google Sheets, introduce tus credenciales y permite el acceso a tu cuenta de Google. Esto creará una nueva hoja de cálculo en tu cuenta, llamada «Home Assistant».
- Renombra la pestaña y dale un título (por ejemplo, «Shopping List»). Luego crea una columna llamada «Product», otra «Category» y, a partir de aquí, tantas columnas como atributos personalizados quieras asignar a los productos (por ejemplo, «Price», «Units», «Quantity», «Store», «Image»…).
- Ahora indica en cada fila los datos correspondientes a cada producto, como puedes ver en el ejemplo:
- Product: el nombre del producto (tal y como lo añades a tu lista).
- Category: categoría a la que corresponde el producto.
- Price: precio de referencia del producto.
- Units: unidades en las que se cobra el producto, en función de si lo compras al peso (‘kg’) o por unidades (‘ud’).
- Quantity: esta es la cantidad que sueles comprar (por ejemplo, 1 unidad o 0,5 kg).
- Store: la tienda donde sueles comprar el producto.
- Image: URL de una imagen o icono que represente el producto.

- Comprueba que ya puedes leer los datos de tu hoja desde Configuración > Herramientas para desarrolladores > Acciones > google_sheets.get_sheet. Selecciona tu hoja en el desplegable y pulsa en «Realizar una acción». En unos segundos verás cómo te devuelve la información de los productos.

- Ya que estás aquí, haz clic en «Ir al modo YAML» y copia el código que indica el campo ‘config_entry’, ya que lo vas a necesitar a continuación.
- Ahora vuelve a tu fichero ‘templates.yaml’, copia el siguiente código y reinicia de nuevo Home Assistant.
- trigger:
- trigger: homeassistant
event: start
- trigger: event
event_type: event_template_reloaded
- trigger: time_pattern
minutes: /10
action:
- delay: "00:00:30"
- action: google_sheets.get_sheet
data:
config_entry: "23KJN23SFEW24FG224GK"
worksheet: "Shopping List"
rows: 100
response_variable: sheet_data
sensor:
- name: "Shopping List (catalogue)"
unique_id: shopping_list_catalogue
state: "{{ (sheet_data['range'][1:] | length) }}"
attributes:
products: >
{% set ns = namespace(result={}) %}
{% for row in sheet_data['range'][1:] %}
{% if row | length > 0 and row[0] != '' %}
{% set ns.result = ns.result | combine({
row[0]: {
'category': row[1] if row | length > 1 else '',
'price': row[2] | replace(',', '.') | float(0) if row | length > 2 else 0,
'units': row[3] if row | length > 3 else '',
'quantity': row[4] | replace(',', '.') | float(0) if row | length > 4 else 0,
'store': row[5] if row | length > 5 else '',
'image': row[6] if row | length > 6 else ''
}
}) %}
{% endif %}
{% endfor %}
{{ ns.result }}
last_update: "{{ now().strftime('%d/%m/%Y %H:%M') }}"
- Esto habrá creado la entidad ‘sensor.shopping_list_catalogue’, cuyo valor es el número de productos en el catálogo. Además, en sus atributos encontrarás todos los productos y sus características.

Actualización automática del catálogo
Supongo que ahora estarás pensando, «qué pereza añadir uno a uno todos los productos al catálogo». Normal, pero tengo una buena noticia. He creado un ‘blueprint’ que, cada vez que se actualice tu lista de la compra, va a comprobar si hay algún producto nuevo y, en este caso, lo añadirá al catálogo automáticamente.
Esto no solo te ayudará a mantenerlo actualizado, también sirve para realizar una carga inicial con lo que ya tienes en la lista de la compra. A partir de ahí, solo tienes que informar los atributos personalizados que hayas creado para cada producto (categoría, precio, etc.).

Para añadir el ‘blueprint’ sólo tienes que pulsar en el siguiente botón y seleccionar tus entidades. Una vez guardado, haz cualquier cambio en tu lista de la compra y observa como se actualiza automáticamente.
Y, si tienes n8n instalado en tu ‘homelab‘, también puedes actualizar los precios automáticamente scrapeando la página web de tu supermercado o la API de Mercadona o Alcampo (como dato real, o como referencia).
Diseño del panel de control
Con los sensores que acabamos de crear ya podemos transformar la interfaz para controlar y domotizar tu lista de la compra.
Pero antes…
Ten en cuenta que necesitarás haber instalado a través de HACS las tarjetas de Bubble Card, Card Mod, Auto-Entities y Mushroom Cards. Además, para crear algunas funciones útiles vamos a hacer unas cosas más:
- En HA, ve a Configuración > Dispositivos y servicios > Ayudantes > Crear ayudante > Desplegable, llámalo «Shopping List Stores» y añade como opciones las tiendas en las que compras (por ejemplo, «Carrefour», «LIDL», etc.), que ya has indicado en tu catálogo de productos. Esto generará una entidad ‘input_select.shopping_list_stores’, que nos servirá para filtrar productos por tienda.
- En HA, ve a Configuración > Dispositivos y servicios > Ayudantes > Crear ayudante > Desplegable, llámalo «Shopping List Filter» y añade como opciones: «Recientes», «Categorías» y «Sugerencias». Esto generará una entidad ‘input_select.shopping_list_filter’, que nos servirá para filtrar productos del catálogo.
- En tu fichero ‘templates.yaml’, añade otro nuevo sensor pegando el siguiente código. Esto creará la entidad ‘sensor.shopping_list_next_shopping’, que mostrará el coste aproximado de tu próxima compra (en función de los datos que hayas indicado en tu catálogo).
- sensor:
- default_entity_id: sensor.shopping_list_next_shopping
name: Shopping List (next)
icon: mdi:cash
unit_of_measurement: '€'
state: >
{% set lista = state_attr('sensor.shopping_list_items_to_buy','list') | map(attribute='summary') | list %}
{% set productos = state_attr('sensor.shopping_list_items_to_buy','list') | map(attribute='summary') | unique | sort | list %}
{% set catalogo = state_attr('sensor.shopping_list_catalogue','products') %}
{% set ns = namespace(total=0.0) %}
{% for producto in productos -%}
{%- set unidades = lista | select('equalto', producto) | list | length | float -%}
{%- set info = catalogo[producto] if catalogo and producto in catalogo else none -%}
{%- set precio = info.price | float if info else 0.0 -%}
{%- set cantidad = info.quantity | float(0) if info else 0.0 -%}
{%- set ns.total = ns.total + (unidades * cantidad * precio) -%}
{%- endfor %}
{{ ns.total | round(2) }}
- Opcionalmente, en tu hoja de Google Sheets puedes añadir una nueva columna llamada «Sugerencias». La idea es que aquí incluyas un criterio adicional para agrupar tus productos en el catálogo (por ejemplo, «Favoritos», «Dieta», «Disfrutón»…). Además, como es una hoja de cálculo puedes añadir fórmulas (por ejemplo, para que indique «Temporada» solo en unos meses concretos del año). Si usas esta función, necesitarás editar el sensor del catálogo de esta forma, para añadir el atributo.
- trigger:
- trigger: homeassistant
event: start
- trigger: event
event_type: event_template_reloaded
- trigger: time_pattern
minutes: /30
action:
- delay: "00:00:30"
- action: google_sheets.get_sheet
data:
config_entry: "01KN435KZDSKAJS2CAE1JZMNJY"
worksheet: "Shopping List"
rows: 100
response_variable: sheet_data
sensor:
- name: "Shopping List (catalogue)"
unique_id: shopping_list_catalogue
state: "{{ (sheet_data['range'][1:] | length) }}"
attributes:
products: >
{% set ns = namespace(result={}) %}
{% for row in sheet_data['range'][1:] %}
{% if row | length > 0 and row[0] != '' %}
{% set ns.result = ns.result | combine({
row[0]: {
'category': row[1] if row | length > 1 else '',
'price': row[2] | replace(',', '.') | float(0) if row | length > 2 else 0,
'units': row[3] if row | length > 3 else '',
'quantity': row[4] | replace(',', '.') | float(0) if row | length > 4 else 0,
'store': row[5] if row | length > 5 else '',
'image': row[6] if row | length > 6 else '',
'sugerencias': row[7] if row | length > 7 else ''
}
}) %}
{% endif %}
{% endfor %}
{{ ns.result }}
last_update: "{{ now().strftime('%d/%m/%Y %H:%M') }}"
Tarjeta de la lista de la compra
Esta es la tarjeta principal, que muestra los productos que están en la lista de la compra.

Como puedes observar, tiene las siguientes características:
- En la esquina superior derecha encontrarás, primero, el coste aproximado de tu próxima compra. Obviamente, es difícil que coincida al céntimo (especialmente si compras algo al peso).
- A su lado, un desplegable que te permite filtrar la lista por la tienda asignada a los productos. La idea es que te resulte más fácil hacer la compra en función de dónde te encuentres. Recuerda que el nombre de las tiendas debe coincidir con el que has indicado en el atributo ‘store’ de los sensores de productos.
- A su derecha encontrarás un acceso directo al catálogo para añadir productos, que veremos a continuación.
- Debajo, un bloque para cada uno de los productos en la lista de la compra. Si pulsas en dicho bloque, se quitará una unidad de la lista de la compra. Como puedes observar, también se indican las unidades que quieres comprar y, debajo, el precio por unidad/kg. Además, los productos se van a incorporar a tu lista incluso aunque no los hayas incluido en tu catálogo.
Si ya has creado tu catálogo, lo único que tienes que hacer es copiar el siguiente código y se creará automáticamente.
type: vertical-stack
cards:
- type: custom:bubble-card
card_type: separator
name: Lista de la compra
icon: mdi:shopping
sub_button:
main:
- entity: sensor.shopping_list_next_shopping
scrolling_effect: false
show_background: false
show_icon: false
show_name: false
show_state: true
- name: Tienda
show_name: false
show_icon: true
icon: ""
entity: input_select.shopping_list_stores
sub_button_type: select
- show_name: false
show_icon: true
icon: mdi:shopping-search
tap_action:
action: navigate
navigation_path: "#shopping_list"
bottom: []
modules:
- default
styles: |-
ha-card {
margin-top: 10px!important;
margin-bottom: 10px!important;
}
.bubble-name {
font-size: 15px !important;
}
- type: custom:auto-entities
visibility:
- condition: state
entity: sensor.shopping_list_items_to_buy
state_not: "0"
show_empty: false
card:
square: false
type: grid
columns: 3
card_param: cards
filter:
template: >-
{% set lista = state_attr('sensor.shopping_list_items_to_buy','list') |
map(attribute='summary') | list %} {% set productos =
state_attr('sensor.shopping_list_items_to_buy','list') |
map(attribute='summary') | unique | sort | list %} {% set catalogo =
state_attr('sensor.shopping_list_catalogue','products') %} {% set tienda
= states('input_select.shopping_list_stores') %}
{% for producto in productos -%} {%- set cantidad = lista |
select('equalto', producto) | list | length | string -%} {%- set info =
catalogo[producto] if catalogo and producto in catalogo else none -%}
{%- set picture = info.image if info and info.image else '' -%} {%- set
precio = info.price | string if info and info.price else '0' -%} {%- set
unidades = info.units if info else '' -%} {%- set store = info.store if
info else '' -%}
{%- if tienda == 'Todas' or tienda == store -%}
{%- if picture != '' -%}
{{
{
'type': 'custom:mushroom-template-card',
'entity': 'sensor.shopping_list_items_to_buy',
'primary': producto,
'secondary': precio + ' €/' + unidades,
'badge_text': cantidad,
'badge_color': 'black',
'picture': picture,
'vertical': 'true',
'fill_container': 'true',
'tap_action': {
'action': 'perform-action',
'perform_action': 'todo.update_item',
'target': { 'entity_id': 'todo.shopping_list' },
'data': {
'item': producto,
'status': 'completed',
},
},
'card_mod': {
'style': {
'ha-tile-info$': '.primary { color: #ffffff !important; font-size: 11px !important; } .secondary { color: #ffffff !important; font-size: 11px !important; }',
'ha-tile-icon$': '.container { border-radius: 0px !important; } .container img { border-radius: 0px !important; }',
'.': 'ha-card { background: linear-gradient(rgba(238, 82, 79, 1), rgba(181, 42, 39, 1)); border-radius: 15px;}'
}
}
}
}},
{%- else -%}
{{
{
'type': 'custom:mushroom-template-card',
'entity': 'sensor.shopping_list_items_to_buy',
'primary': producto,
'badge_text': cantidad,
'badge_color': 'black',
'icon': 'mdi:shopping',
'icon_color': 'white',
'vertical': 'true',
'fill_container': 'true',
'tap_action': {
'action': 'perform-action',
'perform_action': 'todo.update_item',
'target': { 'entity_id': 'todo.shopping_list' },
'data': {
'item': producto,
'status': 'completed',
},
},
'card_mod': {
'style': {
'ha-tile-info$': '.primary { color: #ffffff !important; font-size: 11px !important; } .secondary { color: #ffffff !important; font-size: 11px !important; }',
'ha-tile-icon$': '.container { border-radius: 0px !important; }',
'.': 'ha-card { background: linear-gradient(rgba(238, 82, 79, 1), rgba(181, 42, 39, 1)); border-radius: 15px;} ha-state-icon {--mdc-icon-size: 35px !important;}'
}
}
}
}},
{%- endif -%}
{%- endif -%} {%- endfor %}
Tarjeta para añadir productos
Esta tarjeta sirve para añadir productos a la lista de distintas formas. En mi caso abro esta tarjeta en un popup de Bubble Card, desde el acceso directo que te indicaba en el apartado anterior (aunque la puedes colocar donde quieras).
- Campo de texto. En la parte superior de la tarjeta siempre aparece un campo de texto que te permite añadir productos a la lista de la compra, sólo con escribirlos. No importa si ya están incluidos o no en tu catálogo.

- Productos comprados recientemente. En este apartado encontrarás los productos que has comprado recientemente. Si pulsas sobre ellos volverán a la lista de la compra, por lo que es la forma más rápida de hacerla. También puedes limpiar este apartado pulsando sobre el icono «Vaciar» en la parte superior.

- Productos ordenados por categoría. Desde este apartado podrás encontrar los productos que has introducido en tu catálogo, ordenados alfabéticamente y por categoría (coincidiendo con lo que hayas indicado en los sensores personalizados). Además, sabrás si ya lo has añadido a la lista (en rojo) o no, así como controlar las unidades añadidas desde los iconos correspondientes. Es la mejor forma de hacer la lista más completa.

- Productos sugeridos. Este bloque funciona igual que el anterior, pero en lugar de clasificar los productos por categoría, lo hace por tipo de sugerencia (siempre que exista). Perfecto, si quieres dejarte guiar a la hora de seleccionar tus productos.

- Además, en la esquina superior derecha encontrarás un desplegable que te permite saltar de un apartado a otro (como aprendimos con nuestros menús dinámicos).
Si ya has creado tu catálogo, lo único que tienes que hacer es copiar el siguiente código y se creará automáticamente.
type: vertical-stack
cards:
- type: custom:bubble-card
card_type: pop-up
hash: "#shopping_list"
icon: mdi:shopping-search
name: Catálogo
button_type: name
modules:
- default
- type: todo-list
entity: todo.shopping_list
hide_completed: true
hide_create: false
card_mod:
style: |
ha-card {
background: transparent;
border: 0px;
box-shadow: none;
margin-left: -10px;
}
ha-list {
display: none;
}
- type: vertical-stack
visibility:
- condition: state
entity: input_select.shopping_list_filter
state: Recientes
cards:
- type: custom:bubble-card
card_type: separator
name: Recientemente
icon: mdi:history
sub_button:
- name: Vaciar
show_name: true
icon: mdi:delete
tap_action:
action: perform-action
perform_action: todo.remove_completed_items
target:
entity_id: todo.shopping_list
- entity: input_select.shopping_list_filter
name: ""
show_name: false
show_icon: true
modules:
- default
card_mod:
style: |
ha-card {
margin-top: 10px!important;
margin-bottom: 10px!important;
}
- type: custom:auto-entities
visibility:
- condition: state
entity: sensor.shopping_list_bought_items
state_not: "0"
show_empty: false
card:
square: false
type: grid
columns: 3
card_param: cards
filter:
template: >-
{% set productos =
state_attr('sensor.shopping_list_bought_items','list') |
map(attribute='summary') | unique | sort | list %} {% set catalogo =
state_attr('sensor.shopping_list_catalogue','products') %} {% set
tienda = states('input_select.shopping_list_stores') %}
{% for producto in productos -%} {%- set info = catalogo[producto]
if catalogo and producto in catalogo else none -%} {%- set picture =
info.image if info and info.image else '' -%} {%- set precio =
info.price | string if info and info.price else '0' -%} {%- set
unidades = info.units if info else '' -%} {%- set store = info.store
if info else '' -%}
{%- if picture != '' -%}
{{
{
'type': 'custom:mushroom-template-card',
'entity': 'sensor.shopping_list_items_to_buy',
'primary': producto,
'secondary': precio + ' €/' + unidades,
'picture': picture,
'vertical': 'true',
'fill_container': 'true',
'tap_action': {
'action': 'perform-action',
'perform_action': 'todo.update_item',
'target': { 'entity_id': 'todo.shopping_list' },
'data': {
'item': producto,
'status': 'needs_action',
},
},
'card_mod': {
'style': {
'ha-tile-info$': '.primary { color: #ffffff !important; font-size: 11px !important; } .secondary { color: #ffffff !important; font-size: 11px !important; }',
'ha-tile-icon$': '.container { border-radius: 0px !important; } .container img { border-radius: 0px !important; }',
'.': 'ha-card { background: linear-gradient( rgba(79, 171, 162, 1), rgba(38, 133, 124, 1) ); border-radius: 15px;}'
}
}
}
}},
{%- else -%}
{{
{
'type': 'custom:mushroom-template-card',
'entity': 'sensor.shopping_list_items_to_buy',
'primary': producto,
'icon': 'mdi:shopping',
'icon_color': 'white',
'vertical': 'true',
'fill_container': 'true',
'tap_action': {
'action': 'perform-action',
'perform_action': 'todo.update_item',
'target': { 'entity_id': 'todo.shopping_list' },
'data': {
'item': producto,
'status': 'needs_action',
},
},
'card_mod': {
'style': {
'ha-tile-info$': '.primary { color: #ffffff !important; font-size: 11px !important; } .secondary { color: #ffffff !important; font-size: 11px !important; }',
'ha-tile-icon$': '.container { border-radius: 0px !important; }',
'.': 'ha-card { background: linear-gradient( rgba(79, 171, 162, 1), rgba(38, 133, 124, 1) ); border-radius: 15px;} ha-state-icon {--mdc-icon-size: 35px !important;}'
}
}
}
}},
{%- endif -%}
{%- endfor %}
- type: vertical-stack
visibility:
- condition: state
entity: input_select.shopping_list_filter
state: Categorías
cards:
- type: custom:bubble-card
card_type: separator
name: Categorías
icon: mdi:view-grid
sub_button:
- entity: input_select.shopping_list_filter
name: ""
show_name: false
show_icon: true
modules:
- default
card_mod:
style: |
ha-card {
margin-top: 10px!important;
margin-bottom: 10px!important;
}
- type: custom:auto-entities
show_empty: false
card:
type: vertical-stack
card_param: cards
filter:
template: >-
{%- set catalogo =
state_attr('sensor.shopping_list_catalogue','products') %} {%- set
categories = catalogo.values() | map(attribute='category') | unique
| sort | list -%} {%- set lista =
state_attr('sensor.shopping_list_items_to_buy','list') |
map(attribute='summary') | list %}
{%- for category in categories -%}
{%- set category_name = category if category else 'Sin asignar' -%}
{%- set items_category = catalogo.items() | selectattr('1.category', 'equalto', category) | list -%}
{%- set size_category = items_category | length -%}
{{
{
'type': 'custom:bubble-card',
'card_type': 'separator',
'name': category_name,
'card_mod': {
'style': 'ha-card { margin-top: 10px!important; margin-bottom: 10px!important; }'
},
'sub_button': [
{
'name': size_category | string + ' Productos',
'show_name': true,
'tap_action': { 'action': 'none' }
}
]
}
}},
{%- for nombre, info in items_category -%}
{%- set to_buy = nombre in lista -%}
{%- set cantidad = lista | select('equalto', nombre) | list | length -%}
{%- set gradient = 'rgba(238, 82, 79, 1), rgba(181, 42, 39, 1)' if to_buy else 'rgba(79, 171, 162, 1), rgba(38, 133, 124, 1)' -%}
{{
{
'type': 'custom:bubble-card',
'card_type': 'button',
'button_type': 'state',
'show_state': true,
'entity': 'sensor.shopping_list_catalogue',
'name': nombre + ' (' + cantidad | string + ')' if cantidad | int > 0 else nombre,
'icon': 'mdi:shopping',
'show_last_changed': false,
'tap_action': {
'action': 'perform-action',
'perform_action': 'todo.add_item',
'target': { 'entity_id': 'todo.shopping_list' },
'data': { 'item': nombre }
},
'styles': (
".bubble-icon-container { background-image: url('" + info.image + "') !important; background-size: 25px !important; background-repeat: no-repeat !important; background-color: white !important; background-position: center !important; border-radius: 50% !important; } .bubble-icon-container ha-icon { display: none !important; }"
if info.image else ''
),
'card_mod': {
'style': (
'.bubble-state { font-size: 0 !important; ' + ('display: none !important; ' if not info.store else '') + '}'
+ ' .bubble-state::before { content: "' + (info.store if info.store else '') + '" !important; font-size: 11px !important; color: white !important}'
+ ' .bubble-state * { display: none !important; }'
+ ' .bubble-button-background { opacity: 1 !important; background: linear-gradient('
+ gradient
+ '); } .bubble-entity-picture { width: 25px !important; height: 25px !important; margin-top: 6px; }'
)
},
'sub_button': [
{
'name': (
((info.price | string) + ' €/' + (info.units if info.units else '') if info.price else (info.units if info.units else ''))
),
'show_name': true,
'show_icon': false,
'show_background': false
},
{
'icon': 'mdi:plus-thick',
'show_background': true,
'state_background': false,
'tap_action': {
'action': 'perform-action',
'perform_action': 'todo.add_item',
'target': { 'entity_id': 'todo.shopping_list' },
'data': { 'item': nombre }
}
},
{
'icon': 'mdi:minus-thick',
'show_background': true,
'state_background': false,
'tap_action': {
'action': 'perform-action',
'perform_action': 'todo.update_item',
'target': { 'entity_id': 'todo.shopping_list' },
'data': { 'item': nombre, 'status': 'completed' }
}
}
]
}
}},
{%- endfor %}
{%- endfor -%}
- type: vertical-stack
visibility:
- condition: state
entity: input_select.shopping_list_filter
state: Sugerencias
cards:
- type: custom:bubble-card
card_type: separator
name: Sugerencias
icon: mdi:star
sub_button:
- entity: input_select.shopping_list_filter
name: ""
show_name: false
show_icon: true
modules:
- default
card_mod:
style: |
ha-card {
margin-top: 10px!important;
margin-bottom: 10px!important;
}
- type: custom:auto-entities
show_empty: false
card:
type: vertical-stack
card_param: cards
filter:
template: >-
{%- set catalogo =
state_attr('sensor.shopping_list_catalogue','products') %} {%- set
sugerencias = catalogo.values() | map(attribute='sugerencias') |
reject('equalto', none) | reject('equalto', '') | unique | sort |
list -%} {%- set lista =
state_attr('sensor.shopping_list_items_to_buy','list') |
map(attribute='summary') | list %}
{%- for sugerencia in sugerencias -%}
{%- set sugerencia_name = sugerencia if sugerencia else 'Sin asignar' -%}
{%- set items_sugerencia = catalogo.items() | selectattr('1.sugerencias', 'equalto', sugerencia) | list -%}
{%- set size_sugerencia = items_sugerencia | length -%}
{{
{
'type': 'custom:bubble-card',
'card_type': 'separator',
'name': sugerencia_name,
'card_mod': {
'style': 'ha-card { margin-top: 10px!important; margin-bottom: 10px!important; }'
},
'sub_button': [
{
'name': size_sugerencia | string + ' Productos',
'show_name': true,
'tap_action': { 'action': 'none' }
}
]
}
}},
{%- for nombre, info in items_sugerencia -%}
{%- if info.sugerencias -%}
{%- set to_buy = nombre in lista -%}
{%- set cantidad = lista | select('equalto', nombre) | list | length -%}
{%- set gradient = 'rgba(238, 82, 79, 1), rgba(181, 42, 39, 1)' if to_buy else 'rgba(79, 171, 162, 1), rgba(38, 133, 124, 1)' -%}
{{
{
'type': 'custom:bubble-card',
'card_type': 'button',
'button_type': 'state',
'show_state': true,
'entity': 'sensor.shopping_list_catalogue',
'name': nombre + ' (' + cantidad | string + ')' if cantidad | int > 0 else nombre,
'icon': 'mdi:shopping',
'show_last_changed': false,
'tap_action': {
'action': 'perform-action',
'perform_action': 'todo.add_item',
'target': { 'entity_id': 'todo.shopping_list' },
'data': { 'item': nombre }
},
'styles': (
".bubble-icon-container { background-image: url('" + info.image + "') !important; background-size: 25px !important; background-repeat: no-repeat !important; background-color: white !important; background-position: center !important; border-radius: 50% !important; } .bubble-icon-container ha-icon { display: none !important; }"
if info.image else ''
),
'card_mod': {
'style': (
'.bubble-state { font-size: 0 !important; ' + ('display: none !important; ' if not info.store else '') + '}'
+ ' .bubble-state::before { content: "' + (info.store if info.store else '') + '" !important; font-size: 11px !important; color: white !important}'
+ ' .bubble-state * { display: none !important; }'
+ ' .bubble-button-background { opacity: 1 !important; background: linear-gradient('
+ gradient
+ '); } .bubble-entity-picture { width: 25px !important; height: 25px !important; margin-top: 6px; }'
)
},
'sub_button': [
{
'name': (
((info.price | string) + ' €/' + (info.units if info.units else '') if info.price else (info.units if info.units else ''))
),
'show_name': true,
'show_icon': false,
'show_background': false
},
{
'icon': 'mdi:plus-thick',
'show_background': true,
'state_background': false,
'tap_action': {
'action': 'perform-action',
'perform_action': 'todo.add_item',
'target': { 'entity_id': 'todo.shopping_list' },
'data': { 'item': nombre }
}
},
{
'icon': 'mdi:minus-thick',
'show_background': true,
'state_background': false,
'tap_action': {
'action': 'perform-action',
'perform_action': 'todo.update_item',
'target': { 'entity_id': 'todo.shopping_list' },
'data': { 'item': nombre, 'status': 'completed' }
}
}
]
}
}},
{%- endif -%}
{%- endfor %}
{%- endfor -%}
Más ideas para domotizar tu lista de la compra
En el tiempo que llevamos jugando a domotizar tu lista de la compra hemos compartido un montón de ideas para crear automatizaciones, por ejemplo:
- Añade productos a la lista de forma automática, basándote en la información proporcionada por dispositivos integrados (por ejemplo, añade «Detergente» cada 50 ciclos de la lavadora) o en el periodo de maduración de productos que consumas de forma recurrente (por ejemplo, añade embutido una vez a la semana).
- Añade productos al escanear etiquetas NFC estratégicamente colocadas por tu casa para facilitarte el trabajo (por ejemplo, en las cajas de la despensa).
- Añade todos los productos de una receta ejecutando un ‘script’ compuesto por una secuencia de acciones que añade cada uno de sus ingredientes (y, si quieres, crea un libro de recetas en HA).
- Programa notificaciones cuando alguno de los miembros está en el supermercado, para añadir productos de última hora a la lista.

