Basculement conditionnel sur écran SSD1306

Bonjour,

Je souhaiterai basculer l’affichage de mon SSD1306, via ESPHome, avec un double click sur mon montage. Voici mon programme en entier :

substitutions:
  name: sonde-sdb-fond
  friendly_name: Sonde SdB Fond

esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  min_version: 2024.6.0
  name_add_mac_suffix: false
  project:
    name: esphome.web
    version: dev

#♦ Déclaration variables
globals:
  # Variable pour extinction affichage
  - id: temoin
    type: float
    restore_value: no
    initial_value: "0"
  # Variable pour rotation affichage
  - id: rotat
    type: float
    restore_value: no
    initial_value: "0"

time:
  - platform: homeassistant
    id: esptime

esp8266:
  board: esp01_1m

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "wAv+RFS9pai2YzEyLlk4pcfNV/etWON/lje/OPE8PFk="

ota:
  - platform: esphome
    password: "9b2b9d324b672642424af0d24badfab5"

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

    # Optional manual IP
  manual_ip:
    static_ip: 192.168.1.209
    gateway: 192.168.1.254
    subnet: 255.255.255.0

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Sonde-Sdb-Fond Fallback Hotspot"
    password: "JaHCDM1h0wKO"

captive_portal:


dashboard_import:
  package_import_url: github://esphome/example-configs/esphome-web/esp8266.yaml@main
  import_full_config: true

# To have a "next url" for improv serial
web_server:

# Example configuration entry
sensor:
  - platform: dht
    pin: GPIO14
    temperature:
      id: temp
      name: "Température SdB Fond"
      unit_of_measurement: "°C"
      # filters:
      #   - multiply: 0.9
    humidity:
      id: hum
      name: "Humidité SdB Fond"
      # filters:
      #   - multiply: 1.05
    update_interval: 60s

  - platform: homeassistant
    id: inside_temperature
    entity_id: sensor.mellanvaning_temperature
    internal: true

  - platform: homeassistant
    id: outside_temperature
    entity_id: sensor.10_00080192969d_temperature
    internal: true

button:
  - platform: restart
    name: "Button Restart"
    id: my_button
  - platform: factory_reset
    name: Restart with Factory Default Settings

binary_sensor:
  # Bouton Affichage
    platform: gpio
    pin:
      number: GPIO12
      mode: INPUT_PULLUP
      inverted: True
    name: "bouton affichage"
    id: "bouton_affichage"
    filters:
      - delayed_on: 50ms
    on_click:
      - min_length: 51ms
        max_length: 300ms
        then:
          lambda: |-
            if ((id(temoin) == 0)) {
            id(temoin) = id(temoin) + 1;
            } else {(id(temoin) = 0);
            }
      - min_length: 351ms
        max_length: 1000ms
        then:
            # logger.log: "long click"
            button.press: my_button
    # bouble click pour rotation de l'affichage
    on_double_click: 
      min_length: 50ms
      max_length: 300ms
      then:
        lambda: |-
          if ((id(rotat) == 0)) {
          id(rotat) = id(rotat) + 1;
          } else {(id(rotat) = 0);
          }

font:
  - file: "fonts/arial.ttf"
    id: font1
    size: 10

  - file: "fonts/BebasNeue-Regular.ttf"
    id: font2
    size: 48

  - file: "fonts/arial.ttf"
    id: font3
    size: 12

i2c:
  sda: GPIO04
  scl: GPIO05
  scan: false

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    reset_pin: GPIO16
    address: 0x3C

# Mettre une condition pour rotation: soit 0° ou 180°
# avec variable rotat à 0 ou 1
    
    lambda: |-

        if (id(temoin) == 0) {
        // Print "Chambre Parents" in top center
        it.printf(64, 0, id(font3), TextAlign::TOP_CENTER, "Salle de Bain Fond");
        // it.printf(64, 0, id(font3), TextAlign::TOP_RIGHT , id("temoin"));

        // Print time in HH:MM format
        it.strftime(0, 60, id(font2), TextAlign::BASELINE_LEFT, "%H:%M", id(esptime).now());

        // Print inside temperature (from DHT22)
        it.printf(127, 17, id(font1), TextAlign::TOP_RIGHT , "T  ");
        it.printf(127, 28, id(font3), TextAlign::TOP_RIGHT , "%.1f", id(temp).state);

        // Print outside Humidity (from DHT22)
        it.printf(127, 49, id(font1), TextAlign::BASELINE_RIGHT , "H  ");
        it.printf(127, 60, id(font3), TextAlign::BASELINE_RIGHT , "%.1f", id(hum).state);
        }else{

        // Print un point au centre
        it.clear();
        it.printf(64, 32, id(font3), TextAlign::TOP_CENTER, ".");
        }

Dans ce programme, lorsque je double-clique, je change une variable « rotat » qui peut prendre comme valeur 0 ou 1.

on_double_click: 
  min_length: 50ms
  max_length: 300ms
  then:
    lambda: |-
      if ((id(rotat) == 0)) {
      id(rotat) = id(rotat) + 1;
      } else {(id(rotat) = 0);
      }

J’aimerais, selon la valeur, pouvoir faire varier la variable « rotation: » soit 0°, soit 180°.

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    reset_pin: GPIO16
    address: 0x3C
# rotation: variable
# Mettre une condition pour rotation: soit 0° ou 180°
# avec variable rotat à 0 ou 1

Comment faire ?
Merci.

