Ecran tactile Nextion avec ESPHome

Il peut être très pratique d’installer un petit afficheur tactile la ou c’est utile (thermostat, pilotage d’une chaudière, météo, etc). C’est ce que j’ai fait en mettant un afficheur vers la porte d’accès ou jardin pour gérer la piscine et les éclairages extérieurs :

  • Affichage des températures de l’extérieur, de l’eau et de l’abri (piscine sous abri)
  • Affichage d’éventuelles alertes
  • Gestion de l’ouverture et fermeture du volet de la piscine, allumage des spots
  • Gestion des différentes lumières extérieures

ecrans

Je vous propose ici une description de mon implémentation à base d’un Nextion 2.8 pouces, pour un coût inférieur à 30€. ESPHome est vraiment très puissant, permet des mises à jour en ligne. Cela évite des flux complexes type nodered, comme le propose certains tutos.

Je partage l’ensemble du code et des fichiers ici :
Lien GitHub

1. Le matériel

L’afficheur est un Nextion 2.8 pouces de référence NX3224F08.
Aliexpress : nextion 2.8

J’utilise un ESP8266 Wemos D1.
Aliexpress : wemos d1 mini

Seules les connecteurs de la liaison série (TX et RX) ainsi que le 5v et la terre sont soudés, puis retournés pour ne pas prendre de place.

La connexion de l’afficheur est simple :

  • Liaison série du wemos sur liaison série du nextion (entrée de l’un sur sortie de l’autre : TX afficheur connecté à RX wemos, RX afficheur connecté à TX wemos).
  • Afficheur alimenté par les sorties terre - 5v du wemos
  • Le wemos est lui alimenté par un cable micro-usb

J’ai conçu et imprimé un boitier avec une imprimante 3d :

Je partage les fichiers d’impression sur cult3d
Cult3d - boitier pour Nextion 2.8

Enfin, pour avoir le rendu d’un produit du commerce, j’utilise une résine UV de lissage PolyPrint, sans odeur et qui donne de fabuleux résultats.

image

La résine peut être appliquée au pinceau. Puis on éclaire 10s chaque surface avec une torche UV et la résine est immédiatement dure. Juste faire un petit ponçage avant et après l’application de la résine.
Enfin j’ai peint le boitier avec une bombe de peinture acrylique blanche qui peut se trouver dans n’importe quel magasin de bricolage.

Polyprint vend un kit avec un pot de lissage, un autre de colmatage et la lampe UV :
Résine UV lissage Polyprint Equalizer

2. Le design de l’interface

Le design est assez facile : Nextion fournit un éditeur téléchargeable ici.
Nextion editor

Tous les éléments graphiques (fond, icones) doivent être téléchargés dans le carré en bas à gauche, rubrique « picture ».
Un fond de 240 x 320 pixels doit en particulier est chargé au préalable. Vous pouvez réutilisez le fond noir de mon GitHub.

Ensuite, il faut créer ou charger les polices que vous utiliserez. Reprendre celle de mon github ou les créer en utilisant le menu tools - font generator. Les polices dispos sont dans le carré en bas à gauche, rubrique « Font ».

Ensuite vous pouvez créer les pages de votre application, et y créer les différents éléments.
Dans les attributs de chaque éléments, quelques astuces :

  • mettre un objname (nom court) pour le référencer dans ESPHome.
  • mettre vscope à global pour qu’il soit actif quelque soit la page affichée
  • attribut sta à « crop image » et préciser dans pic le fond utilisé
  • utiliser le browser pour renseigner les différents id (police, images, pages…).
  • les textes sont saisis en cliquant sur « multiline… » et non directement dans le champs.

Dans le carré « event » à gauche du carré « attributs », il est possible de mettre du code qui sera exécuté dans le nextion. On mettra par exemple « page volet » pour le bouton volet, pour ouvrir une page dont le nom est « volet ».

L’afficheur peut être testé en cliquant dans la barre d’outils sur « debug ». Vous serez averti si un champs obligatoire manque dans les attributs (id d’une police par exemple).

