Simulateur de présence (modifié avec utilisation de Painless Mesh)

Réservé : explications code ESP32

Le code sur l'ESP32 nécessite bien sûr une connexion Wifi pour la discussion avec les prises mais aussi pour connaitre l'heure (via un serveur NTP). Les horaires d'allumage des prises sont définis par une structure qui indique, pour chaque plage horaire :

  • L'identifiant de la prise
  • Les jours de la semaine
  • L'heure et les minutes d'allumage
  • L'heure et les minutes d'extinction
  • Une durée aléatoire autour de ces horaires pour rendre le système moins prévisible

Quelques exemples :

  {Salon, 0b1111111,  7, 10,  8,  0,  0}, /* every days, from 7:10 to 8:00, no random */
  {Salon, 0b1000001, 21, 45, 23, 15, 20}, /* saturday & sunday, from 21:45 to 23:15, 20' random */
  {Salon, 0b1000001, 23, 45,  0, 15, 10}, /* saturday & sunday, from 23:45 to 00:15, 10' random */
  {Salon, 0b0111110, 22, 30, 23, 55, 15}, /* week days, from 22:30 to 23:55, 15' random */
  {Salon, 0b0111000,  0, 15,  1, 25, 10}, /* -MTW---, from 00:15 to 01:05, 10' random */

Ensuite, chaque minute pleine, l'ESP32 vérifie si l'on entre ou sort d'une de ces plages et met à jour la ou les prises concernées.

Un affichage sur un petit écran OLED permet de connaitre l'état des prises à chaque instant.

L'ESP32 est à l'adresse IP fixe : 192.168.0.51, ça peut être changé dans le code. Lorsqu'on va sur http://192.168.0.51 on obtient l'IHM montrée plus haut, qui indique l'état de chaque prise : ON (bouton vert), OFF (bouton rouge) ou non connectée (bouton bleu). Le bouton est cliquable : ON <--> OFF.

Si on clique sur le nom de la prise, on accède à une nouvelle page qui liste les plages horaires associées.

Screenshot_20190529-172743_Chrome-270x480.jpg

La connexion à l'ESP32 est protégée par mot de passe, il est écrit en dur dans le code :

// Credentials to connect to the ESP32
const char* www_username = "***";
const char* www_password = "****";

Pour l'instant le code est configuré pour un nombre maximum de 8 prises, c'est réglable avec le paramètre

#define deviceNumber 8

Les identifiants vont donc de 0 à 7, ils sont redéfinis avec un enum :

enum device_t : byte {Salon, Cuisine, Couloir, SalleDeBain, ChLea, ChIrena, WC, Entree};

Les noms des prises sont définis ici

char deviceName[deviceNumber][31] = {"Salon", "Cuisine", "Couloir", "SdB",
                                     "Ch.L",  "Ch.I",    "WC",      "Entree"
                                    };

On peut les changer dans le code mais aussi de manière interactive directement grâce à l'IHM des prises.

Pour le serveur web, j'utilise la bibliothèque WebServer.h pour ESP32, qui permet de gérer des commandes très simplement. Je me suis inspiré de ce tuto. Le traitement des commandes se fait grâce à la méthode 'on', déclarée dans le setup :

  server.on("/", handle_OnConnect);
  server.on("/on", handle_on);
  server.on("/off", handle_off);
  server.on("/list", handle_list);

Elle lie les requêtes à des fonctions appelées selon leur contenu. Ainsi si la requête contient 'on',l'ESP exécute la fonction handle_on qui envoie une commande d'allumage au relais concerné (en argument) et met à jour le serveur.

void handle_on() {
  if (server.arg("id") == "") {
    server.send(400, "text/plain", "Bad request");
  } else {
    byte device = server.arg(0).toInt();
    deviceState[device] = ON;
    sendCommand (device, 4);
    char * ptr = webStatus ();
    server.send(200, "text/html", ptr);
    free(ptr);
  }
}

A noter que j'ai réécrit les affichages sur le serveur sans utiliser de String pour éviter les problèmes de mémoire (avec allocation dynamique et libération de la chaîne de caractères de grande taille utilisée à chaque affichage).

L'envoi des commandes aux prises se fait par la fonction

