ESPHome + LCD ili9341

MATERIEL

  • ESP32 sur Aliexpress [Lien]
  • LCD ILI9341 2.8 pouces [lien]
  • Cable femelle/femelle 10cm [lien]

CABLAGE

SCRIPT PYTHON

  • Infos du jour [lien]

CODE esp-affichage.yaml

time:
  - platform: homeassistant
    id: esptime

esphome:
  name: esp-affichage
  friendly_name: esp-affichage  
  
esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "X3tSsqsyHPK2e3KyiHHxgjgLQdDPPKAJYCf8b/JWLjo="

ota:
  password: "080de7bf5f81b03b41384214726ecc00"

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp-Affichage Fallback Hotspot"
    password: "Thj37Xq8iNsN"

captive_portal:
    # Example configuration entry

web_server:
  port: 80

psram:
  mode: octal
  speed: 80MHz

spi:
  clk_pin: GPIO18 # (Pin on display - SCK/T_CLK)
  mosi_pin: GPIO23 # (Pin on display - SDI(MOSI)/T_DIN)
  miso_pin: GPIO19 # (Pin on display - SDO(MISO)/T_DO)



display:
  - platform: ili9xxx  
    model: ili9341    

    rotation: 0
    cs_pin: GPIO15  # Broche CS (Chip Select)
    dc_pin: GPIO05  # Broche DC (Data/Command)
    reset_pin: GPIO04  # Broche de réinitialisation    
    dimensions: 320x240
    update_interval: 1s
    color_order: rgb

   
    id: my_display    
    pages:
      - id: page1
        lambda: |-
          auto cadre = Color(113, 113, 113);
          auto jaune = Color(250, 255, 143);
          auto bureau = Color(200, 255, 178);
          auto chambre = Color(178, 255, 226);
          auto ami = Color(178, 183, 255);
          auto cuisine = Color(255, 255, 178);
          auto avant = Color(251, 139, 255);
          auto arriere = Color(145, 255, 139);

          it.filled_rectangle(10, 20, 100, 100, bureau);
          it.filled_rectangle(110, 20, 100, 100, chambre);
          it.filled_rectangle(210, 20, 100, 100, ami);
          it.filled_rectangle(10, 120, 100, 100, cuisine);
          it.filled_rectangle(110, 120, 100, 100, avant);
          it.filled_rectangle(210, 120, 100, 100, arriere);


          it.rectangle(10, 20, 100, 100, cadre);
          it.rectangle(110, 20, 100, 100, cadre);
          it.rectangle(210, 20, 100, 100, cadre);

          it.rectangle(10, 120, 100, 100, cadre);
          it.rectangle(110, 120, 100, 100, cadre);
          it.rectangle(210, 120, 100, 100, cadre);

          it.print(42, 26, id(temperature), my_black, "\U000F07C0");          
          it.print(14, 60, id(material20), my_black, "\U000F050F");
          it.printf(26, 60, id(font_temperature), my_black, " %5.1f°", id(temperature_bureau).state);
          it.print(14, 80, id(material20), my_black, "\U000F1503");
          it.printf(26, 80, id(font_temperature), my_black, " %5.1f%%", id(hygro_bureau).state);
          it.print(14, 100, id(material20), my_black, "\U000F17E3");
          it.printf(26, 100, id(font_temperature), my_black, " %5.1f%%", id(batterie_bureau).state);
          
          it.print(142, 26, id(temperature), my_black, "\U000F0099");          
          it.print(114, 60, id(material20), my_black, "\U000F050F");
          it.printf(126, 60, id(font_temperature), my_black, " %5.1f°", id(temperature_chambre).state);
          it.print(114, 80, id(material20), my_black, "\U000F1503");
          it.printf(126, 80, id(font_temperature), my_black, " %5.1f%%", id(hygro_chambre).state);
          it.print(114, 100, id(material20), my_black, "\U000F17E3");
          it.printf(126, 100, id(font_temperature), my_black, " %5.1f%%", id(batterie_chambre).state);

          it.print(242, 26, id(temperature), my_black, "\U000F0097");          
          it.print(214, 60, id(material20), my_black, "\U000F050F");
          it.printf(226, 60, id(font_temperature), my_black, " %5.1f°", id(temperature_chambre_ami).state);
          it.print(214, 80, id(material20), my_black, "\U000F1503");
          it.printf(226, 80, id(font_temperature), my_black, " %5.1f%%", id(hygro_chambre_ami).state);
          it.print(214, 100, id(material20), my_black, "\U000F17E3");
          it.printf(226, 100, id(font_temperature), my_black, " %5.1f%%", id(batterie_chambre_ami).state);

          it.print(42, 126, id(temperature), my_black, "\U000F1061");          
          it.print(14, 160, id(material20), my_black, "\U000F050F");
          it.printf(26, 160, id(font_temperature), my_black, " %5.1f°", id(temperature_cuisine).state);
          it.print(14, 180, id(material20), my_black, "\U000F1503");
          it.printf(26, 180, id(font_temperature), my_black, " %5.1f%%", id(hygro_cuisine).state);
          it.print(14, 200, id(material20), my_black, "\U000F17E3");
          it.printf(26, 200, id(font_temperature), my_black, " %5.1f%%", id(batterie_cuisine).state);

          it.print(142, 126, id(temperature), my_black, "\U000F0F9B");          
          it.print(114, 160, id(material20), my_black, "\U000F050F");
          it.printf(126, 160, id(font_temperature), my_black, " %5.1f°", id(temperature_avant).state);

          it.print(242, 126, id(temperature), my_black, "\U000F09F0");          
          it.print(214, 160, id(material20), my_black, "\U000F050F");
          it.printf(226, 160, id(font_temperature), my_black, " %5.1f°", id(temperature_arriere).state);
          
      - id: page2
        lambda: |-
          auto white = Color(255, 255, 255);
          it.rectangle(0,  0, it.get_width(), it.get_height());
          it.strftime(70, 100, id(font_heure), TextAlign::BASELINE_LEFT, "%H:%M:%S", id(esptime).now());
          it.strftime(40, 160, id(font_heure), TextAlign::BASELINE_LEFT, "%d-%m-%Y", id(esptime).now()); 
          
          
          it.printf(40, 180, id(tempo3), my_white, "Aujourd'hui, nous faitons %s", id(saint_jour).state.c_str());
          it.printf(40, 196, id(tempo3), my_yellow, "Demain, nous faiterons %s", id(saint_demain).state.c_str());

          

      
      - id: page3
        lambda: |-
          it.image(2 , 2, id(edf_tempo));
          it.print(129, 22, id(tempo), my_white, "En ce moment");
          
          if (id(aujourdhui).state == "BLANC") { 
            it.filled_rectangle(9, 78, 142, 40, my_white);
            it.print(20, 87, id(tempo), my_black, "Aujourd'hui");
          }

          if (id(aujourdhui).state == "BLEU") { 
            it.filled_rectangle(9, 78, 142, 40, my_blue);
            it.print(20, 87, id(tempo), my_white, "Aujourd'hui");
          }

          if (id(aujourdhui).state == "ROUGE") { 
            it.filled_rectangle(9, 78, 142, 40, my_red);
            it.print(20, 87, id(tempo), my_white, "Aujourd'hui");
          }

          if (id(demain).state.substr(0, 3) == "Ind") { 
            it.filled_rectangle(169, 78, 142, 40, my_orange);          
            it.print(200, 87, id(tempo), my_black, "Demain");
          } 

          if (id(demain).state == "BLANC") { 
            it.filled_rectangle(169, 78, 142, 40, my_white);          
            it.print(200, 87, id(tempo), my_black, "Demain");
          }

          if (id(demain).state == "BLEU") { 
            it.filled_rectangle(169, 78, 142, 40, my_blue);          
            it.print(200, 87, id(tempo), my_white, "Demain");
          }

          if (id(demain).state == "ROUGE") { 
            it.filled_rectangle(169, 78, 142, 40, my_red);          
            it.print(200, 87, id(tempo), my_white, "Demain");
          }

          it.print(9, 130, id(tempo), my_white, "Jours restants");
          it.print(9, 150, id(tempo2), my_white, "Pour la période du 1er septembre au 31 aout");

          it.print(17, 180, id(tempo2), my_white, "Jours bleus");
          it.filled_circle(25, 205, 8, my_blue);
          it.printf(39, 200, id(tempo2), my_white, "%.0f-301", id(jours_bleus).state);

          it.print(117, 180, id(tempo2), my_white, "Jours blancs");
          it.filled_circle(125, 205, 8, my_white);
          it.printf(139, 200, id(tempo2), my_white, "%.0f-43", id(jours_blancs).state);

          it.print(217, 180, id(tempo2), my_white, "Jours rouges");
          it.filled_circle(225, 205, 8, my_red);
          it.printf(239, 200, id(tempo2), my_white, "%.0f-22", id(jours_rouges).state);

      - id: page4
        lambda: |-
          
          auto white = Color(255, 255, 255);
          it.rectangle(0,  0, it.get_width(), it.get_height(), white);
          
          it.filled_rectangle(20, 20, 80, 80, my_blue);
          it.rectangle(20, 20, 80, 80, my_white);
          it.print(22, 22, id(material80), my_white, "\U000F0CE3");

          it.print(110, 23, id(material20), my_white, "\U000F0DAB");
          it.print(140, 22, id(font_tempo), my_white, "Alain");
          if (id(batterie_tel_alain).state > 65) {
            it.print(110, 46, id(material20), my_white, "\U000F12A3");    
          }  
          if ((id(batterie_tel_alain).state > 33) and (id(batterie_tel_alain).state < 66)) {
            it.print(110, 46, id(material20), my_yellow, "\U000F12A2");    
          } 
          if (id(batterie_tel_alain).state < 34) {
            it.print(110, 46, id(material20), my_red, "\U000F12A1");    
          }  
          it.printf(140, 52, id(tempo3), my_white, "Téléphone: %2.0f%%", id(batterie_tel_alain).state);          
          it.print(110, 69, id(material20), my_white, "\U000F010D");
          if (id(tel_alain_connect).state.find("28:CF:08:EC:36:31") != std::string::npos) {
            it.print(140, 75, id(tempo3), my_white, "EST DANS LA KIA");
          }
          if (id(tel_alain_connect).state.find("74:95:EC:EC:E3:A8") != std::string::npos) {
            it.print(140, 75, id(tempo3), my_white, "EST DANS LA NISSAN");
          } 
          it.print(20, 106, id(material20), my_white, "\U000F12FB");
          it.print(40, 110, id(tempo3), my_white, id(alain_lieu).state.c_str());  

          it.filled_rectangle(20, 130, 80, 80, my_red);
          it.rectangle(20, 130, 80, 80, my_white);
          it.print(22, 132, id(material80), my_white, "\U000F1078");

          it.print(110, 133, id(material20), my_white, "\U000F0DAB");
          it.print(140, 132, id(font_tempo), my_white, "Nadège");
          if (id(batterie_tel_nadege).state > 65) {
            it.print(110, 156, id(material20), my_white, "\U000F12A3");    
          }  
          if ((id(batterie_tel_nadege).state > 33) and (id(batterie_tel_alain).state < 66)) {
            it.print(110, 156, id(material20), my_yellow, "\U000F12A2");    
          } 
          if (id(batterie_tel_nadege).state < 34) {
            it.print(110, 156, id(material20), my_red, "\U000F12A1");    
          }  
          it.printf(140, 162, id(tempo3), my_white, "Téléphone: %2.0f%%", id(batterie_tel_nadege).state);
          
          it.print(110, 183, id(material20), my_white, "\U000F010D");
          if (id(tel_nadege_connect).state.find("28:CF:08:EC:36:31") != std::string::npos) {
            it.print(140, 189, id(tempo3), my_white, "EST DANS LA KIA");
          }
          if (id(tel_nadege_connect).state.find("74:95:EC:EC:E3:A8") != std::string::npos) {
            it.print(140, 189, id(tempo3), my_white, "EST DANS LA NISSAN");
          } 
          it.print(20, 216, id(material20), my_white, "\U000F12FB");
          it.print(40, 220, id(tempo3), my_white, id(nadege_lieu).state.c_str()); 