Enfin, il ne reste plus qu’à charger le fichier (format TFT) sur le nextion. Pour cela, cliquer sur file / TFT File Output et télécharger le fichier sur une carte micro SD (utiliser un adaptateur USB - micro SD). Puis insérer la carte micro SD dans le nextion et allumer le : le fichier sera alors chargé.
Par la suite, il sera possible de téléverser un nouveau fichier en wifi et nous verrons plus loin comment.

3. Paramétrage ESPHome

Il faut créer un nouveau composant dans ESPHome. J’utilise maintenant ESPHome Web et avais décrit la procédure ici (avec référence au tuto de @McFly).
Utilisation ESPHome web pour de nouveaux composants

Voici les paramètres de base, sans composant connecté.

esphome:
  name: esp-nextion

esp8266:
  board: d1

ota:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

logger:
  baud_rate: 0

http_request:

uart:
  rx_pin: GPIO3
  tx_pin: GPIO01
  baud_rate: 9600

api:
  services:
    - service: update_tft
      then:
        - lambda: 'id(esp_nextion)->upload_tft();'

display:
  - platform: nextion
    id: esp_nextion
    update_interval: 60s   # Pas de réel besoin de rafraichissement
    touch_sleep_timeout: 180
    wake_up_page: 0
    tft_url: http://192.168.99.99:8123/local/nextion/nextion.tft
    brightness: 70%

Le code (service: update_tft et paramètre tft_url) permet de téléverser le code issu de l’éditeur nextion dans l’afficheur. Bien renseigner l’adresse de votre machine HA pour le paramètre tft_url.
Il faut mettre le fichier dans un répertoire sous HA .\config\www\nextion
Ensuite l’appel du service ESPHome: esp_nextion_update_tft lancera le transfert et la mise à jour. Très pratique quand l’afficheur sera dans son boitier et ne sera plus accessible.

touch_sleep_timeout: 180 permet de mettre en veille l’afficheur si il n’est pas utilisé pendant plus de 3 minutes. Il suffit alors de le toucher pour le réveiller.

wake_up_page: 0 permet de revenir à la première page quand l’afficheur est réveillé.

4. Programmation de l’affichage des températures

Un champs texte a été défini dans l’outil de création d’interface du nextion (ici « tempeau » pour la température de l’eau) . Une entrée de type « Nextion » est alors créée dans ESPHome pour reprendre la valeur d’une entité sensor, la formater avec 1 décimale et l’envoyée à l’afficheur, dans le champs texte tempeau.
Si on a plusieurs pages, on doit préfixer ce nom de champs par le nom de la page (ici « main.tempeau »).

sensor:
  - platform: homeassistant
    id: ha_temp_eau
    entity_id: sensor.fibaro_piscine_temperature_eau
    on_value:
      then:
        lambda: |-
          id(esp_nextion).set_component_text_printf("main.tempeau","%.1f",id(ha_temp_eau).state);

5. Programmation d’un texte d’alerte

Le texte peut être en vert ou rouge suivant si un input_boolean « alert » dans HA est actif ou non. Le texte a afficher est dans un input_texte dans HA.

# Texte d'information
text_sensor:
  - platform: homeassistant
    id: ha_info
    entity_id: input_text.nextion_message
    on_value:
      then:
        lambda: |-
          id(esp_nextion).set_component_text("main.info", id(ha_info).state.c_str() );
# Gestion de la couleur
binary_sensor:
  - platform: homeassistant
    id: ha_alerte
    entity_id: input_boolean.nextion_info_alerte
    on_state:
      then:
        lambda: |-
          if (x==1) {
            id(esp_nextion).set_component_font_color("main.info","63488");
          } else {
            id(esp_nextion).set_component_font_color("main.info","24260");
          }

6. Programmation d’un bouton à un état

