[DefiDIY25] T-00.001 la version lave linge notificator du T-800 à base d'esp

Hello,

Je l’avais dit si je recevais les capteurs à temps et si j’avais le temps de tester. C’est le cas donc « I came back ». Pour vous présenter le lave linge notificator, la version la moins puissante du Terminator :smiley:

Quelques composants de bases seront nécessaires mais pour une quinzaine d’euros, vous aurez un système complet de surveillance du lave linge sur vibrations et ouverture de porte. Avec démarrage et mise en veille automatique. Vous le branchez une fois et c’est tout.

Alors bien entendu on peut tout à fait faire la même chose avec des capteurs de vibrations et d’ouverture zigbee ( ou autre ) et l’automation qui va bien, sans à avoir à gérer le deepsleep ( mais la gestion des piles que j’exècre ) et pas certain que ça revienne beaucoup moins cher au final.

Comme j’aime à le dire, pourquoi mettre un NAS quand on peut mettre une baie de 250kg :wink:

Place au projet.

Il est parfois compliqué de trouver du matériel avec relevé de consommation supportant des pointes de plus de 10A, toutes les prises que j’ai pu tester sautent pendant le cycle avec des pics au dela de 10A du coup je suis resté sur des prises OSRAM sans suivi conso mais qui supportent la charge. Pour palier à ce problème j’ai envisagé une autre approche en suivant les vibrations générées par le lave linge.

Si porte ouverte le T00.001 s’endort et attend le moindre frémissement de la machine pour se remettre en mode surveillance.

