Hoy te enseño a integrar el SenseCAP Indicator en HA, y sacarle todo el provecho a sus componentes para explotarlo en tu instancia.
Índice
SenseCAP Indicator D1
El SenseCAP Indicator D1 es un producto desarrollado por Seeed Studio, fabricante que ya conocemos por otros magníficos productos como el ReSpeaker Lite, y distribuidor oficial de productos de Home Assistant. En concreto se trata de una pantalla táctil de 4 pulgadas (480 x 480 píxeles) que funciona impulsada por un sistema de doble microcontrolador (ESP32-S3 y RP2040), y admite comunicación Wi-Fi/BLE/LoRa.

En principio, se trata de un dispositivo pensado para medir la calidad del aire, ya que tiene sensores tVOC (SGP40) y CO2 (SCD41) integrados, y un sensor externo de temperatura y humedad (AHT20) que se conecta a través de su puerto Grove. También incorpora un ‘buzzer’ o zumbador (MLT-8530) y un lector de tarjetas Micro SD (no incluida). No obstante, también he visto otros usos para este dispositivo (como interactuar con ChatGPT).
💡 Por supuesto, puedes aprovechar su puerto Grove para conectar otro tipo de sensores.

Ten en cuenta que te acabo de describir las especificaciones de la versión más completa, pero puedes elegir aquella que más te convenga (y adaptar el precio). La diferencia entre las distintas versiones se detalla en esta tabla:

Requisitos previos
Para integrar el SenseCAP Indicator en HA previamente necesitas:
- Un SenseCAP Indicator, en alguna de sus versiones.
- Haber instalado MQTT en Home Assistant, si sigues el método «oficial».
- Haber instalado ESPHome en Home Assistant, si sigues nuestro método.
💡 Puedes encontrar todas las versiones disponibles en su página web.
Primeros pasos con el SenseCAP Indicator
Antes de integrar el SenseCAP Indicator en HA, vamos a ver qué podemos hacer con él con su configuración de serie:
- Saca la pantalla de la caja y conecta el sensor de temperatura y humedad en el puerto Grove derecho de la parte posterior. Utiliza el cable USB-C que viene en la caja para alimentarlo y este se encenderá automáticamente.
- Lo primero que verás en pantalla es que te solicita que selecciones tu red WiFi para conectarse. Como siempre, te recomiendo que asignes una IP fija en tu router para evitar fallos en el futuro si esta cambia.
- Hecho esto ya puedes volver a la pantalla inicial que muestra la fecha, hora y ubicación. Si te desplazas hacia los lados aparecerá el detalle de la calidad del aire, opciones de ajustes del dispositivo y para configurar tu cuenta de OpenAI.
- Si pulsas sobre cada uno de los bloques de información de calidad del aire encontrarás una gráfica de la evolución de los valores en las últimas 24 horas o la última semana.