L’appui sur le bouton « fermer la piscine » dans l’interface appelle un service dans HA qui ferme la piscine.

  - platform: nextion
    page_id: 1
    component_id: 7
    id: nx_ouvre_volet_piscine
    on_press:
      then:
        - homeassistant.service:
            service: cover.open_cover
            data:
              entity_id: cover.ipx800_volet_piscine

7. Programmation d’un bouton à 2 états pour les lumières

On utilise dans l’interface nextion un « dual state button ». Chaque état a une couleur (orange quand la lumière est allumée, gris autrement). La lumière peut être activée depuis l’interface du Nextion ou depuis HA. Il faut alors 2 entrées : 1 pour le nextion qui envoie l’ordre à HA si allumée depuis l’interface nextion, 1 pour HA qui envoie l’ordre à l’interface Nextion quand la lumière est allumée depuis HA. Je conseille de préfixer les entrées en fonction de la platform : le nom de l’entrée est ha_lum_plage pour l’entrée ha et nx_lum_plage pour l’entrée nextion.
Le code c (lambda) se déclenche sur événement de changement d’état.

  - platform: homeassistant
    id: ha_lum_plage
    entity_id: group.lumieres_plage
    on_state:
      then:
        lambda: |-
          if (id(ha_lum_plage).state) {
            id(esp_nextion).set_component_value("lumieres.bplage",1);
          } else {
            id(esp_nextion).set_component_value("lumieres.bplage",0);
          }

  - platform: nextion
    page_id: 2
    component_id: 10
    id: nx_lum_plage
    on_press:
      then:
        if:
          condition:
            lambda: 'return id(ha_lum_plage).state;'
          then:
            - homeassistant.service:
                service: switch.turn_off
                data:
                  entity_id: switch.ipx800_spots_terrasse
            - homeassistant.service:
                service: switch.turn_off
                data:
                  entity_id: switch.ipx800_lumiere_escalier_plage
          else:
            - homeassistant.service:
                service: switch.turn_on
                data:
                  entity_id: switch.ipx800_spots_terrasse
            - homeassistant.service:
                service: switch.turn_on
                data:
                  entity_id: switch.ipx800_lumiere_escalier_plage

9. Mise à jour de l’afficheur quand il est réveillé

Le code précédent permet les mises à jour quand le nextion est actif. Mais l’interface n’est pas mise à jour que le nextion est en veille. Il faut donc rajouter du code pour la mise à jour quand le nextion est réveillé. Certains tutos proposent une mise à jour toutes les 5s, mais ce ne sera pas nécessaire dans notre cas.

display:
  - platform: nextion
    id: esp_nextion
    update_interval: 60s   # Pas de réel besoin de raffraichissement
    touch_sleep_timeout: 180
    wake_up_page: 0
    tft_url: http://192.168.5.30:8123/local/nextion/nextion.tft
    brightness: 70%
    on_wake:
      then:
        # Initialisation avec les bonnes valeurs
        lambda: |-
          id(esp_nextion).set_component_text("info", id(ha_info).state.c_str() );
          if (id(ha_alerte).state == 1) {
            id(esp_nextion).set_component_font_color("main.info","63488");
          } else {
            id(esp_nextion).set_component_font_color("main.info","24260");
          }
    
          id(esp_nextion).set_component_text_printf("main.tempeau","%.1f",id(ha_temp_eau).state);
          id(esp_nextion).set_component_text_printf("main.tempabri","%.2f",id(ha_temp_abri).state);
          id(esp_nextion).set_component_text_printf("main.tempext","%.1f",id(ha_temp_ext).state);
    
          if (id(ha_spots_piscine).state) {
            id(esp_nextion).set_component_value("lumieres.bpiscine",1);
          } else {
            id(esp_nextion).set_component_value("lumieres.bpiscine",0);
          }
          if (id(ha_lum_plage).state) {
            id(esp_nextion).set_component_value("lumieres.bplage",1);
          } else {
            id(esp_nextion).set_component_value("lumieres.bplage",0);
          }
....etc....

