Le module "Séjour". *** EN COURS DE FINALISATION ***



Mon séjour comporte 3 fenêtres et une porte fenêtre équipés de volets électriques branchés avec des interrupteurs provisoires, du provisoire qui dure depuis au moins 15 ans ! Le module aura pour rôle principal de s'occuper des volets plus quelques autres fonctions annexes.

Voici donc toutes les fonctions que j'ai imaginé pour ce module avec quelques détails techniques pour chacun d'entre eux.
Je vais brancher tout ça sur un ESP32-WROOM-32D installé sur un «devkit» de 30 pins. Un petit module 220v Hi-link délivrera du 5v avec une puissance de 5w. La carte devkit, alimentée en 5v possède un régulateur fournissant du 3,3v.

La carte 8 relais vient de chez Ali. mais je l'ais bien modifié pour ajouter une sécurité : les relais de montée et de descente d'un même volet ne peuvent pas être actionnés en même temps. J'ai aussi remodelé les connnecteurs : un connecteur 3 fils pour chaque moteur. Il faut 2 relais pour chaque volet.
Au repos le relais 1 envoie le jus sur le relais 2 qui en s'activant alimente B. En activant le relais 1 on alimente A mais on n'alimente plus le relais 2. CQFD Les borniers sont des modèles débrochables. Le résultat est presque propre !

Le schéma est très simple puisque tous les capteurs et relais sont déportés et connectés grâce à des fiches RJ.

Les fichiers KiCad et PDF sont disponibles sous licence

Les fonctionnalités qui permettent à plusieurs modules ESPhome d'interagir nécessitent de valider une autorisation dans HA sous Appareil --> Options

Reste à écrire le fichier YAML de l'appareil dans ESPHome builder; quelques comentaires avant de plonger dans le code.
esphome:
  name: sejour-e7a318
  friendly_name: Sejour
  min_version: 2025.9.0

esp32:
  variant: esp32
  framework:
    type: esp-idf

logger:

ota:
  - platform: esphome

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: "Sejour Hotspot"

captive_portal:

api:

globals:
  - id: flag_stop
    type: bool
    initial_value: "false"
  - id: groupement
    type: int
    initial_value: "6"
  - id: systeme_actif
    type: bool
    initial_value: "false"

esp32_touch:

