Si andabas buscando una gran pantalla de tinta electrónica para tus paneles, en esta guía te enseño a integrar la Inkplate 10 en HA.
Índice
Pantallas de tinta electrónica
Hace poco configuré mi primera pantalla de tinta electrónica en Home Assistant, usando ESPHome. En ese proyecto utilizamos un display de 4.2″ y salió tan bien que había que llevarlo «a la gran pantalla» (nunca mejor dicho).

La Inkplate 10 es una pantalla de tinta electrónica de grandes dimensiones (9.7″ y 1200 x 820 pixels), frecuencia de actualización de 1.61s, modo de escala de grises y compatibilidad con actualizaciones parciales. Funciona sobre una ESP32, con WiFi y Bluetooth. Incorpora lector de tarjetas microSD, GPIO adicionales y tiene soporte para I²C y SPI.
Todo ello la convierten en el dispositivo perfecto si te habías encaprichado con esconder un panel de control en un cuadro, porque queda genial.
Requisitos previos
Para integrar la Inkplate 10 en HA previamente necesitas:
- Una pantalla de tinta electrónica Inkplate 10.
- Haber instalado ESPHome en Home Assistant.
- Opcionalmente (aunque me parece el broche final), un marco para tu placa.
Configuración de ESPHome
Ahora tenemos que ‘flashear’ la pantala con ESPHome y la configuración correspondiente, que vamos a extraer directamente de la documentación sobre el componente Inkplate. Para ello sigue estos pasos:
- Conecta la pantalla a tu ordenador a través del puerto USB-C, usando el cable que viene con la misma.
- En Home Assistant, accede al complemento de ESPHome desde el menú lateral y pulsa en “New device”. Pulsa en “Continue” y dale un nombre (por ejemplo, “Inkplate”).
- Pulsa en “Next” y a continuación selecciona la opción “ESP32” como tipo de dispositivo. Verás que en el fondo se ha creado un nuevo dispositivo.
- Pulsa en “Skip” y haz clic en el enlace “Edit” del bloque correspondiente al dispositivo que acabas de crear.
- Añade las siguientes líneas al final del código.
captive_portal:
i2c:
time:
- platform: pcf85063
id: esptime
# repeated synchronization is not necessary unless the external RTC
# is much more accurate than the internal clock
update_interval: never
- platform: homeassistant
# instead try to synchronize via network repeatedly ...
on_time_sync:
then:
# ... and update the RTC when the synchronization was successful
pcf85063.write_time:
pca6416a:
- id: pca6416a_hub
address: 0x20
# Primary expander for display control and additional I/O
- id: pca6416a_hub2
address: 0x21
# Secondary expander for additional I/O
switch:
- platform: gpio
id: battery_read_mosfet
pin:
pca6416a: pca6416a_hub
number: 9
sensor:
- platform: adc
id: battery_voltage
update_interval: never
attenuation: 12db
pin: 35
- platform: template
name: "Inkplate Battery Voltage"
unit_of_measurement: "V"
accuracy_decimals: 3
lambda: |-
// Enable MOSFET to connect battery voltage divider
id(battery_read_mosfet).turn_on();
// Wait for voltage to stabilize
delay(5);
// Sample ADC value
float adc = id(battery_voltage).sample();
// Disable MOSFET to save power
id(battery_read_mosfet).turn_off();
return adc;
filters:
- multiply: 2 # Compensate for voltage divider (1:2 ratio)
display:
- platform: inkplate6
id: inkplate_display
greyscale: false
partial_updating: false
update_interval: 60s
model: inkplate_10
lambda: |-
it.fill(COLOR_WHITE); // Fondo blanco
it.printf(20, 100, id(my_font), COLOR_BLACK, "Hola, aguacateros!");
ckv_pin: 32
sph_pin: 33
gmod_pin:
pca6416a: pca6416a_hub
number: 1
gpio0_enable_pin:
pca6416a: pca6416a_hub
number: 8
oe_pin:
pca6416a: pca6416a_hub
number: 0
spv_pin:
pca6416a: pca6416a_hub
number: 2
powerup_pin:
pca6416a: pca6416a_hub
number: 4
wakeup_pin:
pca6416a: pca6416a_hub
number: 3
vcom_pin:
pca6416a: pca6416a_hub
number: 5
font:
- file: "gfonts://Roboto"
id: my_font
size: 80
- Cuando hayas terminado de editar el código pulsa en “Save” e “Install”. Selecciona la opción “Manual download” y espera a que el código se compile.
- Cuando termine, selecciona la opción “Modern format” para descargar el fichero ‘.bin’ correspondiente.
- 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 7. 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.
- Tras esperar unos segundos deberías ver el siguiente mensaje en pantalla. A partir de aquí, los resultados dependen de tu creatividad!