Le code sera adapté suivant vos besoins. Il pourrait aussi être repris pour flasher un afficheur sonoff.
N’hésitez pas à proposer des évolutions ou partager vos propres implémentations.

11 « J'aime »

Super tuto complet et beau projet :+1:
Dommage qu’on ne puisse pas l’alimenter par pile, car en plus d’être compact on pourrait le poser à portée de main :sweat_smile:

Merci du partage, et félicitations pour ce beau travail. On ne te demande pas combien d’heures tu as dû y passer !!

1 « J'aime »

merci pour le tuto :slight_smile:
c’est vrai que la gestion de mes nextions par node red est assez volumineuse. en revanche je gère également la diffusion de radio web sur le GH choisi ( le google home de la sdb ou la cuisine par exemple) et je ne sais pas si tu faire cela via esp
comme ca :

Bon bah je vais refaire mes boitiers le tiens à l’air top :slight_smile:

2 « J'aime »

Merci pour ton retour.
Superbe ton interface !! Après il n’y pas de raisons de ne pas pouvoir le faire avec ESPHome : on peut gérer des boutons et afficher dynamiquement des images.
Je suis perso fan de ESPHome, qui rend les choses très simples et est facilement maintenable, tout en offrant la possibilité de faire du code C (lambda). Perso j’utilise les automatisations yaml et très peu nodered, mais je comprend qu’on puisse tout capitaliser sur nodered, qui offre une boite à outils juste énorme.
Pour info, arrives tu à déployer les mises à jour TFT de l’afficheur via le wifi ?

1 « J'aime »

(j ai pas vu que l on voyait mon tee shirt batman dans le reflet… Nerd powa lol)
J avoue ne pas avoir essayé la maj via wifi, je vais tester tantôt pour mettre à jour l écran de la salle de bain :slight_smile:

2 « J'aime »

Bjr; merci de votre tuto et je vais l’ essayer aussi:
Une question avec, je cherche une solution ’ bon prix’ pour visualiser soit un videostream soit un photo, l ’ idée est de montrer mon camera d’ entrée dans des chambres. Est-ce que vous savez d’ une solution pour le faire ?

1 « J'aime »

Oh j’ai trouver un nouveau projet. Ce qui manque dans tout notre domotique, c’est a mon avis la visualisation. Sa fait un moment que je cherche, un écran dans une boite qu’on peut placer n’importe ou pour afficher les données comme température, humidité ou autre. La tablette qui se trouve dans le salon est bien pour une utilisation si on veut allumer des lumières, descendre les stores etc, mais pour un affichage pur et simple…

Merci pour le tuto

1 « J'aime »

Bonjour à tous

J’aimerais utiliser un bouton lumière avec 2 états en fonction d’une commande sur le nextion ou sur HA . Est-ce possible à partir de ceci ? Si oui comment procéder ?

Merci d’avance


 platform: nextion
    page_id: 2
    component_id: 8
    id: btable
    on_press:
     then:
        - homeassistant.service:
           service: light.toggle
           data:
            entity_id: light.coin_repas_table 

Hello,
Cela est présenté dans le chapitre 7 de mon tuto

Salut

Je me suis replongé dans ESP :smile: et grâce à ton tuto j’ai réussi a paramétrer un bouton lumière avec deux états.

Merci encore pour cet excellent tuto.

A bientot

1 « J'aime »

Bonjour
Excellent article .
Je tente de créer mon premier écran en repartant de pas mal de lignes du votre.
Je sèche sur 2 points majeurs :
1: je veux ecrire une donnée au dessus d’une image; avec « text » sans l’option crop, ca marche mais cela fait un grand cadre autour du texte. avec l’option crop, j’ai une erreur de « parsing » au debug ce qui ensuite empêche le nextion de fonctionner.
en repartant de votre fichier, je peux utiliser sans et avec crop sans problème; avec le mien ca ne veut pas.
2: j’ai tenté plusieurs fois de telecharger le nextion depuis une commande HA. ca telecharge mais à la fin, le nextion est en erreur et n’affiche plus rien (sauf l’erreur).