Il lance le timer 1 et un décompte digne des plus grand films d’action jusqu’à lancer « Alerte! », le buzzer bip, si pendant ce timer 1 il y a des vibrations, le timer reset.
Si pas de vibrations, il lance le timer 2 de 60 secondes et prépare le deep sleep et la notification à Home assistant que la machine est terminée. Si pendant ce timer2 il y a des vibrations ( j’ai mis un filet de sécurité surtout pendant la phase de réglage, si la machine n’était pas terminée ) les 2 timers reset, il se remet en surveillance, et si tout va à terme, envoie l’info à HA machine terminée et entre en sommeil, jusqu’à ce qu’il détecte à nouveau des vibrations ( idéalement le claquement de la porte de la machine.

La première phase sera d’analyser le comportement du lave linge suivant les cycles utilisés ( on ne reste pas devant la machine … on a un Esp et un capteur de vibrations, on lance un cycle, on met un history graph dessus et on s’en va :wink: ) l’analyse sera faite après coup.

Schéma de principe

rien de compliqué tout est trouvable dans les bonnes crèmeries de matériel électronique.

  • ESP32 30 pins

  • SW 420 (capteur de vibrations)

  • Capteur d’ouverture avec sa résistance de pullup de 10kΩ (peut être activé en interne)

  • (optionnel) Buzzer 6V + BC547B (ou autre NPN du même type) + résistance de 10kΩ

  • (optionnel) Led + résistance 220Ω pour avoir l’état du deepsleep et le différencier de l’état de l’esp

lien direct vers le schéma.

Le code de l’esp ( détaillé sur le github, le lien est en bas de ce topic ).

substitutions:
  name: esp-test
  friendly_name: esp-test
  wifi_bssid: "xx.xx.xx.xx.xx.xx"
  static_ip: xx.xx.xx.xx

packages:
  base: !include .base1.yaml
 
api:
  encryption:
    key: xxx

esphome:
  name: esp32-bluetooth-proxy-24ae54
  includes:
    - sleep_patch.h
  on_boot:
    priority: -100
    then:
      - delay: 1s
      - light.turn_on: status_light
      - logger.log: "ESP démarré - Surveillance active"
      - lambda: |-
          // Initialiser les variables globales pour les timers
          id(last_vibration_time) = millis();
          id(ready_to_sleep) = false;
          id(sleep_timer_start) = 0;
          id(buzzer_blinking) = false;
          id(buzzer_start_time) = 0;

          ESP_LOGI("boot", "Timers réinitialisés");

logger:
  level: DEBUG

output:
  - platform: gpio
    pin: GPIO05
    id: buzzer_output

  - platform: gpio
    pin: GPIO12
    id: status_led

light:
  - platform: binary
    name: "LED État ESP"
    output: status_led
    id: status_light

text_sensor:
  - platform: template
    name: "Timer1 2min sans vib"
    id: countdown_display
    update_interval: 1s
    lambda: |-
      unsigned long current_time = millis();
      unsigned long last_vib = id(last_vibration_time);
      
      if (last_vib == 0) {
        return {"LL en marche"};
      }
      
      unsigned long elapsed_seconds = (current_time - last_vib) / 1000;
      unsigned long target_seconds = 120; // 2 minutes
      
      if (elapsed_seconds >= target_seconds) {
        return {"Alerte!"};
      } else {
        unsigned long remaining_seconds = target_seconds - elapsed_seconds;
        unsigned long minutes = remaining_seconds / 60;
        unsigned long seconds = remaining_seconds % 60;
        
        char buffer[10];
        sprintf(buffer, "%02lu:%02lu", minutes, seconds);
        return {buffer};
      }

  - platform: template
    name: "Timer2 lancement du deepsleep"
    id: sleep_countdown
    update_interval: 1s
    lambda: |-
      if (!id(ready_to_sleep)) {
        return {"-"};
      }
      
      unsigned long current_time = millis();
      unsigned long sleep_start = id(sleep_timer_start);
      unsigned long sleep_elapsed = (current_time - sleep_start) / 1000;
      
      if (sleep_elapsed >= 60) {
        return {"Sleep!"};
      } else {
        unsigned long remaining = 60 - sleep_elapsed;
        char buffer[10];
        sprintf(buffer, "00:%02lu", remaining);
        return {buffer};
      }

binary_sensor:
  - platform: gpio
    pin:
      number: 4
      mode: INPUT_PULLUP
    name: "Hublot Machine"
    device_class: door
    id: hublot_sensor

  - platform: gpio
    pin:
      number: 32
      mode: INPUT_PULLUP
      inverted: false
    name: "Vibration Machine"
    device_class: vibration
    id: vibration_sensor
    on_press:
      - logger.log: "Machine en marche - Reset timers"
      - globals.set:
          id: last_vibration_time
          value: '0'
      - globals.set:
          id: ready_to_sleep
          value: 'false'
      - globals.set:
          id: sleep_timer_start
          value: '0'
      - component.update: countdown_display
      - component.update: sleep_countdown
    on_release:
      - logger.log: "Machine arrêtée - Démarrage timer 1"
      - globals.set:
          id: last_vibration_time
          value: !lambda 'return millis();'
      - component.update: countdown_display

  - platform: template
    name: "Machine Terminée"
    id: machine_terminee
    lambda: |-
      if (!id(ready_to_sleep)) {
        return false;
      }
      unsigned long elapsed = (millis() - id(sleep_timer_start)) / 1000;
      return elapsed >= 60;

globals:
  - id: last_vibration_time
    type: unsigned long
    initial_value: '0'
  - id: ready_to_sleep
    type: bool
    initial_value: 'false'
  - id: sleep_timer_start
    type: unsigned long
    initial_value: '0'
  - id: buzzer_blinking
    type: bool
    initial_value: 'false'
  - id: buzzer_start_time
    type: unsigned long
    initial_value: '0'

interval:
  # Logique des timers et buzzer uniquement
  - interval: 2s
    then:
      - lambda: |-
          unsigned long current_time = millis();
          unsigned long last_vib = id(last_vibration_time);

          if (last_vib == 0) {
            id(last_vibration_time) = current_time;
            return;
          }

          unsigned long elapsed_seconds = (current_time - last_vib) / 1000;

          // Timer 1: 2 minutes sans vibration → buzzer
          if (elapsed_seconds >= 120 && !id(ready_to_sleep)) {
            ESP_LOGW("alert", "2 minutes sans vibration - Activation buzzer");
            id(buzzer_blinking) = true;
            id(buzzer_start_time) = current_time;
            id(ready_to_sleep) = true;
            id(sleep_timer_start) = current_time;
          }
          
          // Pas de deep sleep automatique - géré par HA

  # Clignotement du buzzer
  - interval: 250ms
    then:
      - lambda: |-
          if (id(buzzer_blinking)) {
            unsigned long now = millis();
            if (now - id(buzzer_start_time) >= 5000) {
              id(buzzer_output).turn_off();
              id(buzzer_blinking) = false;
            } else {
              if ((now / 250) % 2 == 0) {
                id(buzzer_output).turn_on();
              } else {
                id(buzzer_output).turn_off();
              }
            }
          }

switch:
  - platform: template
    name: "Deep Sleep"
    id: deep_sleep_switch
    turn_on_action:
      - logger.log: "ESP en deep sleep (porte ignorée)"
      - lambda: |-
          // Configurer le réveil uniquement sur vibrations
          esp_sleep_enable_ext0_wakeup(GPIO_NUM_32, 1);  // HIGH = vibration détectée
          ESP_LOGI("sleep", "Activation Deep Sleep avec réveil sur vibration...");
          esp_deep_sleep_start();
      - switch.turn_off: deep_sleep_switch

Le code de l’automation, soit porte ouverte soit machine terminée déclenchent le sleep

alias: ESP - Deep Sleep après fin de machine ou ouverture porte
description: Met l'ESP en sommeil quand la machine est terminée OU la porte est ouverte
triggers:
  - entity_id: binary_sensor.esp32_bluetooth_proxy_24ae54_machine_terminee
    to: "on"
    trigger: state
  - entity_id: binary_sensor.esp_test_hublot_machine
    to: "on"
    trigger: state
actions:
  - target:
      entity_id: switch.esp32_bluetooth_proxy_24ae54_deep_sleep
    action: switch.turn_on
mode: single

quelques logs et gifs en rafale

Timer1

Timer2

1

J’ai tout laissé dedans pour débug facilement éventuellement mais ça fonctionne pour moi comme je l’ai pensé.

A quoi ça ressemble assemblé?

Pensez à bien éloigner le buzzer du boitier principal, à la base il était dans le boitier principal, mais générait trop de vibrations et de bugs de réveil, j’ai dû le déporter.

Et avec l’article que nous avons partagé @Gael et moi
soyez notifié quelque soit la pièce ou vous vous trouvez si vous avez mis en place les notifications dynamiques Notifications dynamiques en fonction de la pièce occupée toutes mes notifcations passent par le diffuseur contextuel

Retrouvez tout ce qui manque sur le github du projet

et n’hésitez pas à partager vos créations :slight_smile:

cdt

5 « J'aime »

Ce sujet a été automatiquement fermé après 30 jours. Aucune réponse n’est permise dorénavant.