# Dans l'ordre alphabétique des composants
binary_sensor:
  # Bouton sélection
  - platform: esp32_touch
    id: bouton_select
    name: "bouton_select"
    pin: GPIO12
    threshold: 300
    filters:
      - delayed_on: 20ms
      - delayed_off: 20ms
    on_press:
      then:
        - if:
            condition:
              lambda: 'return ! id(systeme_actif);'
            then:
              - script.execute:
                  id: allume_led
            else:
              - if:
                  condition:
                    lambda: 'return id(groupement) == 6;'
                  then:
                    - lambda: 
                        id(groupement) = 1;
                  else:
                    - lambda: 
                        id(groupement) = id(groupement) + 1;
              - script.execute:
                  id: allume_led
  # Bouton monte
  - platform: esp32_touch
    id: bouton_monte
    name: "bouton_monte"
    pin: GPIO13
    threshold: 300
    filters:
      - delayed_on: 20ms
      - delayed_off: 20ms
    on_press:
      then:
        - if:
            condition:
              lambda: 'return ! id(systeme_actif);'
            then:
              - script.execute:
                  id: allume_led
            else:
              - if:
                  condition:
                    lambda: 'return id(flag_stop);'
                  then:
                    - script.execute:
                        id: stop_relais
                    - lambda: 
                        id(flag_stop) = false;
                  else:
                    - script.execute:
                        id: monter
                    - lambda: 
                        id(flag_stop) = true;
                    - script.execute:
                        id: bouton_press
    on_release: 
      then:
        - if:
            condition:
              lambda: 'return ! id(flag_stop);'
            then:
              - script.execute:
                  id: stop_relais
              - lambda: 
                  id(flag_stop) = false;
    on_click:
      min_length: 50ms
      max_length: 400ms
      then:
        - script.stop:
            id: bouton_press
  # Bouton descend
  - platform: esp32_touch
    id: bouton_descend
    name: "bouton_descend"
    pin: GPIO14
    threshold: 300
    filters:
      - delayed_on: 20ms
      - delayed_off: 20ms
    on_press: 
      then:
        - if:
            condition:
              lambda: 'return ! id(systeme_actif);'
            then:
              - script.execute:
                  id: allume_led
            else:
              - if:
                  condition:
                    lambda: 'return id(flag_stop);'
                  then:
                    - script.execute:
                        id: stop_relais
                    - lambda: 
                        id(flag_stop) = false;
                  else:
                    - script.execute:
                        id: descendre
                    - lambda: 
                        id(flag_stop) = true;
                    - script.execute:
                        id: bouton_press
    on_release: 
      then:
        - if:
            condition:
              lambda: 'return ! id(flag_stop);'
            then:
              - script.execute:
                  id: stop_relais
              - lambda: 
                  id(flag_stop) = false;
    on_click:
      min_length: 50ms
      max_length: 400ms
      then:
        - script.stop:
            id: bouton_press
  # Bouton thermomètre
  - platform: esp32_touch
    id: bouton_thermo
    name: "bouton_thermo"
    pin: GPIO15
    threshold: 300
    filters:
      - delayed_on: 20ms
      - delayed_off: 20ms
  # Détecteur d'ouverture fenêtre'
  - platform: gpio
    id: contact_fenetre
    name: "contact_fenetre"
    icon: mdi:door-closed
    pin: GPIO34
  # Détecteur d'ouverture porte'
  - platform: gpio
    id: contact_porte
    name: "contact_porte"
    icon: mdi:door-closed
    pin: GPIO35
  # Détecteur de présence
  - platform: gpio
    id: presence_sejour
    name: "presence_sejour"
    device_class: "motion"
    pin: GPIO36

display:
  - platform: ssd1306_i2c
    model: "SSD1306 128x64"
    address: 0x3C
    lambda: |-
      it.printf(0, 0, id(lucida), "Intérieur : %.1f °", id(temperature_sejour).state);
      it.printf(0, 20, id(lucida), "Extérieur : %.1f °", id(temperature_rue).state);
      it.printf(0, 40, id(lucida), "Piscine : %.1f °", id(temperature_piscine).state);

font:
  - file: "fonts/lucon.ttf"
    id: lucida
    size: 12
    glyphsets:
      - GF_Latin_Core

i2c:
  - id: bus_display
    sda: GPIO26
    scl: GPIO27

one_wire:
  - platform: gpio
    pin: GPIO32