Vous avez une idée ? une experience ?
Merci d’avance
Cdlt
Phil

Merci pour ton retour :smiley:

Pour le point 1, il faut bien vérifier les résolutions des images (reprendre les mêmes que les miennes). Il est impératif d’avoir un fond avec une résolution de 240 x 320 pixels.

Point 2 : quand tu dis « télécharger », j’imagine que ce n’est pas mettre à jour l’ESP via ESPHome, mais mettre à jour en OTA (wifi) le programme du nextion (fichier tft) ?

Si oui, le fichier tft doit être placé dans le répertoire config/www/nextion.
Vérifier qu’on peut le charger en tapant dans l’explorer son url
Par exemple : http://192.168.1.30:8123/local/nextion/nextion.tft

Ensuite on doit avoir 2 choses dans la config ESPHome

La création d’un service de mise à jour

api:
  services:
    - service: update_tft
      then:
        - lambda: 'id(esp_nextion)->upload_tft();'

Et enfin la déclaration de l’url du fichier dans le chapitre display :

display:
  - platform: nextion
    id: esp_nextion
    update_interval: 60s   # Pas de réel besoin de raffraichissement
    touch_sleep_timeout: 180
    wake_up_page: 0
    tft_url: http://192.168.1.30:8123/local/nextion/nextion.tft
    brightness: 70%

Ainsi, il sera possible d’appeler le service update_nextion depuis HA.
Plus d’infos ici

Bien redémarrer le nextion après la mise à jour.
En cas de pb, vérifier si le fichier tft est correct en le chargeant sur le nextion via un cable depuis le PC.

Bonjour et bonne année .
Pour le point 1, j’ai trouvé. Il faut indiquer l’image de fond dans la déclaration du texte. Donc ça c’est ok
Pour le point 2, le pb est effectivement la mise à jour du nextion depuis HA via ESPHome. Tout ce que vous décrivez fonctionne. Le nextion passe bien en upgrade comme si il était relié avec une interface usb / ttl. Le problème est que systématiquement l’écran affiche une erreur d’upload à la fin du processus . Et si je le débranche rebranche, il n’affiche qu’une ligne disant que son F/W est foiré. Heureusement qu’il suffit de le reloaded avec l’interface usb/ ttl ensuite !
Je soupçonne une raison: mon programme ESPHome envoi des données en automatique ( valeur de mon Linky) je soupçonne que pendant le chargement du F/W le téléchargement est interrompu voire foiré . Je vais ressayer en arrêtant ces process et je dirai si ça fonctionne. C’est une hypothèse car votre programme utilise la même logique en fait mais les maj sont peut être moins fréquentes.
Dans tous les cas, c’est un peu bloquant car l’écran sera dans une boîte ensuite et ce sera moins pratique de le mettre à jour voire de le déplanter sans tout ouvrir.
Il restera la solution se card qui n’a pas fonctionné pour l’instant ( l’écran me dit que ma sd n’est pas formatée en fat32alors qu’elle l’est)
Voilà un beau sujet en tous cas .

Prochaines étapes : faire une « gauge « ( ça parait simple) et un graphe en barres ( beaucoup moins simple)
Cordialement
Philippe

Merci et tous mes vœux également.
J’ai aussi le même besoin de ne pas avoir à ouvrir le boitier quand il faut faire une mise à jour.
J’espère que le problème vient effectivement d’interférences réseau, mais j’ai un doute. Il faudrait tester avec un tout petit fichier tft (le tien est peut être trop gros ?). Tiens nous au courant.

ps : on a l’habitude de se tutoyer sur le forum. Entre passionnés… :blush:

Pas de problème … je tutoie !
Alors j’ai coupé l’autre système qui génère l’arrivée des infos du Linky ( du gazpar et de l’eau ). J’étais en 115200 et le téléchargement du fichier vers le nextion a été quasi instantané et était bon .
Donc ma piste était bonne. Reste à trouver comment arrêter proprement cette arrivée de flux avant de lancer l’upgrade
Je suis repassé en 9600 après car de toutes façons l’ensemble a du mal a démarrer en 115200.
De même avec un Esp32 peut être faut il passer sur un autre uart que le 0 ….
Tout ça est en rodage. J’ai démarré l’ensemble hier seulement !

