If it can help. With the help of Claude AI, we were able to set up a ESP32-4848S04C_I display to show inside/outside temp/humidity and the HA default weather actual state. It was quite a challenge. Next change will be to allow touch screen to change the weather actual state to the day's forecast.
The ESP32 configuration is as follow:
# ════════════════════════════════════════════════════════════════════
# Tableau de Bord ESPHome — ESP32-4848S040C_I (480×480, tactile)
# Affiche: Temp. intérieure, temp. extérieure, météo HA avec icônes
# ════════════════════════════════════════════════════════════════════
substitutions:
device_name: esp32-dashboard
friendly_name: "Tableau de Bord"
esphome:
name: ${device_name}
friendly_name: ${friendly_name}
platformio_options:
board_build.flash_mode: dio
board_upload.maximum_size: 16777216
on_boot:
priority: -100
then:
- light.turn_on:
id: backlight_light
brightness: 100%
# ─────────────────────────────────────────────────────────────────────
# ESP32-S3 — 16 Mo Flash, 8 Mo PSRAM OPI (requis pour LVGL + RGB LCD)
# ─────────────────────────────────────────────────────────────────────
esp32:
board: esp32-s3-devkitc-1
variant: esp32s3
flash_size: 16MB
framework:
type: esp-idf
version: recommended
sdkconfig_options:
CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y"
psram:
mode: octal
speed: 80MHz
# ─────────────────────────────────────────────────────────────────────
# Réseau & intégration
# ─────────────────────────────────────────────────────────────────────
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "${friendly_name} AP"
password: "configureme"
captive_portal:
logger:
level: DEBUG
hardware_uart: UART0 # libère GPIO19/GPIO20 du USB Serial JTAG
api:
encryption:
key: !secret api_encryption_key
ota:
- platform: esphome
password: !secret ota_password
# ─────────────────────────────────────────────────────────────────────
# I2C — Contrôleur tactile GT911
# SDA: GPIO19 / SCL: GPIO45 (vérifier selon révision de carte)
# ─────────────────────────────────────────────────────────────────────
i2c:
id: i2c_touch
sda: GPIO19
scl: GPIO45 # ✅ confirmé par source communautaire
scan: false
frequency: 10kHz
# ─────────────────────────────────────────────────────────────────────
# Rétroéclairage PWM (GPIO38)
# ─────────────────────────────────────────────────────────────────────
output:
- platform: ledc
id: backlight_output
pin: GPIO38
light:
- platform: monochromatic
id: backlight_light
name: "Rétroéclairage"
output: backlight_output
restore_mode: ALWAYS_ON
default_transition_length: 0s
# ─────────────────────────────────────────────────────────────────────
# Écran tactile GT911
# ─────────────────────────────────────────────────────────────────────
touchscreen:
- platform: gt911
id: touch_panel
i2c_id: i2c_touch
address: 0x14 # ✅ confirmé par le log précédent
# interrupt_pin retiré — GPIO18 utilisé par de_pin du display
# ─────────────────────────────────────────────────────────────────────
# Bus SPI — requis par st7701s. GPIO47/48 = init uniquement.
# miso_pin: GPIO41 requis par cette carte (confirmé par tests)
# ─────────────────────────────────────────────────────────────────────
spi:
clk_pin: GPIO48
mosi_pin: GPIO47
miso_pin: GPIO41
# ─────────────────────────────────────────────────────────────────────
# Affichage ST7701S — RGB 480×480
# ✅ Paramètres CONFIRMÉS par tests sur la carte physique
# ─────────────────────────────────────────────────────────────────────
display:
- platform: st7701s
id: main_display
update_interval: never
auto_clear_enabled: false
spi_mode: MODE3 # ✅ confirmé (MODE0 ne fonctionnait pas)
cs_pin: GPIO39
# reset_pin retiré — GPIO4 utilisé par data_pins red
dimensions:
width: 480
height: 480
color_order: RGB # ✅ confirmé (rouge = rouge)
invert_colors: false
pclk_frequency: 16MHz
pclk_pin: GPIO21 # ✅ confirmé
de_pin: GPIO18 # ✅ confirmé
vsync_pin: GPIO17 # ✅ confirmé
hsync_pin: GPIO16 # ✅ confirmé
hsync_front_porch: 10
hsync_pulse_width: 9
hsync_back_porch: 50
vsync_front_porch: 10
vsync_pulse_width: 9
vsync_back_porch: 20
data_pins: # ✅ confirmés par tests
blue:
- 11 # B1
- 12 # B2
- 13 # B3
- 14 # B4
- 0 # B5
green:
- 8 # G0
- 20 # G1
- 3 # G2
- 46 # G3
- 9 # G4
- 10 # G5
red:
- 4 # R1
- 5 # R2
- 6 # R3
- 7 # R4
- 15 # R5
# ─────────────────────────────────────────────────────────────────────
# Polices de caractères
# Roboto: via Google Fonts (téléchargé automatiquement à la compile)
# MDI : placer materialdesignicons-webfont.ttf dans /config/esphome/
# https://github.com/Templarian/MaterialDesign-Webfont/raw/master/fonts/materialdesignicons-webfont.ttf
# ─────────────────────────────────────────────────────────────────────
font:
- file: "gfonts://Roboto"
id: font_s # Textes secondaires
size: 16
- file: "gfonts://Roboto"
id: font_m # Labels
size: 22
- file: "gfonts://Roboto"
id: font_l # Valeurs
size: 38
- file: "gfonts://Roboto"
id: font_xl # Températures principales
size: 58
- file: "gfonts://Roboto"
id: font_clock # Horloge
size: 46
glyphs: "0123456789:"
# Icônes météo MDI (taille grande — carte météo)
- file: "materialdesignicons-webfont.ttf"
id: mdi_large
size: 88
glyphs:
- "\U000F0599" # weather-sunny
- "\U000F0594" # weather-night
- "\U000F0595" # weather-partly-cloudy
- "\U000F0590" # weather-cloudy
- "\U000F0591" # weather-fog
- "\U000F0597" # weather-rainy
- "\U000F0596" # weather-pouring
- "\U000F0F36" # weather-snowy
- "\U000F067F" # weather-snowy-rainy
- "\U000F0592" # weather-hail
- "\U000F0593" # weather-lightning
- "\U000F059F" # weather-lightning-rainy
- "\U000F059D" # weather-windy
- "\U000F059E" # weather-windy-variant
- "\U000F0F38" # weather-dust / exceptionnel
# Icônes MDI petites (étiquettes de cartes)
- file: "materialdesignicons-webfont.ttf"
id: mdi_small
size: 22
glyphs:
- "\U000F050F" # thermometer
- "\U000F058E" # water-percent (humidité)
- "\U000F059D" # weather-windy
- "\U000F0590" # weather-cloudy
# ─────────────────────────────────────────────────────────────────────
# Heure SNTP
# ─────────────────────────────────────────────────────────────────────
time:
- platform: sntp
id: sntp_time
timezone: "America/Toronto" # Montréal = America/Toronto
servers:
- 0.ca.pool.ntp.org
- 1.pool.ntp.org
on_time:
# Mise à jour de l'horloge toutes les minutes
- seconds: 0
then:
- lvgl.label.update:
id: lbl_time
text: !lambda |-
return id(sntp_time).now().strftime("%H:%M");
# Mise à jour de la date toutes les 30 s (rattrape le démarrage)
- seconds: /30
then:
- lvgl.label.update:
id: lbl_date
text: !lambda |-
static const char* jours[] =
{"Dim","Lun","Mar","Mer","Jeu","Ven","Sam"};
static const char* mois[] =
{"Jan","Fev","Mar","Avr","Mai","Jun",
"Jul","Aou","Sep","Oct","Nov","Dec"};
auto t = id(sntp_time).now();
if (!t.is_valid()) return std::string("---");
char buf[24];
snprintf(buf, sizeof(buf), "%s %d %s",
jours[t.day_of_week], t.day_of_month, mois[t.month - 1]);
return std::string(buf);
# ─────────────────────────────────────────────────────────────────────
# Capteurs Home Assistant
# ─────────────────────────────────────────────────────────────────────
sensor:
# ── Température intérieure (capteur 433 MHz) ──────────────────────
- platform: homeassistant
id: temp_int
entity_id: sensor.rtl433_2029_temperature
unit_of_measurement: "°C"
on_value:
then:
- lvgl.label.update:
id: lbl_temp_int
text:
format: "%.1f°"
args: [ x ]
# ── Température extérieure (capteur 433 MHz) ──────────────────────
- platform: homeassistant
id: temp_ext
entity_id: sensor.rtl433_79_temperature
unit_of_measurement: "°C"
on_value:
then:
- lvgl.label.update:
id: lbl_temp_ext
text:
format: "%.1f°"
args: [ x ]
# ── Humidité intérieure (capteur 433 MHz) ────────────────────────
- platform: homeassistant
id: hum_int
entity_id: sensor.rtl433_2029_humidity
unit_of_measurement: "%"
on_value:
then:
- lvgl.label.update:
id: lbl_hum_int
text:
format: "%.0f%%"
args: [ x ]
# ── Humidité extérieure (capteur 433 MHz) ────────────────────────
- platform: homeassistant
id: hum_ext
entity_id: sensor.rtl433_79_humidity
unit_of_measurement: "%"
on_value:
then:
- lvgl.label.update:
id: lbl_hum_ext
text:
format: "%.0f%%"
args: [ x ]
# ── Attributs de weather.forecast_maison ─────────────────────────
- platform: homeassistant
id: weather_temp
entity_id: weather.forecast_maison
attribute: temperature
on_value:
then:
- lvgl.label.update:
id: lbl_weather_temp
text:
format: "%.0f°C"
args: [ x ]
- platform: homeassistant
id: weather_humidity
entity_id: weather.forecast_maison
attribute: humidity
on_value:
then:
- lvgl.label.update:
id: lbl_weather_hum
text:
format: "%.0f%%"
args: [ x ]
- platform: homeassistant
id: weather_wind
entity_id: weather.forecast_maison
attribute: wind_speed
on_value:
then:
- lvgl.label.update:
id: lbl_weather_wind
text:
format: "%.0f km/h"
args: [ x ]
- platform: homeassistant
id: weather_pressure
entity_id: weather.forecast_maison
attribute: pressure
on_value:
then:
- lvgl.label.update:
id: lbl_weather_pressure
text:
format: "%.0f hPa"
args: [ x ]
# ── État météo + icône mappée ─────────────────────────────────────────
text_sensor:
- platform: homeassistant
id: weather_condition
entity_id: weather.forecast_maison
on_value:
then:
- lambda: |-
// ── Correspondance condition HA → icône MDI + libellé FR ──
struct WeatherMap {
const char* state;
const char* icon;
const char* label_fr;
};
static const WeatherMap table[] = {
{ "sunny", "\U000F0599", "Ensoleille" },
{ "clear-night", "\U000F0594", "Nuit claire" },
{ "partlycloudy", "\U000F0595", "Partiell. nuageux" },
{ "cloudy", "\U000F0590", "Nuageux" },
{ "fog", "\U000F0591", "Brouillard" },
{ "rainy", "\U000F0597", "Pluie" },
{ "pouring", "\U000F0596", "Forte pluie" },
{ "snowy", "\U000F0F36", "Neige" },
{ "snowy-rainy", "\U000F067F", "Pluie/Neige" },
{ "hail", "\U000F0592", "Grele" },
{ "lightning", "\U000F0593", "Orage" },
{ "lightning-rainy", "\U000F059F", "Orage et pluie" },
{ "windy", "\U000F059D", "Venteux" },
{ "windy-variant", "\U000F059E", "Tres venteux" },
{ "exceptional", "\U000F0F38", "Exceptionnel" },
};
const char* icon = "\U000F0599"; // défaut: soleil
const char* label = "Inconnu";
for (auto& e : table) {
if (x == e.state) { icon = e.icon; label = e.label_fr; break; }
}
lv_label_set_text(id(lbl_weather_icon), icon);
lv_label_set_text(id(lbl_weather_cond), label);
# ─────────────────────────────────────────────────────────────────────
# Interface LVGL — Tableau de bord 480×480
# ─────────────────────────────────────────────────────────────────────
lvgl:
displays:
- main_display
touchscreens:
- touch_panel
color_depth: 16
bg_color: 0x0D1117 # fond quasi-noir
# ── Styles réutilisables ─────────────────────────────────────────
style_definitions:
- id: style_card
bg_color: 0x161B22
bg_opa: COVER
border_color: 0x30363D
border_width: 1
radius: 14
shadow_width: 10
shadow_color: 0x000000
shadow_opa: 80%
pad_all: 14
- id: style_label_sec
text_color: 0x8B949E
text_font: font_s
- id: style_value_int
text_color: 0xFFD700
text_font: font_xl
- id: style_value_ext
text_color: 0x58A6FF
text_font: font_xl
pages:
- id: page_main
bg_color: 0x0D1117
widgets:
# ════════════════════════════════════════
# EN-TÊTE (bande du haut 480×62)
# ════════════════════════════════════════
- obj:
x: 0
y: 0
width: 480
height: 62
bg_color: 0x161B22
border_width: 0
radius: 0
pad_all: 0
widgets:
- label:
id: lbl_title
text: "Maison"
align: LEFT_MID
x: 18
text_font: font_m
text_color: 0x58A6FF
- label:
id: lbl_date
text: "---"
align: CENTER
text_font: font_s
text_color: 0x8B949E
- label:
id: lbl_time
text: "--:--"
align: RIGHT_MID
x: -18
text_font: font_clock
text_color: 0xE6EDF3
# ════════════════════════════════════════
# CARTE — Température + Humidité Intérieure
# Position: colonne gauche, ligne 1
# ════════════════════════════════════════
- obj:
styles: style_card
x: 10
y: 70
width: 224
height: 170
widgets:
- label:
text: "Interieur"
align: TOP_LEFT
text_font: font_s
text_color: 0x8B949E
- label:
id: lbl_temp_int
text: "--°"
align: TOP_LEFT
y: 22
text_font: font_l
text_color: 0xFFD700
# Ligne humidité (icône + valeur)
- label:
text: "\U000F058E"
align: TOP_LEFT
y: 78
text_font: mdi_small
text_color: 0x58A6FF
- label:
id: lbl_hum_int
text: "--%"
align: TOP_LEFT
x: 28
y: 80
text_font: font_m
text_color: 0xE6EDF3
- label:
text: "rtl433 #2029"
align: BOTTOM_LEFT
text_font: font_s
text_color: 0x484F58
# ════════════════════════════════════════
# CARTE — Température + Humidité Extérieure
# Position: colonne droite, ligne 1
# ════════════════════════════════════════
- obj:
styles: style_card
x: 246
y: 70
width: 224
height: 170
widgets:
- label:
text: "Exterieur"
align: TOP_LEFT
text_font: font_s
text_color: 0x8B949E
- label:
id: lbl_temp_ext
text: "--°"
align: TOP_LEFT
y: 22
text_font: font_l
text_color: 0x58A6FF
# Ligne humidité (icône + valeur)
- label:
text: "\U000F058E"
align: TOP_LEFT
y: 78
text_font: mdi_small
text_color: 0x58A6FF
- label:
id: lbl_hum_ext
text: "--%"
align: TOP_LEFT
x: 28
y: 80
text_font: font_m
text_color: 0xE6EDF3
- label:
text: "rtl433 #79"
align: BOTTOM_LEFT
text_font: font_s
text_color: 0x484F58
# ════════════════════════════════════════
# CARTE — Météo (grande, pleine largeur)
# Position: ligne 2, toute la largeur
# ════════════════════════════════════════
- obj:
styles: style_card
x: 10
y: 250
width: 460
height: 220
widgets:
# Titre de la carte
- label:
text: "Meteo — Prevision maison"
align: TOP_LEFT
text_font: font_s
text_color: 0x8B949E
# Icône météo MDI (grande, côté gauche)
- label:
id: lbl_weather_icon
text: "\U000F0599"
align: LEFT_MID
x: 4
y: 12
text_font: mdi_large
text_color: 0xFFD700
# ── Bloc infos météo (à droite de l'icône) ──────────────
# Condition en texte
- label:
id: lbl_weather_cond
text: "Chargement..."
x: 114
y: 44
text_font: font_m
text_color: 0xE6EDF3
# Température météo (grande)
- label:
id: lbl_weather_temp
text: "--°C"
x: 114
y: 72
text_font: font_l
text_color: 0xFFD700
# Séparateur visuel
- line:
points:
- x: 106
y: 130
- x: 448
y: 130
line_color: 0x30363D
line_width: 1
# Humidité
- label:
text: "\U000F058E"
x: 108
y: 140
text_font: mdi_small
text_color: 0x58A6FF
- label:
id: lbl_weather_hum
text: "--%"
x: 136
y: 142
text_font: font_s
text_color: 0x8B949E
# Vent
- label:
text: "\U000F059D"
x: 220
y: 140
text_font: mdi_small
text_color: 0x58A6FF
- label:
id: lbl_weather_wind
text: "-- km/h"
x: 248
y: 142
text_font: font_s
text_color: 0x8B949E
# Pression
- label:
text: "\U000F0590"
x: 108
y: 168
text_font: mdi_small
text_color: 0x58A6FF
- label:
id: lbl_weather_pressure
text: "-- hPa"
x: 136
y: 170
text_font: font_s
text_color: 0x8B949E
