Go Down

Topic: Simulateur de présence (modifié avec utilisation de Painless Mesh)  (Read 1 time) previous topic - next topic

lesept

Voici un système de simulation de présence à base d'un ESP32 qui orchestre des prises connectées Sonoff S26. L'idée est de brancher des lampes sur ces prises, les mettre en divers endroits du domicile et simuler une présence par allumage et extinction des lampes selon des horaires prévus à l'avance.


On trouve ces prises chez Ali pour près de 8€ la pièce. Bien choisir la référence EU-E (voir photo) pour une prise de terre à la française.

Matériel :
  • Des prises Sonoff
  • Un ESP32
  • Un écran OLED 128 x 64
  • Des fils, une breadboard et un fer à souder


2 codes sont écrits :
  • Un code qui tourne sur les prises : il permet de recevoir les ordres et allumer ou éteindre le relais et / ou la led. Il gère un serveur qui permet de la contrôler via un browser et un certain nombre de commandes pour la configurer ou la commander.
  • Un code qui tourne sur l'ESP32, compte le temps qui passe et allume ou éteint les prises en fonction des plages horaires prédéfinies. Il gère aussi un serveur Web pour afficher l'état des prises et les commander. Il affiche l'état des prises sur l'écran OLED.


Quelques images :


IHM de l'ESP32 sur smartphone



ESP32 et affichage OLED (cercle vide: prise éteinte,cercle plein: prise allumée, T: Timeout, X: prise non connectée)



Les prises


Les codes sont attachés.
Pour ceux qui ont suivi une discussion ce weekend, je n'ai pas réussi à diviser le gros code de l'ESP32 sur plusieurs fichiers : les interactions entre serveur, clients, écran et prises sont trop complexes. Si un courageux veut s'y lancer je suis preneur...


EDIT : Après plusieurs mises à jour, vous pouvez trouver les dernières versions des codes dans le dernier message (numéro 29 à ce jour)
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

lesept

#1
May 29, 2019, 05:38 pm Last Edit: May 29, 2019, 08:11 pm by lesept
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 :
Code: [Select]
  {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.



La connexion à l'ESP32 est protégée par mot de passe, il est écrit en dur dans le code :
Code: [Select]
// 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
Code: [Select]
#define deviceNumber 8
Les identifiants vont donc de 0 à 7, ils sont redéfinis avec un enum :
Code: [Select]
enum device_t : byte {Salon, Cuisine, Couloir, SalleDeBain, ChLea, ChIrena, WC, Entree};
Les noms des prises sont définis ici
Code: [Select]
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 :
Code: [Select]
  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.
Code: [Select]
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
Code: [Select]
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.

A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

lesept

#2
May 29, 2019, 05:39 pm Last Edit: Sep 20, 2019, 07:02 pm by lesept
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 :


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é.


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).




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.

A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

al1fch

#3
May 29, 2019, 07:11 pm Last Edit: May 29, 2019, 07:14 pm by al1fch
Ecxellent !!
Merci pour le partage.
je vois que finalement tu as mis tout le monde sur le réseau local de ta box

lesept

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.

Quote
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.
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

icare

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).
2B OR NOT(2B) = FF
Arduino 1.0.5 à 1.8.5 + gEdit + Ubuntu 18.04 LTS

lesept

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 ?
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

al1fch

#7
May 30, 2019, 11:20 am Last Edit: May 30, 2019, 11:21 am by al1fch
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 ?

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 ?
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

icare

Re,
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.
2B OR NOT(2B) = FF
Arduino 1.0.5 à 1.8.5 + gEdit + Ubuntu 18.04 LTS

Artouste

#10
May 30, 2019, 12:54 pm Last Edit: May 30, 2019, 01:25 pm by Artouste

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


al1fch

#11
May 30, 2019, 01:52 pm Last Edit: May 30, 2019, 05:26 pm by al1fch
Quote
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

lesept

J'espérais quelque chose comme ça, je vais tester. Merci !
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

lesept

#13
May 31, 2019, 01:03 am Last Edit: Sep 20, 2019, 07:04 pm by lesept
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
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

lesept

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...
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

Go Up