state sendCommand (byte device, byte command) {
  /*
     List of available commands:
     0 get id
     1 get name
     2 get status
     3 switch off (relay and led)
     4 switch on (relay and led)
     5 blink
  */

6 commandes sont possibles pour l'instant. Elles sont envoyées lors du clic sur les boutons de l'IHM, ce qui permet de construire le texte de la requête contenant la commande et ses arguments.

Screenshot_20190529-172743_Chrome-270x480.jpg

Les prises sont commandées soit par l'ESP32, soit par l'interface web. Dans ce dernier cas, d'autres commandes sont disponibles :

  • / connexion simple, affiche l'état et un bouton pour changer
  • /web/on réservé à la commande ESP32 (allumage relais & led)
  • /web/off réservé à la commande ESP32 (extinction relais & led)
  • /cmd/blink led cignote (arguments : nombre, durée_ms)
  • /cmd/all/on allumage relais & led
  • /cmd/all/off extinction relais & led
  • /cmd/relay/on allumage relais (led inchangée)
  • /cmd/relay/off extinction relais (led inchangée)
  • /cmd/led/on allumage led (relais inchangé)
  • /cmd/led/off extinction led (relais inchangé)
  • /cmd/get_id renvoie l'id de la prise
  • /cmd/get_name renvoie le nom de la prise
  • /cmd/set_id changer l'id (donc l'IP : reboote la prise) et le nom de la prise
  • /cmd/set_name changer le nom de la prise (si les noms par défaut ne conviennent pas)
  • /cmd/get_ip renvoie l'IP de la prise
  • /cmd/relay/status renvoie l'état de relais (1, 0 pour on, off)
  • /cmd/led/status renvoie l'état de la led (1, 0 pour on, off)

Au besoin voir la syntaxe des commandes plus bas.
Exemple : http://192.168.0.52/cmd/led/on

Le code se lance au moment où la prise est branchée.
Il est alors possible de configurer la prise avec le bouton : l'utilisateur dispose de 15 secondes pour appuyer sur le bouton. Le nombre d'appuis devient l'identifiant de la prise (+1). Exemple : 3 appuis --> l'identifiant sera 2 (1 appui pour 0) et l'IP de la prise sera 192.168.0.54

Pendant les 15 secondes, la led rouge clignote, de plus en plus vite au fur et à mesure que les secondes s'écoulent. S'il n'y a plus d'appui pendant 2 secondes, le délai de 15 secondes s'arrête.

Si on n'a pas appuyé sur le bouton pendant le délai, l'IP sera 192.168.0.99

Ensuite, la prise se connecte au Wifi. Il est alors possible d'accéder à l'IHM par le web, avec l'IP de la prise. L'adresse IP (ex: http://192.168.0.54) affiche l'état de la prise (voir photo ci-dessous). Cliquer sur le bouton permet d'allumer ou éteindre la prise.

Les commandes sont accessibles via la barre d'adresse du browser. Exemple :
http://192.168.0.54/cmd/blink?N=5&d=200 fera clignoter la led 5 fois avec une durée de 200 ms à chaque fois.

Les commandes ont une syntaxe de base identique http://adresse_ip/cmd/commande?paramètres
La syntaxe est indiquée dans le code. La commande set_id est particulière : elle permet de changer d'identifiant (si on n'a pas pu le faire avec le bouton au boot), de changer d'adresse IP et éventuellement de changer de nom pour la prise. Syntaxe:
http://ip_address/cmd/set_id?ID=new_id&Name=new_device_name
Exemple : http://ip_address/cmd/set_id?ID=4&Name=Ch.J --> l'identifiant de la prise devient le numéro 4, l'IP devient automatiquement 192.168.0.55 (=51+4) et le nom de la prise devient "Ch.J", qui devrait s'afficher sur l'IHM (je ne sais pas s'il change sur l'IHM de l'ESP32...). La prise va alors rebooter (sans la phase initiale de 15 secondes) et son adresse IP sera changée (elle sera indiquée dans l'IHM) : il faudra alors utiliser la nouvelle pour connaitre son état.

Quelques photos :

Screenshot_20190529-172732_Chrome-270x480.jpg
IHM de commande d'une prise

J'aurais voulu stocker les paramètres tels que l'identifiant et le nom de chaque prise dans un fichier dans la SPIFFS pour le relire à la prochaine utilisation, mais je me suis aperçu que mes ESP8266 n'ont pas de SPIFFS. Donc tant pis. Le code est là mais reste inexploité.