script:
  - id: bouton_press
    then:
      - delay: 600ms
      - lambda: 
          id(flag_stop) = false;
  - id: monter
    then:
      - script.execute:
          id: allume_led
      - if:
          condition:
            lambda: 'return id(groupement) == 1 || id(groupement) == 5 || id(groupement) == 6;'
          then:
            - switch.turn_off: relais_D1
            - switch.turn_on: relais_M1
      - if:
          condition:
            lambda: 'return id(groupement) == 2 || id(groupement) == 6;'
          then:
            - switch.turn_off: relais_D2
            - switch.turn_on: relais_M2
      - if:
          condition:
            lambda: 'return id(groupement) == 3 || id(groupement) == 5 || id(groupement) == 6;'
          then:
            - switch.turn_off: relais_D3
            - switch.turn_on: relais_M3
      - if:
          condition:
            lambda: 'return id(groupement) == 4 || id(groupement) == 5 || id(groupement) == 6;'
          then:
            - switch.turn_off: relais_D4
            - switch.turn_on: relais_M4
  - id: descendre
    then:
      - logger.log: "***** Début descendre *****"
      - script.execute:
          id: allume_led
      - if:
          condition:
            lambda: 'return id(groupement) == 1 || id(groupement) == 5 || id(groupement) == 6;'
          then:
            - switch.turn_off: relais_M1
            - switch.turn_on: relais_D1
      - if:
          condition:
            lambda: 'return id(groupement) == 2 || id(groupement) == 6;'
          then:
            - switch.turn_off: relais_M2
            - switch.turn_on: relais_D2
      - if:
          condition:
            lambda: 'return id(groupement) == 3 || id(groupement) == 5 || id(groupement) == 6;'
          then:
            - switch.turn_off: relais_M3
            - switch.turn_on: relais_D3
      - if:
          condition:
            lambda: 'return id(groupement) == 4 || id(groupement) == 5 || id(groupement) == 6;'
          then:
            - switch.turn_off: relais_M4
            - switch.turn_on: relais_D4
  - id: allume_led
    mode: restart
    then:
      - lambda: 
          id(systeme_actif) = true;
      - switch.turn_off: led_1
      - switch.turn_off: led_2
      - switch.turn_off: led_3
      - switch.turn_off: led_4
      - if:
          condition:
            lambda: 'return id(groupement) == 1 || id(groupement) == 5 || id(groupement) == 6;'
          then:
            - switch.turn_on: led_1
      - if:
          condition:
            lambda: 'return id(groupement) == 2 || id(groupement) == 6;'
          then:
            - switch.turn_on: led_2
      - if:
          condition:
            lambda: 'return id(groupement) == 3 || id(groupement) == 5 || id(groupement) == 6;'
          then:
            - switch.turn_on: led_3
      - if:
          condition:
            lambda: 'return id(groupement) == 4 || id(groupement) == 5 || id(groupement) == 6;'
          then:
            - switch.turn_on: led_4
      - delay: 60s
      - script.execute:
          id: stop_relais
      - switch.turn_off: led_1
      - switch.turn_off: led_2
      - switch.turn_off: led_3
      - switch.turn_off: led_4
      - lambda: 
          id(systeme_actif) = false;
      - lambda: 
          id(flag_stop) = false;
  - id: stop_relais
    mode: restart
    then:
      - switch.turn_off: relais_M1
      - switch.turn_off: relais_D1
      - switch.turn_off: relais_M2
      - switch.turn_off: relais_D2
      - switch.turn_off: relais_M3
      - switch.turn_off: relais_D3
      - switch.turn_off: relais_M4
      - switch.turn_off: relais_D4
          
sensor:
  # Capteur local Dallas DS18
  - platform: dallas_temp
    id: temperature_sejour
    name: Temperature séjour
    update_interval: 10min
  # Récupérer température de la piscine
  - platform: homeassistant
    id: temperature_piscine
    entity_id: sensor.thermometre_piscine_temperature
    internal: true
    unit_of_measurement: "°C"
  # Récupérer température extérieure
  - platform: homeassistant
    id: temperature_rue
    entity_id: sensor.portier_temperature_rue
    internal: true
    unit_of_measurement: "°C"

switch:
  # 8 relais des volets
  - platform: gpio
    id: relais_M1
    name: relais_M1
    pin: GPIO16
  - platform: gpio
    id: relais_D1
    name: relais_D1
    pin: GPIO17
  - platform: gpio
    id: relais_M2
    name: relais_M2
    pin: GPIO18
  - platform: gpio
    id: relais_D2
    name: relais_D2
    pin: GPIO19
  - platform: gpio
    id: relais_M3
    name: relais_M3
    pin: GPIO21
  - platform: gpio
    id: relais_D3
    name: relais_D3
    pin: GPIO22
  - platform: gpio
    id: relais_M4
    name: relais_M4
    pin: GPIO23
  - platform: gpio
    id: relais_D4
    name: relais_D4
    pin: GPIO25
  # 4 LEDs d'indication de volet actif
  - platform: gpio
    id: led_1
    name: led_1
    pin: GPIO1
  - platform: gpio
    id: led_2
    name: led_2
    pin: GPIO2
  - platform: gpio
    id: led_3
    name: led_3
    pin: GPIO3
  - platform: gpio
    id: led_4
    name: led_4
    pin: GPIO4
			
Le dessin du C.I.
Le C.I. terminé.

Les pièces 3D et le montage