salut,
essaye ça

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    reset_pin: GPIO16
    address: 0x3C
    lambda: |-
      // Appliquer la rotation en fonction de la variable rotat
      if (id(rotat) == 0) {
        it.set_rotation(0);
      } else {
        it.set_rotation(180);
      }

      if (id(temoin) == 0) {
        // Affichage normal
        it.printf(64, 0, id(font3), TextAlign::TOP_CENTER, "Salle de Bain Fond");
        it.strftime(0, 60, id(font2), TextAlign::BASELINE_LEFT, "%H:%M", id(esptime).now());
        it.printf(127, 17, id(font1), TextAlign::TOP_RIGHT , "T  ");
        it.printf(127, 28, id(font3), TextAlign::TOP_RIGHT , "%.1f", id(temp).state);
        it.printf(127, 49, id(font1), TextAlign::BASELINE_RIGHT , "H  ");
        it.printf(127, 60, id(font3), TextAlign::BASELINE_RIGHT , "%.1f", id(hum).state);
      } else {
        // Écran éteint avec un point au centre
        it.clear();
        it.printf(64, 32, id(font3), TextAlign::TOP_CENTER, ".");
      }

Bonjour hackdiy … Merci pour ta réponse.

Quand je déploie mon code, j’ai un message d’erreur

Compiling .pioenvs/sonde-sdb-fond/src/main.cpp.o
/config/esphome/sonde-sdb-fond.yaml: In lambda function:
/config/esphome/sonde-sdb-fond.yaml:166:25: error: invalid conversion from 'int' to 'esphome::display::DisplayRotation' [-fpermissive]
  166 |         it.set_rotation(0);
      |                         ^
      |                         |
      |                         int
In file included from src/esphome.h:24,
                 from src/main.cpp:3:
src/esphome/components/display/display.h:597:37: note:   initializing argument 1 of 'void esphome::display::Display::set_rotation(esphome::display::DisplayRotation)'
  597 |   void set_rotation(DisplayRotation rotation);
      |                     ~~~~~~~~~~~~~~~~^~~~~~~~
/config/esphome/sonde-sdb-fond.yaml:168:25: error: invalid conversion from 'int' to 'esphome::display::DisplayRotation' [-fpermissive]
  168 |         it.set_rotation(180);
      |                         ^~~
      |                         |
      |                         int
In file included from src/esphome.h:24,
                 from src/main.cpp:3:
src/esphome/components/display/display.h:597:37: note:   initializing argument 1 of 'void esphome::display::Display::set_rotation(esphome::display::DisplayRotation)'
  597 |   void set_rotation(DisplayRotation rotation);
      |                     ~~~~~~~~~~~~~~~~^~~~~~~~
*** [.pioenvs/sonde-sdb-fond/src/main.cpp.o] Error 1
========================= [FAILED] Took 12.37 seconds =========================

J’ai aussi essayé avec « 0° » et « 180° » mais c’est pareil …

Bonsoir.
Quelqu’un a une idée pour mon problème ?
Merci

Remplace les lignes it.set_rotation(0); et it.set_rotation(180); par :
Essaie ça et dis-moi si ça fonctionne !

lambda: |-
  if (id(rotat) == 0) {
    it.set_rotation(DISPLAY_ROTATION_0_DEGREES);
  } else {
    it.set_rotation(DISPLAY_ROTATION_180_DEGREES);
  }

a modifier également si ca ne fonctionne toujours pas

globals:
  - id: global_display_rotation
    type: esphome::display::DisplayRotation
    restore_value: yes
    initial_value: 'DISPLAY_ROTATION_0_DEGREES'

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO12
      mode: INPUT_PULLUP
      inverted: true
    name: "Bouton Affichage"
    id: bouton_affichage
    filters:
      - delayed_on: 50ms
    on_double_click:
      min_length: 50ms
      max_length: 300ms
      then:
        - lambda: |-
            switch (id(global_display_rotation)) {
              case DISPLAY_ROTATION_0_DEGREES: 
                id(global_display_rotation) = DISPLAY_ROTATION_180_DEGREES;
                break;
              default:
                id(global_display_rotation) = DISPLAY_ROTATION_0_DEGREES;
            }
        - component.update: my_display

Un double-clic alterne entre et 180°.
component.update: my_display force l’affichage à se mettre à jour immédiatement .

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    reset_pin: GPIO16
    address: 0x3C
    id: my_display
    lambda: |-
      it.set_rotation(id(global_display_rotation));  

      if (id(temoin) == 0) {
        it.printf(64, 0, id(font3), TextAlign::TOP_CENTER, "Salle de Bain Fond");
        it.strftime(0, 60, id(font2), TextAlign::BASELINE_LEFT, "%H:%M", id(esptime).now());

        // Température et Humidité
        it.printf(127, 17, id(font1), TextAlign::TOP_RIGHT , "T  ");
        it.printf(127, 28, id(font3), TextAlign::TOP_RIGHT , "%.1f", id(temp).state);
        it.printf(127, 49, id(font1), TextAlign::BASELINE_RIGHT , "H  ");
        it.printf(127, 60, id(font3), TextAlign::BASELINE_RIGHT , "%.1f", id(hum).state);
      } else {
        it.clear();
        it.printf(64, 32, id(font3), TextAlign::TOP_CENTER, ".");
      }

L’écran prend en compte immédiatement la rotation stockée
(id(global_display_rotation)).
Gère bien l’affichage en fonction de temoin (affichage ou point central).