20190529_101317-270x151.jpg
Des fils soudés sur les ports RX et TX de la prise (fils bleus) et sur VCC (fils rouge) et GND (fil gris)

La difficulté principale est de se connecter à la prise pour flasher le code. Il faut 4 fils, deux pour RX et TX, un pour VCC et un pour GND, et un adaptateur. Les contacts VCC et GND sont assez faciles à souder car ils sont en un endroit assez robuste. Par contre les contacts RX et TX se font sur des pastilles très fines et fragiles. D'une part il n'est pas facile d'y souder des fils, d'autre part les pastilles se détachent si elles sont soumises à des contraintes trop fortes. Et là, les ennuis commencent...

Pour RX, on dispose d'un autre point de soudure à côté des VCC et GND, et je conseille de l'utiliser plutôt que la pastille. Mais pour TX il n'y a pas le choix et si la pastille se détache, la seule solution qui reste est de se brancher sur la patte TX de l'esp8266 (galère).

20190529_101437-270x151.jpg

20190529_101449-270x480.jpg
On voit bien les pastilles
J'ai utilisé des fils monobrins assez rigides et je pense que c'était une erreur car lors des manipulations, ils forcent sur les pastilles.

En résumé : la carte principale de la sonoff comporte des points d'accès étiquetés :

  • J1 = 3V3
  • J2 = GND
  • J3 = GPIO12 = RELAI
  • J4 = GPIO0 = BOUTON
  • J5 = GPI13 = LED
  • J10 = RX (ERX) EDIT : sauf si la pastille a sauté, car elle fait le contact !!!

Je conseille de se brancher à cet endroit pour VCC, GND et RX, et sur la pastille pour TX (pas trop le choix). Utiliser des fils souples ou les coller sur le PCB après la soudure afin que les opérations de branchement et flashage ne transmettent pas de contrainte sur les pastilles. Au pire, il suffit de le faire pour la TX, les autres peuvent être resoudées plusieurs fois.


Sur cette photo, le fil blanc / rose est pour RX

L'adaptateur : Al1fch m'a prêté celui-ci qui est parfait et permet d'alimenter l'ESP8266 pendant le flashage et son utilisation.

Screenshot_20190529-172732_Chrome-270x480.jpg

20190529_101317-270x151.jpg

20190529_101437-270x151.jpg

20190529_101449-270x480.jpg

Ecxellent !!
Merci pour le partage.
je vois que finalement tu as mis tout le monde sur le réseau local de ta box

A venir :

  • Configurer la box pour que l'ESP32 soit accessible depuis internet,
  • Refaire les codes avec la bibliothèque painlessMesh qui me semble particulièrement adaptée à cette application.

painlessMesh is a library that takes care of the particulars of creating a simple mesh network using esp8266 and esp32 hardware. The goal is to allow the programmer to work with a mesh network without having to worry about how the network is structured or managed.

Je voulais ajouter la possibilité d'allumer ou éteindre une prise en appuyant sur le bouton, mais il fallait que l'IHM de l'ESP32 se mette à jour automatiquement, donc que la prise envoie une requête à l'ESP32. Un réseau mesh devrait rendre ça plus facile à coder.

Bonjour,
Bravo très belle réalisation.
J'ai fait quelque chose de similaire mais sur un réseau wifi indépendant, et par choix, entièrement déconnecté du web.
Mais j'ai la possibilité de passé par une passerelle (Raspberry pi) connectée au réseau domotique et au wifi classique. La sécurité passe par iptable (ne peu galère d'ailleurs).

Merci !
J'aurai besoin de conseil pour l'accès depuis internet : j'imagine que dans l'absolu c'est assez simple. On renvoie les requêtes arrivant de l'extérieur via une redirection du port 80.

Mais que se passe-t-il si j'ai plusieurs appareils avec chacun un serveur ? Comment se routent les requêtes ?

Une redirection du port 80 vers l'ESP32 devrait normalement suffire pour prendre la main indirectement sur les Sonoff ? Ton système n'est pas conçu pour ca ?

Si, mais j'ai aussi un serveur sur un Raspberry Pi qui peut tourner en même temps et recevoir des requêtes.

Ne risque-t-il pas d'y avoir des conflits ?

Re,

lesept:
Si, mais j'ai aussi un serveur sur un Raspberry Pi qui peut tourner en même temps et recevoir des requêtes.

Ne risque-t-il pas d'y avoir des conflits ?