Ejemplo práctico
Como siempre, tras integrar la Inkplate 10 en HA, lo primero que he hecho es ponerme a diseñar un panel de ejemplo. Aprovechando las grandes dimensiones de la pantalla, esta vez he querido utilizarla para crear un «cuadro inteligente».
substitutions:
# Device customization
# Personalización del dispositivo
name: inkplate
friendly_name: Inkplate
main_image: https://aguacatec.es/wp-content/uploads/2025/04/eink-1.jpg
# Entities / Entidades
sensor_temperature: sensor.openweathermap_temperature
sensor_home_temperature: sensor.home_temperatura
sensor_home_humidity: sensor.home_humedad
calendar: calendar.aguacatec
# Other settings / Otros ajustes
allowed_characters: " ¿?¡!#%'()+,-./:°0123456789ABCDEFGHIJKLMNOPQRSTUVWYZabcdefghijklmnopqrstuvwxyzáéíóú"
################################################################################################################
esphome:
name: ${name}
friendly_name: ${friendly_name}
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "st+Y49mRdasffds5445L7UeFNS34534fdu5U="
ota:
- platform: esphome
password: "sdffsd0f904e6da9ca5fe3243244"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Inkplate Fallback Hotspot"
password: "Stdsfsdf543Rrp"
captive_portal:
i2c:
time:
- platform: pcf85063
id: esptime
# repeated synchronization is not necessary unless the external RTC
# is much more accurate than the internal clock
update_interval: never
- platform: homeassistant
# instead try to synchronize via network repeatedly ...
on_time_sync:
then:
# ... and update the RTC when the synchronization was successful
pcf85063.write_time:
pca6416a:
- id: pca6416a_hub
address: 0x20
# Primary expander for display control and additional I/O
- id: pca6416a_hub2
address: 0x21
# Secondary expander for additional I/O
switch:
- platform: gpio
id: battery_read_mosfet
pin:
pca6416a: pca6416a_hub
number: 9
sensor:
- platform: adc
id: battery_voltage
update_interval: never
attenuation: 12db
pin: 35
- platform: template
name: "Inkplate Battery Voltage"
unit_of_measurement: "V"
accuracy_decimals: 3
lambda: |-
// Enable MOSFET to connect battery voltage divider
id(battery_read_mosfet).turn_on();
// Wait for voltage to stabilize
delay(5);
// Sample ADC value
float adc = id(battery_voltage).sample();
// Disable MOSFET to save power
id(battery_read_mosfet).turn_off();
return adc;
filters:
- multiply: 2 # Compensate for voltage divider (1:2 ratio)
- platform: homeassistant
id: sensor_temperature
entity_id: ${sensor_temperature}
internal: true
- platform: homeassistant
id: sensor_home_temperature
entity_id: ${sensor_home_temperature}
internal: true
- platform: homeassistant
id: sensor_home_humidity
entity_id: ${sensor_home_humidity}
internal: true
text_sensor:
- platform: homeassistant
id: calendar_event
entity_id: ${calendar}
attribute: message
internal: true
- platform: homeassistant
id: calendar_time
entity_id: ${calendar}
attribute: start_time
internal: true
font:
- file: "gfonts://Lobster"
id: font_title
size: 90
glyphs: ${allowed_characters}
- file: "gfonts://Lobster"
id: font_subtitle
size: 35
glyphs: ${allowed_characters}
- file: "gfonts://Kanit"
id: font_data
size: 40
glyphs: ${allowed_characters}
- file: "gfonts://Kanit"
id: font_day
size: 70
glyphs: ${allowed_characters}
- file: "gfonts://Kanit"
id: font_date
size: 20
glyphs: ${allowed_characters}
- file: "gfonts://Exo 2"
id: font_calendar
size: 40
glyphs: ${allowed_characters}
- file: "gfonts://Raleway"
id: font_event
size: 25
glyphs: ${allowed_characters}
image:
- file: mdi:weather-partly-cloudy
id: icon_temperature
resize: 50x50
type: BINARY
transparency: chroma_key
- file: mdi:home-thermometer
id: icon_home_temperature
resize: 50x50
type: BINARY
transparency: chroma_key
- file: mdi:water-percent
id: icon_humidity
resize: 50x50
type: BINARY
transparency: chroma_key
- file: ${main_image}
id: wallpaper
resize: 900x564
type: BINARY
transparency: chroma_key
- file: mdi:calendar-blank
id: icon_calendar
resize: 200x200
type: BINARY
transparency: chroma_key
display:
- platform: inkplate6
id: inkplate_display
greyscale: false
partial_updating: false
update_interval: 60s
model: inkplate_10
rotation: 270
lambda: |-
it.fill(Color::BLACK);
it.printf(410, 120, id(font_title), TextAlign::CENTER, "Home, Sweet Home");
it.printf(580, 160, id(font_subtitle), "Assistant");
it.image(80, 200, id(icon_temperature));
it.printf(140, 195, id(font_data), "%.0f°C", id(sensor_temperature).state);
it.image(215, 200, id(icon_home_temperature));
it.printf(275, 195, id(font_data), "%.0f°C", id(sensor_home_temperature).state);
it.image(365, 200, id(icon_humidity));
it.printf(415, 195, id(font_data), "%.0f%%", id(sensor_home_humidity).state);
it.image(-20, 330, id(wallpaper));
it.image(50, 950, id(icon_calendar));
it.strftime(150, 1050, id(font_day), TextAlign::CENTER, "%d", id(esptime).now());
it.strftime(150, 1088, id(font_date), TextAlign::CENTER, "%b / %y", id(esptime).now());
if (id(calendar_time).state.length() >= 16) {
std::string date = id(calendar_time).state.substr(8, 2); // Extrae el día (DD)
std::string month = id(calendar_time).state.substr(5, 2); // Extrae el mes (MM)
std::string hour = id(calendar_time).state.substr(11, 2); // Extrae la hora (HH)
std::string minute = id(calendar_time).state.substr(14, 2); // Extrae los minutos (MM)
// Mapea el número del mes a su nombre en español
std::map<std::string, std::string> month_names = {
{"01", "enero"}, {"02", "febrero"}, {"03", "marzo"}, {"04", "abril"},
{"05", "mayo"}, {"06", "junio"}, {"07", "julio"}, {"08", "agosto"},
{"09", "septiembre"}, {"10", "octubre"}, {"11", "noviembre"}, {"12", "diciembre"}
};
std::string month_name = month_names[month]; // Obtiene el nombre del mes
// Imprime el evento y la fecha formateada
it.printf(250, 1010, id(font_calendar), "%s", id(calendar_event).state.c_str());
it.printf(250, 1060, id(font_event), "Tendrá lugar el %s de %s, a las %s:%sh", date.c_str(), month_name.c_str(), hour.c_str(), minute.c_str());
}
ckv_pin: 32
sph_pin: 33
gmod_pin:
pca6416a: pca6416a_hub
number: 1
gpio0_enable_pin:
pca6416a: pca6416a_hub
number: 8
oe_pin:
pca6416a: pca6416a_hub
number: 0
spv_pin:
pca6416a: pca6416a_hub
number: 2
powerup_pin:
pca6416a: pca6416a_hub
number: 4
wakeup_pin:
pca6416a: pca6416a_hub
number: 3
vcom_pin:
pca6416a: pca6416a_hub
number: 5