Integración con Home Assistant
Como ves, el dispositivo es muy sencillo de utilizar. No obstante, me parece que el dispositivo es demasiado potente como para utilizarlo únicamente como un sensor de calidad del aire. Afortunadamente, podemos integrar el SenseCAP Indicator en HA, no sólo para visualizar sus valores en nuestro panel de control y utilizarlo en nuestras automatizaciones, también para controlar nuestros dispositivos desde su pantalla.
Para ello puedes seguir el proceso de la documentación oficial de Seeed Studio, flasheando el dispositivo con un firmware alternativo y utilizando MQTT. No osbtante, puesto que el dispositivo funciona sobre una placa ESP32-S3, en nuestro caso vamos a integrarlo usando ESPHome (así podrás usarlo para otras funciones, como detección de presencia con Bermuda).
💡 Si en algún momento quieres flashear el firmware original, sigue estas instrucciones de la documentación oficial.
Si quieres integrar el SenseCAP Indicator en HA a «nuestra manera», sigue estos pasos:
- En Home Assistant, ve a tu complemento de ESPHome, pulsa en “New device” y “Continue”.
- Dale un nombre a tu dispositivo (por ejemplo, “SenseCAP Indicator”) y pulsa en “Next”.
- Como tipo de dispositivo selecciona “ESP32-S3”. Observarás de fondo que se ha creado un nuevo bloque para tu dispositivo.
- Pulsa en “Skip” y haz clic en “Edit”, sobre el bloque de tu dispositivo. Copia el código que aparece y consérvalo, ya que vas a necesitar alguna parte del mismo.
- Copia el siguiente código y úsalo para reemplazar el código anterior en ESPHome.
substitutions:
# Device customization
# Personalización del dispositivo
name: sensecap-indicator
friendly_name: SenseCAP Indicator
# Example of Sensors
# Ejemplo de Sensores
sensor_temperature: sensor.openweathermap_temperature
# Example of Devices
# Ejemplo de Dispositivos
device1: light.tira_led_escritorio
device2: climate.salon
device3: switch.ventilador
device4: switch.impresora_3d
# Other settings
# Otros ajustes
allowed_characters: " ¿?¡!#%'()+,-./:°0123456789ABCDEFGHIJKLMNOPQRSTUVWYZabcdefghijklmnopqrstuvwxyzáéíóú"
################################################################################################################
esphome:
name: ${name}
friendly_name: ${friendly_name}
min_version: 2024.6.0
name_add_mac_suffix: false
platformio_options:
board_build.flash_mode: dio
build_unflags: -Werror=all
project:
name: esphome.web
version: dev
esp32:
board: esp32-s3-devkitc-1
framework:
type: esp-idf
# Required to achieve sufficient PSRAM bandwidth for screen graphics
sdkconfig_options:
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: y
CONFIG_ESP32S3_DATA_CACHE_64KB: y
CONFIG_SPIRAM_FETCH_INSTRUCTIONS: y
CONFIG_SPIRAM_RODATA: y
external_components:
- source:
type: git
url: https://github.com/tobi1449/esphome-sensecap-indicator-sensors.git
ref: main
components: [sensecap_indicator_sensors]
refresh: 1s
# Enable Home Assistant API
api:
encryption:
key: "E21VY8asjsa9823a4D2FGXod6fasdasd12"
# Allow Over-The-Air updates
ota:
- platform: esphome
password: "a0d023dfggdfb5b67b3f4bf17234df35"
# Allow provisioning Wi-Fi via serial
improv_serial:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Sensecap-Indicator"
password: "cC2sada45tS"
psram:
mode: octal
speed: 80MHz
logger:
level: DEBUG
hardware_uart: UART0
captive_portal:
binary_sensor:
- platform: touchscreen
name: "Previous Page"
internal: true
x_min: 0
x_max: 30
y_min: 0
y_max: 480
on_press:
then:
lvgl.page.previous:
- platform: touchscreen
name: "Next Page"
internal: true
x_min: 450
x_max: 480
y_min: 0
y_max: 480
on_press:
then:
lvgl.page.next:
font:
- file: "gfonts://Rubik"
id: font_clock
size: 75
glyphs: ${allowed_characters}
- file: "gfonts://Rubik"
id: font_date
size: 20
glyphs: ${allowed_characters}
- file: "gfonts://Material+Symbols+Outlined"
id: font_icons
size: 40
glyphs: [
"\U0000e846", # thermometer
"\U0000f87e", # humidity
"\U0000e7b0", # co2
"\U0000f55b", # pollution
"\U0000ea24", # bulb
"\U0000ea43", # fireplace
"\U0000f168", # fan
"\U0000e8ad", # printer
]
- file: "gfonts://Roboto"
id: font_button_value
size: 22
glyphs: ${allowed_characters}
- file: "gfonts://Roboto"
id: font_button
size: 18
glyphs: ${allowed_characters}
i2c:
sda: 39
scl: 40
scan: false
id: bus_a
image:
- file: https://img.icons8.com/?size=100&id=qA3w9Yp2vY7r&format=png&color=000000
id: icon_weather
resize: 70x70
type: RGB565
transparency: alpha_channel
light:
- platform: monochromatic
output: ledc_gpio4
name: Display Backlight
id: display_backlight
restore_mode: ALWAYS_ON
output:
- platform: ledc
pin:
number: GPIO45
ignore_strapping_warning: true
id: ledc_gpio4
frequency: 100Hz
pca9554:
- id: p_c_a
pin_count: 16
address: 0x20
sensor:
- platform: homeassistant
id: sensor_temperature
entity_id: ${sensor_temperature}
internal: true
on_value:
then:
- lvgl.label.update:
id: lbl_weather
text:
format: "%.0f°C"
args:
- id(sensor_temperature).state
- lvgl.label.update:
id: lbl_weather2
text:
format: "%.0f°C"
args:
- id(sensor_temperature).state
- platform: sensecap_indicator_sensors
temperature:
name: "Temperature"
id: sensor_temp
on_value:
then:
- lvgl.label.update:
id: lbl_button1_value
text:
format: "%.0f°C"
args:
- id(sensor_temp).state
humidity:
name: "Humidity"
id: sensor_humi
on_value:
then:
- lvgl.label.update:
id: lbl_button2_value
text:
format: "%.0f%%"
args:
- id(sensor_humi).state
co2:
name: "CO2"
id: sensor_co2
on_value:
then:
- lvgl.label.update:
id: lbl_button3_value
text:
format: "%.0f ppm"
args:
- id(sensor_co2).state
altitude: 405
tvoc:
name: "TVOC"
id: sensor_tvoc
on_value:
then:
- lvgl.label.update:
id: lbl_button4_value
text:
format: "%.0f ppb"
args:
- id(sensor_tvoc).state
spi:
- id: lcd_spi
clk_pin: 41
mosi_pin: 48
text_sensor:
- platform: homeassistant
id: device_1
entity_id: ${device1}
internal: true
on_value:
then:
- lvgl.label.update:
id: lbl_device1_state
text: !lambda |-
if (x == "on") {
return "Encendida";
} else {
return "Apagada";
}
- platform: homeassistant
id: device_2
entity_id: ${device2}
internal: true
on_value:
then:
- lvgl.label.update:
id: lbl_device2_state
text: !lambda |-
if (x == "on") {
return "Encendida";
} else {
return "Apagada";
}
- platform: homeassistant
id: device_3
entity_id: ${device3}
internal: true
on_value:
then:
- lvgl.label.update:
id: lbl_device3_state
text: !lambda |-
if (x == "on") {
return "Encendido";
} else {
return "Apagado";
}
- platform: homeassistant
id: device_4
entity_id: ${device4}
internal: true
on_value:
then:
- lvgl.label.update:
id: lbl_device4_state
text: !lambda |-
if (x == "on") {
return "Encendida";
} else {
return "Apagada";
}
time:
- platform: homeassistant
id: esptime
touchscreen:
- platform: ft5x06
id: ft5x06_touchscreen
transform:
mirror_x: true
mirror_y: true
on_release:
then:
- if:
condition: lvgl.is_paused
then:
- light.turn_on: display_backlight
- lvgl.resume:
- lvgl.widget.redraw:
uart:
tx_pin: 19
rx_pin: 20
baud_rate: 115200
display:
- platform: st7701s
auto_clear_enabled: false
update_interval: never
spi_mode: MODE3
color_order: RGB
dimensions:
width: 480
height: 480
invert_colors: true
transform:
mirror_x: true
mirror_y: true
cs_pin:
pca9554: p_c_a
number: 4
reset_pin:
pca9554: p_c_a
number: 5
de_pin: 18
hsync_pin: 16
vsync_pin: 17
pclk_pin: 21
# Init sequence can be one of the defaults and/or custom sequences.
init_sequence:
- 1 # select canned init sequence number 1
# Custom sequences are an array, first byte is command, the rest are data.
- [ 0xE0, 0x1F ] # Set sunlight readable enhancement
data_pins:
red:
- 4 #r1
- 3 #r2
- 2 #r3
- 1 #r4
- 0 #r5
green:
- 10 #g0
- 9 #g1
- 8 #g2
- 7 #g3
- 6 #g4
- 5 #g5
blue:
- 15 #b1
- 14 #b2
- 13 #b3
- 12 #b4
- 11 #b5
lvgl:
touchscreens: ft5x06_touchscreen
buffer_size: 100%
bg_color: 0x062e20
on_idle:
- timeout: 10s
then:
- logger.log: idle timeout
- if:
condition:
lvgl.is_idle:
timeout: 5s
then:
- logger.log: LVGL is idle
- timeout: 60s
then:
- logger.log: idle 60s timeout
- lvgl.pause:
- light.turn_off:
id: display_backlight
transition_length: 5s
# debugging info will write all the touchscreen taps and their x/y to console
log_level: INFO
color_depth: 16
style_definitions:
- id: style_button
width: 208
height: 145
bg_color: 0x042318
border_color: 0x042318
radius: 20
- id: style_button_icon
align: TOP_MID
text_font: font_icons
- id: style_button_value
align: CENTER
text_color: 0xffffff
text_font: font_button_value
pad_top: 25
- id: style_button_text
align: BOTTOM_MID
text_color: 0x57766b
text_font: font_button
pad_bottom: 10
pages:
- id: page_home
widgets:
- label:
align: TOP_LEFT
id: lbl_date
text: "00/00/0000"
text_color: 0x21c48e
text_font: font_date
pad_top: 20
pad_left: 30
- label:
align: TOP_LEFT
id: lbl_clock
text: "00:00"
text_color: 0xd3ebe3
text_font: font_clock
pad_top: 35
pad_left: 20
- label:
align: TOP_RIGHT
id: lbl_weather
text: "25°C"
text_color: 0x21c48e
text_font: font_date
pad_top: 20
pad_right: 30
- image:
align: TOP_RIGHT
src: icon_weather
pad_top: 45
pad_right: 20
- obj:
styles: style_button
x: 28
y: 148
widgets:
- label:
styles: style_button_icon
text: "\U0000e846"
text_color: 0xaee55f
- label:
styles: style_button_value
id: lbl_button1_value
text: "25°C"
- label:
styles: style_button_text
id: lbl_button1
text: "Temperatura"
- obj:
styles: style_button
x: 245
y: 148
widgets:
- label:
styles: style_button_icon
text: "\U0000f87e"
text_color: 0x5fb4e5
- label:
styles: style_button_value
id: lbl_button2_value
text: "45%"
- label:
styles: style_button_text
id: lbl_button2
text: "Humedad"
- obj:
styles: style_button
x: 28
y: 305
widgets:
- label:
styles: style_button_icon
text: "\U0000e7b0"
text_color: 0xa7a7a7
- label:
styles: style_button_value
id: lbl_button3_value
text: "1000 ppm"
- label:
styles: style_button_text
id: lbl_button3
text: "CO2"
- obj:
styles: style_button
x: 245
y: 305
widgets:
- label:
styles: style_button_icon
text: "\U0000f55b"
text_color: 0xe96fb4
- label:
styles: style_button_value
id: lbl_button4_value
text: "20 ppb"
- label:
styles: style_button_text
id: lbl_button4
text: "tVOC"
- id: page_devices
widgets:
- label:
align: TOP_LEFT
id: lbl_date2
text: "00/00/0000"
text_color: 0x21c48e
text_font: font_date
pad_top: 20
pad_left: 30
- label:
align: TOP_LEFT
id: lbl_clock2
text: "00:00"
text_color: 0xd3ebe3
text_font: font_clock
pad_top: 35
pad_left: 20
- label:
align: TOP_RIGHT
id: lbl_weather2
text: "25°C"
text_color: 0x21c48e
text_font: font_date
pad_top: 20
pad_right: 30
- image:
align: TOP_RIGHT
src: icon_weather
pad_top: 45
pad_right: 20
- obj:
styles: style_button
x: 28
y: 148
on_press:
then:
- homeassistant.action:
service: light.toggle
data:
entity_id: ${device1}
widgets:
- label:
styles: style_button_icon
text: "\U0000ea24"
text_color: 0xe9d96f
- label:
styles: style_button_value
id: lbl_button1_value2
text: "Escritorio"
- label:
styles: style_button_text
id: lbl_device1_state
text: "Apagado"
- obj:
styles: style_button
x: 245
y: 148
on_press:
then:
- homeassistant.action:
service: climate.toggle
data:
entity_id: ${device2}
widgets:
- label:
styles: style_button_icon
text: "\U0000ea43"
text_color: 0xe99d6f
- label:
styles: style_button_value
id: lbl_button2_value2
text: "Calefacción"
- label:
styles: style_button_text
id: lbl_device2_state
text: "Apagado"
- obj:
styles: style_button
bg_color: 0x042318
border_color: 0x042318
x: 28
y: 305
on_press:
then:
- homeassistant.action:
service: switch.toggle
data:
entity_id: ${device3}
widgets:
- label:
styles: style_button_icon
text: "\U0000f168"
text_color: 0xcde4f2
- label:
styles: style_button_value
id: lbl_button3_value2
text: "Ventilador"
- label:
styles: style_button_text
id: lbl_device3_state
text: "Apagado"
- obj:
styles: style_button
x: 245
y: 305
on_press:
then:
- homeassistant.action:
service: switch.toggle
data:
entity_id: ${device4}
widgets:
- label:
styles: style_button_icon
text: "\U0000e8ad"
text_color: 0xeeeeee
- label:
styles: style_button_value
id: lbl_button4_value2
text: "Impresora"
- label:
styles: style_button_text
id: lbl_device4_state
text: "Apagado"
interval:
- interval: 60s
then:
- lvgl.label.update:
id: lbl_date
text: !lambda 'return id(esptime).now().strftime("%d/%m/%y");'
- lvgl.label.update:
id: lbl_date2
text: !lambda 'return id(esptime).now().strftime("%d/%m/%y");'
- interval: 60s
then:
- lvgl.label.update:
id: lbl_clock
text: !lambda 'return id(esptime).now().strftime("%H:%M");'
- lvgl.label.update:
id: lbl_clock2
text: !lambda 'return id(esptime).now().strftime("%H:%M");'
- Parte importante. En este código no se han incluido las credenciales para que el dispositivo se conecte a tu WiFi y tu instancia de Home Assistant y tienes que incluirlas manualmente. En concreto me refiero a las siguientes líneas del código que has copiado en el paso 4.
# Enable Home Assistant API
api:
encryption:
key: "bg6hash6sjdjsdjk02hh0qnQeYVwm123vdfKE8BP5"
ota:
- platform: esphome
password: "asddasda27aab65a48484502b332f"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Assist Fallback Hotspot"
password: "ZsasdasdHGP2234"
- Lo que tienes que hacer es, encontrar las líneas correspondientes en el código (está al principio) y añadir la información correspondiente.
- Ahora sí, pulsa en “Save” e “Install”. Selecciona “Manual download” y espera a que se compile el código.
- Cuando termine, selecciona la opción “Modern format” para descargar el fichero ‘.bin’ correspondiente.
- Conecta el SenseCAP Indicator con el cable USB-C de datos por el puerto que trae en la parte trasera a tu ordenador.
- Ahora ve a la página de ESPHome y pulsa en “Connect”. En la ventana emergente selecciona tu placa y pulsa en “Conectar”.
- Ahora pulsa en “Install” y selecciona el fichero ‘.bin’ obtenido en el paso 9. De nuevo, pulsa en “Install”.
- Vuelve a Home Assistant y ve a Configuración > Dispositivos y servicios. Lo normal es que tu dispositivo haya sido descubierto y aparezca en la parte superior, esperando únicamente a que pulses el botón de “Configurar”. De lo contrario pulsa en el botón de “Añadir integración”, busca “ESPHome” e introduce la IP de tu placa en el campo ‘Host’. Como siempre, te recomiendo que asignes una IP fija en tu router para evitar fallos en el futuro si esta cambia.
- Para terminar ve a Configuración > Dispositivos y servicios > ESPHome. Pulsa sobre el enlace «Configurar» correspondiente tu dispositivo. En la ventana emergente marca la casilla «Permitir que el dispositivo realice acciones de Home Assistant» y pulsa en «Enviar». Esto va a permitir que podamos controlar nuestros dispositivos desde la pantalla.
🎨 Observa que puedes personalizar el dispositivo como quieras (colores, dispositivos, iconos...). Este es sólo un ejemplo para que te sirva de punto de partida!



Ofertas & Descuentos
Diseños 3D
Academia





