Dans mon cas, le seul accès c'est le RPI qui lui gère le reste.

lesept:
20190529_101317-270x151.jpg
Des fils soudés sur les ports RX et TX de la prise (fils bleus) et sur VCC (fils rouge) et GND (fil gris)

La difficulté principale est de se connecter à la prise pour flasher le code. Il faut 4 fils, deux pour RX et TX, un pour VCC et un pour GND, et un adaptateur.

Bonjour lesept
retour interessant

Quelquefois il peut être intéressant de se fabriquer ses propres connecteurs de "flashage/repiquage"
Ce n'est vraiment intéressant que si le nombre de dispo à flasher est assez important

perso lorsque je decide de le faire j'utilise le + souvent des pogo pin avec d'autres aides comme patafix, colle uv,araldite etc ...

juste pour illustration

Si, mais j'ai aussi un serveur sur un Raspberry Pi qui peut tourner en même temps et recevoir des requêtes.

Ne risque-t-il pas d'y avoir des conflits ?

non si ton ESP32 ,par exemple, a son serveur HTTP sur le port , disons, 81
tu fais deux redirections au niveau de la Box pour les ports 80 et 81 vers les bonnes cartes

Avec ton navigateur, depuis l'exérieur , tu ajoutes :81 à l'url de la box pour tomber sur le serveur HTTP de l'ESP32

J'espérais quelque chose comme ça, je vais tester. Merci !

Artouste:
Quelquefois il peut être intéressant de se fabriquer ses propres connecteurs de "flashage/repiquage"

Pour la seconde prise, j'ai soudé sur mes paires de fils des connecteurs qui rendent le tout un peu plus solide. Je posterai une photo demain

La patafix me semble une bonne idée. Je testerai plus tard. Merci

Edit : voici la photo
La patafix ne marche pas, trop dur de conserver les contacts tout en bougeant la prise

al1fch:
Avec ton navigateur, depuis l'exérieur , tu ajoutes :81 à l'url de la box pour tomber sur le serveur HTTP de l'ESP32

Ça fonctionne, je peux même utiliser le nom de domaine de ma freebox ! C'est cool...

Bravo pour cette belle réalisation et merci de l'avoir publiée.

Pour la soudure de fils sur des pastilles très fines comme c'est le cas pour "hacker" les prises Sonoff, j'utilise du fil émaillé de 2/10. Il est très souple et cela diminue le risque d'arracher les pastilles.

Pour le découpage d'un programme en "modules" constitués chacun d'un fichier .h et .cpp, j'y suis arrivé pour mes projets, mais ce n'est pas vraiment simple et demande une grande rigueur. J'avais fait une ébauche de recette de cuisine, mais elle n'est plus à jour... Je vais la mettre à jour et la publier... mais sans promesse ferme...

Bonne bidouille

MicroQuettas

Je reprends le fil avec une version basée sur la bibliothèque Painless Mesh. Le but de cette bibli est de fournir des outils pour créer un réseau "mesh", c'est à dire un réseau maillé, au sein duquel les messages transitent d'un nœud à l'autre en étant parfois renvoyés par d'autres nœuds.

Du coup, il est possible d'étendre le réseau sur une plus grande distance ou dans un endroit où le wifi passe mal, du fait de cette retransmission. Ainsi, si le nœud A envoie un message au nœud D, il peut passer par le B et le C avant de lui arriver.

Bref, la bibli permet de créer facilement ce genre de réseau. Elle est toujours en évolution, mais la version actuelle 1.4.2 est assez stable.

Mon application est de faire une simulation de présence dans un endroit qui n'est pas habité. J'utilise des prises commandées Sonoff S26 et un ESP32 comme chef d'orchestre. La prise coûte près de 8€ chez Ali,bien choisir la prise adaptée à la France (modèle EU E, pas F).

Le code est donc en 2 parties : une pour les prises, et une pour l'ESP32. L'ESP32 joue le rôle de coordinateur du réseau, mais aussi de passerelle vers Internet, via la box, pour pouvoir contrôler l'état des prises en temps réel et les commander le cas échéant. Un écran OLED est attaché à l'ESP32 pour donner une vue synthétique de l'état des prises.

Il y a donc 3 couples identifiant / password dans cette appli :

  • Connexion des prises et de l'ESP32 au réseau mesh (il doit être le même dans le code des prises)
  • Connexion de l'ESP32 au Wifi
  • Connexion sécurisée sur l'ESP32 pour le contrôle à distance