Pour le texte ce n’est pas terrible encore . C’est un tout tout premier jet !
Phil

1 « J'aime »

Hello
Je viens de refaire le test en 9600. En laissant les sensors tourner et de nouveau j’ai planté le nextion.
Dans la phase de téléchargement, j’ai vu quasi instantanément 95 %, ça bloque quelques secondes puis 99%, ça a rebloqué et finalement 100% avec une erreur sur l’écran.
Tu ne dois pas envoyer des données aussi souvent . Perso j’ai limite a des envois des infos du Linky toutes les 5 secondes mais ça doit suffire à perturber .
Je ne sais pas comment bloquer ça quand je lance l’upgrade.

Sinon pour les caractères, tu as du voir sur la photo que les blocs conservent soit un arrière plan vert, soit un fond d’image bizarre avec l’option « crop »
Tu peux m’en dire plus ?
Merci
Phil

Hello Phil,
J’ai aussi un ESP32 avec de la teleinfo (en 1200 baud, update toutes les 60s), mais je n’ai pas le pb d’interférence.
Pour désactiver, il faudrait exposer un service qui met en deepsleep pendant 2 mn. Cela se programme dans la config ESPHome mais je ne l’ai jamais fait.

Vérifie si ton fichier tft n’est pas trop lourd (image de fond trop lourde ?). Le miens fait 442k.

Mon Nextion est en 9600 bauds sur l’UART 0.
Mais question bête : as tu bien désactivé les logs sur le port série 0 ?

logger:
  baud_rate: 0

Pour le fond, j’ai créé une image qui a la bonne couleur de fond et l’ai sélectionnée dans le paramètre picc.
Tu devrais essayer de faire une image qu’avec du blanc, la mettre sous picture et sélectionner son id dans le paramètre picc du champs texte?

Hello
Je suis passé sur Uart2. Mais c’est le même resultat. J’ai trouvé des posts qui parlent du même problème (enfin du même resultat) mais les solutions ne sont pas claires.
Sur lUART0 j’ai bien le log a 0 mais ça valait le coup d’essayer.
Tant que le nextion est récupérable ……!
Pour la transparence oui je vais essayer pas mal de choses.
Merci encore
Phil

Bon alors je désespère !
Le bon côté est que j’ai réglé le problème d’affichage . En fait le mode crop n’est pas un mode transparent. Donc si on prend une image complexe comme fond, ça prend une moyenne pas belle comme fond du texte. Suivant ton conseil, j’ai chargé une image blanche que je n’utilise pas sauf comme référence de fond. Et ça ça fonctionne .

Pour l upgrade via HA, rien a faire. J’ai même tenté un autre esp. ça a marché une fois sans les données entrantes mais c’était par hasard.
Le protocole est tel que le téléchargement est très court quand il y a peu de modifs: dans ce cas, en 9600, ça coince instantanément @ 99 % a tous les coups . A 115200, ça a marché une fois mais pas une deuxième fois .
Si je fais une modification plus importante, c’est très très long et se coince aussi vers 99%

En fait le protocole fait que l’espace et le nextion rebootent à la fin du process. Il semble que l’esp reboot trop vite par rapport au nextion qui ne finit pas son activité .
C’est pour ça qu’en 118200, en téléchargeant le même fichier tft, ce soit tellement court que ça réussit de temps en temps
Suis je clair ?!
Peut être que mon nextion n’est pas clean ( je n’arrive pas à utiliser une carte Sd non plus …… il réclame une carte formatée en fat32 ce qui est le cas )
J’ai peut être récupère du rebut chez Ali !

Si tu as une autre piste, je suis preneur .
Je vais arrêter sur ce fill car ça pollue ta réalisation.
Amitiés
Phil