interval:
  - interval: 10s
    then:
      - display.page.show_next: my_display
      - component.update: my_display


font:    

  - file: "fonts/calibri.ttf"
    id: tempo
    size: 24
    glyphs: "<>♡ÆØÅæøå!'%(){}+,-_.:;*=°?~#0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdeéèfghijklmnopqrstuvwxyzôç"
  
  - file: "fonts/calibri.ttf"
    id: tempo2
    size: 16
    glyphs: "<>♡ÆØÅæøå!'%(){}+,-_.:;*=°?~#0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdeéèfghijklmnopqrstuvwxyzôç"
  
  - file: "fonts/calibri.ttf"
    id: tempo3
    size: 14
    glyphs: "<>♡ÆØÅæøå!'%(){}+,-_.:;*=°?~#0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdeéèfghijklmnopqrstuvwxyzôç"

  
  - file: "gfonts://Protest Guerrilla"
    id: Protest
    size: 64
    glyphs: "<>♡ÆØÅæøå!'%(){}+,-_.:;*=°?~#0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdeéfghijklmnopqrstuvwxyzôç"
  
  - file: "gfonts://Bebas Neue"
    id: font_heure
    size: 64
    glyphs: "<>♡ÆØÅæøå!'%(){}+,-_.:;*=°?~#0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdeéfghijklmnopqrstuvwxyzôç"

  - file: "gfonts://Roboto"
    id: font_tempo
    size: 20
    glyphs: "<>♡ÆØÅæøå!'%(){}+,-_.:;*=°?~#0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdeéèfghijklmnopqrstuvwxyzôç"

  - file: "gfonts://Sono"
    id: font_temperature
    size: 18
    glyphs: "<>♡ÆØÅæøå!'%(){}+,-_.:;*=°?~#0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdeéfghijklmnopqrstuvwxyzôç"

  - file: "gfonts://Bebas Neue"
    id: my_font12
    size: 12
    glyphs: "<>♡ÆØÅæøå!'%(){}+,-_.:;*=°?~#0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdeéfghijklmnopqrstuvwxyzôç"

  - file: "gfonts://Oxygen Mono"
    id: my_font_temp
    size: 24
    glyphs: "<>♡ÆØÅæøå!'%(){}+,-_.:;*=°?~#0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdeéfghijklmnopqrstuvwxyzôç"

  - file: "gfonts://Bebas Neue"
    id: my_font8
    size: 8
    glyphs: "<>♡ÆØÅæøå!'%(){}+,-_.:;*=°?~#0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdeéfghijklmnopqrstuvwxyzôç"
  
  - file: "fonts/materialdesignicons-webfont.ttf"
    id: material80
    size: 80
    glyphs: 
      - "\U000F0CE3" # mdi:account-tie
      - "\U000F1078" # mdi:face-woman-outline
      

  - file: "fonts/materialdesignicons-webfont.ttf"
    id: material20
    size: 20
    glyphs: 
      - "\U000F0DAB" # mdi:card-account-details-outline
      - "\U000F12A1" # mdi:battery-low
      - "\U000F12A2" # mdi:battery-medium
      - "\U000F12A3" # mdi:battery-high
      - "\U000F010D" # mdi:car-connected
      - "\U000F12FB" # mdi:map-marker-check-outline
      - "\U000F050F" # mdi:thermometer
      - "\U000F1503" # mdi:water-alert-outline
      - "\U000F17E3" # mdi:battery-check-outline
  
  - file: "fonts/materialdesignicons-webfont.ttf"
    id: temperature
    size: 32
    glyphs: 
      - "\U000F07C0" # mdi:desktop-classic
      - "\U000F12A1" # mdi:battery-low
      - "\U000F12A2" # mdi:battery-medium
      - "\U000F12A3" # mdi:battery-high
      - "\U000F010D" # mdi:car-connected
      - "\U000F12FB" # mdi:map-marker-check-outline
      - "\U000F0099" # mdi:bed-outline
      - "\U000F0097" # mdi:bunk-bed-outline
      - "\U000F1061" # mdi:table-chair
      - "\U000F0F9B" # mdi:home-export-outline
      - "\U000F09F0" # mdi:flower-outline   


  