Je commente ici le code de l'ESP32 (attaché).
C'est lui qui définit les intervalles d'allumage de chaque prise (que j'appelle slots). Ils sont définis par une struct qui contient :

typedef struct {
  byte device;
  byte days : 7;   // binary 0bSMTWTFS (Sunday, Monday, Tuesday ... Saturday) - use 7 bits
  byte hourBegin;  // 0 ... 23
  byte minBegin;   // 0 ... 59
  byte hourEnd;
  byte minEnd;
  byte randomMin;  // randomly add or decrease begin and end times of up to xx minutes
} TimeSlot;
  • Le numéro de la prise associée
  • Les jours concernés : DLMMJVS (de Dimanche à Samedi), en binaire sur 7 bits: 0b1001010 signifie Dimanche, Mercredi et Vendredi
  • L'heure d'allumage : heure (0 - 23) et minutes (0 - 59)
  • L'heure d'extinction (idem : attention à bien définir une heure de fin après l'heure de début)
  • Un intervalle (en minutes) aléatoire qui s'ajoute ou se retranche aux heures précédentes pour ne pas avoir de répétition trop franche d'un jour sur l'autre (0 : horaires fixes)

Le numéro de la prise peut être remplacé par les éléments d'un enum, comme par exemple

enum device_t : byte {Salon, Cuisine, Bureau, SalleDeBain, ChLea, ChIrena, WC, Entree};

La prise 0 serait équivalente à Salon, 1 Cuisine, etc.

Un exemple de slot :

{Salon, 0b1010101, 20, 10, 20, 50, 10}

La prise du Salon s'allumera les Dimanche, Mardi, Jeudi et Samedi, de 20h10 +- random(10) minutes à 20h50 +- random(10) minutes, random(10) étant un nombre aléatoire entre 0 et 10. Les horaires peuvent être par exemple 20h03 à 20h56.

Evitez de définir un trop grand nombre de slots, car on peut avoir des problèmes de mémoire. J'ai eu des soucis autour de 60... Je travaillerai plus tard sur une solution pour régler ça.

Pour l'affichage web ou OLED, il est possible de définir des noms spécifiques aux prises, par exemple "Salon", 'Cuis.", etc.

Le montage électronique est très simple : ESP32 - OLED sur I2C (SCL 22, SDA 21). L'écran affiche de manière synthétique l'état de chaque prise et son nom :

  • ON : petit cercle plein (comme une lumière allumée)
  • OFF : petit cercle vide
  • Inconnu : cercle barré

20190818_123656-270x360.jpg

L'ESP32 abrite un server web, avec une adresse IP fixe : il est accessible sur un browser via :

http://192.168.0.51:81

J'ai choisi le port 81 car j'ai parfois un RPi sur le port 80, mais ça peut être changé dans le code. La connexion est authentifiée et demande l'identifiant et le password défini plus haut.

L'écran principal affiche l'état des prises :

  • Rectangle vert, état ON : prise allumée
  • Rectangle rouge, état OFF : prise éteinte
  • Rectangle bleu : prise non connectée

Si la prise est allumée, rectangle vert, on peut l'éteindre en cliquant sur le mot 'OFF' à l'intérieur du rectangle. De même si la prise est éteinte. Si elle n'est pas connectée, le rectangle n'est pas cliquable. Je sais, ça peut être trompeur de voir ON à l'intérieur du rectangle rouge (prise éteinte), mais juste au dessus est écrit "Status OFF"... C'est un choix...

Screenshot_20190818-123640_Chrome-270x480.jpg

En cliquant sur le nom de la prise, on accède à la liste des slots qui lui sont associés. Ça permet de connaitre à distance les jours et horaires (et leur partie aléatoire) d'allumage.
Screenshot_20190818-124004_Chrome-270x480.jpg

Enfin, en cliquant sur le titre de la page principale, on accède à la liste des prises, avec leur numéro 'mesh', leur nom, et si elles sont forcées ou non.
Screenshot_20190818-123948_Chrome-270x480.jpg
Prise forcée : si on clique sur un rectangle vert ou rouge, on force l'allumage ou l'extinction d'une prise. Elle va rester dans cet état jusqu'à ce qu'on change d'état en cliquant une nouvelle fois, ou qu'un slot du même état se termine.

Painless_ESP32.ino (29.7 KB)

Screenshot_20190818-123640_Chrome-270x480.jpg

20190818_123656-270x360.jpg

Screenshot_20190818-124004_Chrome-270x480.jpg

Screenshot_20190818-123948_Chrome-270x480.jpg

Le code des prises est en pièce jointe.

Il organisé en fonctions :

  • Callbacks en cas d’événement Painless Mesh (connexion, message entrant)
  • Blink pour faire clignoter la led
  • Fonction pour indiquer le numéro d'ordre de la prise avec le bouton poussoir (à l'initialisation)
  • Fonction de changement d'état en cas d'appui sur le bouton (allumer ou éteindre la prise par un appui sur le bouton)
  • Setup : initialisation du réseau mesh
  • Loop : surveillance du bouton en cas de changement d'état

L'avantage de Painless Mesh est que la loop n'a pratiquement rien à faire : tout est fait par les fonctions Callback, en l’occurrence ici traiter un message entrant et y répondre.

Les messages entrants sont très simples :

  • ON : ordre d'allumage de la prise,
  • OFF : ordre d'extinction,
  • GET : demande d'envoi d'information d'état,
  • SET : ordre de mise à jour de l'Id de la prise,
  • BLINK : ordre de clignotement de la led.

La fonction de choix du numéro de la prise est plus complexe : elle permet après branchement de la prise de choisir son numéro (puis de l'envoyer à l'ESP32 qui saura ainsi de quelle prise il s'agit, et donc où elle se trouve). L'utilisateur a 15 secondes pour appuyer N fois sur le bouton (N étant le numéro d'ordre choisi).
Si aucun appui n'est fait au bout de 2 secondes, le décompte s'arrête.

Un appui sur le bouton de la prise permet de forcer son état ON ou OFF.
Dans cette version, plus de serveur pour accéder à la prise et la commander : c'est l'ESP32 qui commande toutes les prises via Painless Mesh.

Painless_prises.ino (6.36 KB)

J'ai envisagé de faire une version du code sans utiliser la classe String, qui pourrait poser des problèmes de fragmentation de la mémoire à long terme. Mais, après une série de tests sans aucun problème sur plus de 2 semaines, je pense que ce n'est pas nécessaire.

Donc, sauf demande expresse ou temps libre, je ne pense pas la développer...

Je me suis aperçu que l'ESP32 perd assez souvent la connexion internet, ce qui rend impossible la consultation de l'état des prises à distance. Par contre, Painless Mesh a l'air protégé contre les déconnexions, et le contrôle des prises continue donc quand même.

Pour pallier à ce problème, j'ajoute une vérification de l'état de connexion au Wifi toutes les 20 secondes :

Ajout d'une déclaration de variable dans l'en-tête :

bool checkWiFi = true;

Et de la vérification dans la loop :

void loop() {
  //  userScheduler.execute();
  mesh.update();

  if (myIP != mesh.getStationIP()) {
    myIP = mesh.getStationIP();
    Serial.println("\nServer -> connect to " + myIP.toString() + ":81");
    Serial.print("------------------------------------\n");
  }

  getLocalTime(&timeinfo);
  // verify WiFi connection @ seconds 5, 25 & 45
  if (timeinfo.tm_sec % 20 == 5) {
    if (checkWiFi) {
      if (WiFi.status() != WL_CONNECTED) wifiConnect();
      checkWiFi = false;
    }
  } else checkWiFi = true;

  //  do nothing until next plain minute (seconds == 0)
  if (timeinfo.tm_sec == 0) {
    if (!isVerified) {
      int timeNow = timeinfo.tm_hour * 60 + timeinfo.tm_min;
      if (timeNow == 0) setTimesBE (); // update slots at midnight
      Serial.printf ("\nTime : %d (%02d:%02d:%02d)", timeNow, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
      verifyDevices (timeNow);
    }
  } else isVerified = false;
}

Depuis cette modification, plus aucun problème, si ce n'est des demandes de login / pass parfois lorsque je veux vérifier l'état des prises.

Voici la version finale du code pour le contrôleur sur ESP32. Le code des prises ne change pas.
Bonne utilisation à ceux qui voudraient tester, et n'hésitez pas à me contacter si vous avez des questions ou à réutiliser tout ou partie des codes.

Painless_ESP32b.ino (28.4 KB)