color:
  - id: my_red
    hex: ff0000
  - id: my_green
    hex: 00ff91
  - id: my_blue
    hex: 00b3ff
  - id: my_yellow
    hex: cbed0c
  - id: my_white
    hex: FFFFFF
  - id: my_black
    hex: "000000"
  - id: my_orange
    hex: ff8400

sensor:
  - platform: homeassistant
    id: batterie_tel_alain
    entity_id: sensor.telephone_alain_battery_level
  - platform: homeassistant
    id: batterie_tel_nadege
    entity_id: sensor.sm_a505fn_battery_level

  - platform: homeassistant
    id: temperature_bureau
    entity_id: sensor.thermometre_bureau_temperature
  - platform: homeassistant
    id: hygro_bureau
    entity_id: sensor.thermometre_bureau_humidite
  - platform: homeassistant
    id: batterie_bureau
    entity_id: sensor.thermometre_bureau_batterie

  - platform: homeassistant
    id: temperature_chambre
    entity_id: sensor.exterieur_temperature
  - platform: homeassistant
    id: hygro_chambre
    entity_id: sensor.exterieur_humidite
  - platform: homeassistant
    id: batterie_chambre
    entity_id: sensor.exterieur_batterie


  - platform: homeassistant
    id: temperature_chambre_ami
    entity_id: sensor.wen_shi_du_chuan_gan_qi_chambre_d_ami_temperature
  - platform: homeassistant
    id: hygro_chambre_ami
    entity_id: sensor.wen_shi_du_chuan_gan_qi_chambre_d_ami_humidite
  - platform: homeassistant
    id: batterie_chambre_ami
    entity_id: sensor.wen_shi_du_chuan_gan_qi_chambre_d_ami_batterie

  - platform: homeassistant
    id: temperature_cuisine
    entity_id: sensor.cuisine_temperature
  - platform: homeassistant
    id: hygro_cuisine
    entity_id: sensor.cuisine_humidite
  - platform: homeassistant
    id: batterie_cuisine
    entity_id: sensor.cuisine_batterie

  - platform: homeassistant
    id: temperature_avant
    entity_id: camera.avant
    attribute: temperature_c

  - platform: homeassistant
    id: temperature_arriere
    entity_id: camera.arriere
    attribute: temperature_c

  - platform: homeassistant
    id: jours_bleus
    entity_id: sensor.jours_bleu_restants
  - platform: homeassistant
    id: jours_blancs
    entity_id: sensor.jours_blanc_restants
  - platform: homeassistant
    id: jours_rouges
    entity_id: sensor.jours_rouge_restants
  - platform: homeassistant
    id: puissance
    entity_id: sensor.compteur_linky_puissance_apparente
  


text_sensor:
  - platform: homeassistant
    id: aujourdhui
    entity_id: sensor.tempo_aujourd_hui
  - platform: homeassistant
    id: demain
    entity_id: sensor.tempo_demain
  - platform: homeassistant
    id: tel_alain_connect
    entity_id: sensor.telephone_alain_bluetooth_connection
    attribute: connected_paired_devices
  - platform: homeassistant
    id: alain_lieu
    entity_id: sensor.telephone_alain_geocoded_location
  - platform: homeassistant
    id: tel_nadege_connect
    entity_id: sensor.sm_a505fn_bluetooth_connection
    attribute: connected_paired_devices
  - platform: homeassistant
    id: nadege_lieu
    entity_id: sensor.sm_a505fn_geocoded_location
  - platform: homeassistant
    id: saint_jour
    entity_id: sensor.saint_du_jour
  - platform: homeassistant
    id: saint_demain
    entity_id: sensor.saint_de_demain
  



image:
  - file: "images/edf-tempo-logo.jpg"
    id: edf_tempo
    type: RGB24

IMAGE
edf-tempo-logo

S’il manque quelque chose, dites le moi

3 « J'aime »