MQTT ESP8266

Vous souhaitez piloter votre framboise à partir d'une page web ? Ou mieux encore à partir d'un smartphone ou d'une tablette Android ? Venez donc visiter cette rubrique...

Modérateur : Francois

78fred
Messages : 8
Enregistré le : sam. 9 oct. 2021 17:31

MQTT ESP8266

Message par 78fred » dim. 17 oct. 2021 14:33

Bonjour,

Après avoir consulter le tuto pour piloter un relais via MQTT avec un ESP8266, je me suis lancé.
Lorsque je lance le moniteur série, le wifi et MQTT se connecte.

14:25:35.506 -> ......
14:25:38.048 -> WiFi connecté
14:25:38.048 -> Addresse IP : 192.168.1.90
14:25:38.048 -> Tentative de connexion MQTT...connecté

J'ai donc crée un inter virtuel où l'adresse du device est reportée dans le programme arduino de l'ESP.
Lorsque je lance la commande depuis Domoticz, il n' y a aucune réaction dans le moniteur et dans les log sur Domoticz, il y a ceci :

2021-10-17 12:25:13.078 Test: Light/Switch (Test)
2021-10-17 12:25:13.073 Status: User: Admin (IP: 192.168.1.48) initiated a switch command (12/Test/On)
2021-10-17 12:25:16.046 Test: Light/Switch (Test)
2021-10-17 12:25:16.042 Status: User: Admin (IP: 192.168.1.48) initiated a switch command (12/Test/Off)
2021-10-17 12:41:15.420 Status: Incoming connection from: 192.168.1.48
2021-10-17 12:47:39.570 Test: Light/Switch (Test)
2021-10-17 12:47:39.566 Status: User: Admin (IP: 192.168.1.48) initiated a switch command (12/Test/On)
2021-10-17 12:49:13.155 Test: Light/Switch (Test)
2021-10-17 12:49:13.150 Status: User: Admin (IP: 192.168.1.48) initiated a switch command (12/Test/Off)
2021-10-17 12:55:55.762 Test: Light/Switch (Test)
2021-10-17 12:55:55.758 Status: User: Admin (IP: 192.168.1.48) initiated a switch command (12/Test/On)
2021-10-17 12:56:45.567 Test: Light/Switch (Test)
2021-10-17 12:56:45.562 Status: User: Admin (IP: 192.168.1.48) initiated a switch command (12/Test/Off)

J'ai beau cherché mais je ne trouve pas la réponse. Quelqu'un aurait-il une idée ?
Merci

78fred
Messages : 8
Enregistré le : sam. 9 oct. 2021 17:31

Re: MQTT ESP8266

Message par 78fred » lun. 18 oct. 2021 22:13

J'ai réussi à voir les messages apparaitre sur le moniteur série. Sur mon ESP8266, il fallait sélectionner le mode QOUT.
A partir du programme d'origine,(tuto #20 ) je souhaite pouvoir commander GPIO2 en même temps que le GPIO1 avec un sélecteur.
Etant donné que je suis un novice en la matière dans le programme Python, je cru qu'en ajoutant une ligne sup. Digital (pinRelay2, Hight) et les nvalue =10, 20, 30 cela aurait suffit. Malheureusement, cela ne fonctionne pas.

Quelqu'un pourrait m'aider sur ce coup ?

Un grand MERCI par avance

piper
Raspinaute
Messages : 645
Enregistré le : sam. 5 juin 2021 18:57

Re: MQTT ESP8266

Message par piper » mer. 20 oct. 2021 09:10

Bonjour,
Activer GPIO01 et GPIO02 ??? sur le Raspberry ???
Donc en notation BCM alors (Broches numérotations 28 et 3)
Habituellement le GPIO01 est utilisé en port SCL de l'I2C numéro 0
et le GPIO02, c'est le SDA du port I2C numéro 1
Donc choisir ces ports pour de la simple sortie digital c'est se priver de possibilité d'utiliser plus tard l'I2C.

Bref, quoi qu'il en soit, ça donnerait ceci :

Sous réserve d'installer au préalable la bibliothèque python RPI.GPIO:

Code : Tout sélectionner

sudo pip install RPi.GPIO

Code : Tout sélectionner

import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
PIN_1=ton numéro de PIN GPIO dans le mode BCM
#Situlation initiale de la sortie de PIN_1
GPIO.setup(PIN_1, initial=GPIO.LOW)

#Passage au mode bas
GPIO.output(PIN_1, GPIO.LOW)

#Passage au mode haut
GPIO.output(PIN_1, GPIO.HIGH)
Tu noteras que le mot clé est HIGH et pas HIGHT

Autre option :
Le faire directement en shell :

Code : Tout sélectionner

NPIN = ton numéro de PIN
#mettre le PIN en mode sortie
gpio export "$NPIN" out
@mettre le pin en niveau bas
gpio -g write "$NPIN" 0
@mettre le pin en niveau haut
gpio -g write "$NPIN" 1
3 Pi4 : Emby / Samba , Librelec, Android TV
3 Pi3 : Hifiberry /OSMC, Games station, Samba / VPN / HotSpot Wifi
2 Pi2 : RFID, radio reveil (PiReveil)
1 Pi0 : traker GPS et acquisitions
1 Pi0 2W : tests divers
5 Arduinos dont 4 nanos et 1 Mega
1 ESP32

78fred
Messages : 8
Enregistré le : sam. 9 oct. 2021 17:31

Re: MQTT ESP8266

Message par 78fred » jeu. 21 oct. 2021 10:29

Bonjour Piper,

Merci pour ta réponse mais excuse moi, je me suis mal exprimé. Il est possible que ma demande n'est pas dans la bonne rubrique.
Je m'explique, dans le tuto de Dominique (#20) où il programme un ESP8266-01 pour piloter un relais en objet connecté via Domoticz, je me suis inspiré de ce programme pour commander mes radiateurs électriques via le fil pilote.

Aussi le programme initial pour commander le relais est le suivant :

Code : Tout sélectionner

void  callback ( char * topic, byte * payload, unsigned  int length) {
  // Message reçu du Broker.
  String string;
  // On vérifie qu'il vient bien de Domoticz.
  int valeur = strcmp(topic, topicIn);
  if (valeur == 0 ) {
    Serial.print ( "Message arrivé [" );
    Serial.print(topic);
    Serial.print ( "] " );
    for ( int i = 0; i < length ; i++) {
      string+=((char)payload[i]);
    }
   // Affiche le message entrant - affiche le message entrant
    Serial.println(string);
   // Parse l'objet JSON nommé "root"
    StaticJsonBuffer<512> jsonBuffer;
    JsonObject &root = jsonBuffer.parseObject(string);
    if (root.success ()) {
      int idx = root[ "idx" ];
      int nvalue = root[ "nvalue" ];

      // Activer la sortie du relais si 1a "nvalue" 1 est reçu.
      if (idx == idxDevice && nvalue == 1 ) {
        digitalWrite (pinRelais, LOW);
        En série. print ( " Périphérique " );
        En série. imprimer (idx);
        En série. println ( " sur ON " );
      } else  if (idx == idxDevice && nvalue == 0 ) {
        digitalWrite (pinRelais, HAUT);
        En série. print ( " Périphérique " );
        En série. imprimer (idx);
        En série. println ( " sur OFF " );
      } else  if (idx != idxDevice) {
        En série. print ( " Reçu informations du Device : " );
        En série. println (idx);
      }

    } else {
      Serial.println ( " Erreur de lecture du JSON ! " );
    }
  }

}
Dans Domoticz, j'ai remplacé l'inter par un sélecteur et j'ai complété les commandes pour chaque état , à savoir :

Code : Tout sélectionner

// Activer les sorties.
      if (idx == idxDevice && nvalue == 0 ) {
        digitalWrite (MOCP, HIGH);
        digitalWrite (MOCN, LOW);
        Serial.print ( " Périphérique " );
        Serial.print (idx);
        Serial.println ( " sur ARRET " );
      } else  if (idx == idxDevice && nvalue == 10 ) {
        digitalWrite(MOCP, LOW);
        digitalWrite(MOCN, HIGH);
        Serial.print ( " Périphérique " );
        Serial.print(idx);
        Serial.println ( " sur HORS GEL " );
      } else  if (idx == idxDevice && nvalue == 20 ) {
        digitalWrite(MOCP, HIGH);
        digitalWrite(MOCN, HIGH);
        Serial.print ( " Périphérique " );
        Serial.print (idx);
        Serial.println ( " sur ECONOMIE " );
       } else  if (idx == idxDevice && nvalue == 30 ) {
        digitalWrite(MOCP, LOW);
        digitalWrite(MOCN, LOW);
        Serial.print ( " Périphérique " );
        Serial.print (idx);
        Serial.println ( " sur CONFORT " );         
      } else  if (idx != idxDevice) {
        Serial.print ( " Reçu informations du Device : " );
        Serial.println (idx);
      }
    
    } else {
      Serial.println ( " Erreur de lecture du JSON ! " );
    }
Je suppose que le programme ne soit pas optimiser mais compréhensible pour ma part.
Toutefois, cela ne fonctionne pas car lorsque je passe les commandes, je vois sur le moniteur série dans IDE arduino que la "nvalue" est toujours égale à 2 (sauf l'arrêt à 0) et il m'affiche le message d'erreur " Erreur de lecture du JSON ! ".
Je comprends que les valeurs inscritent "nvalue == 10 , ou, 20, 30" ne soient pas les bonnes. Je l'ai remplacé par 1,2,3 (qui pour ma part n'était logique) mais de toute les manières j'obtiens le même résultat.

Et pourtant, j'ai bien la connexion wifi et MQTT.

Je vois bien qu'il manque un lien entre la valeur du sélecteur et le programme et là je bloque.

Je te remercie par avance de m'éclairer et navré de t'avoir mal orienté dans ta réponse.

piper
Raspinaute
Messages : 645
Enregistré le : sam. 5 juin 2021 18:57

Re: MQTT ESP8266

Message par piper » sam. 23 oct. 2021 09:48

Ok. Tu parlais de python. Ce n'est pas du python. C'est du C.
Le message vient du fait que nvalue vaut 2.
Il vaut 2 parceque strncmp vaut 2.
Ce dernier vaut 2 parce que dans les 2 chaines que tu compares avec strncmp, la 1ere est plus grande que la seconde et la position du caractere qui permet de l'affirmer est en position 2.
Bon courage

Envoyé de mon SM-J710F en utilisant Tapatalk

3 Pi4 : Emby / Samba , Librelec, Android TV
3 Pi3 : Hifiberry /OSMC, Games station, Samba / VPN / HotSpot Wifi
2 Pi2 : RFID, radio reveil (PiReveil)
1 Pi0 : traker GPS et acquisitions
1 Pi0 2W : tests divers
5 Arduinos dont 4 nanos et 1 Mega
1 ESP32

78fred
Messages : 8
Enregistré le : sam. 9 oct. 2021 17:31

Re: MQTT ESP8266

Message par 78fred » sam. 23 oct. 2021 15:38

Bonjour,
Cela démontre bien mon niveau de compétence. Je ne sais pas faire la différence entre du C et du Python.
J’ai beau chercher depuis ce matin mais là tu m’as donné une énigme supplémentaire pour lequel je suis incapable de trouver la solution.
Peux tu m’aider?
Merci

piper
Raspinaute
Messages : 645
Enregistré le : sam. 5 juin 2021 18:57

Re: MQTT ESP8266

Message par piper » sam. 23 oct. 2021 20:28

On va essayer,
déjà oups : me suis gourré car je mets toujours les accolages à la ligne dans les instructions conditionnelles et là, ce n'est pas le cas.
Donc le message vient du fait que jsonBuffer.parseObject(string) echoue

Comme le développeur a eu la merveilleuse idée d'afficher le contenue de string avant par : Serial.println(string)

Si tu nous dit ce qui s'affiche sur la sortie série , cela permettra de voir si cette le contenu de cette chaîne de caractères est réellement des données de type json.
3 Pi4 : Emby / Samba , Librelec, Android TV
3 Pi3 : Hifiberry /OSMC, Games station, Samba / VPN / HotSpot Wifi
2 Pi2 : RFID, radio reveil (PiReveil)
1 Pi0 : traker GPS et acquisitions
1 Pi0 2W : tests divers
5 Arduinos dont 4 nanos et 1 Mega
1 ESP32

78fred
Messages : 8
Enregistré le : sam. 9 oct. 2021 17:31

Re: MQTT ESP8266

Message par 78fred » dim. 24 oct. 2021 11:25

Bonjour Piper,

Tout d'abord je tiens à te remercier pour ton aide et du temps que tu y consacres. Cela fait une dizaine de jours que je me prends la tête !!

Pour information, le programme fonctionne (Normal, c'est Dominique qui l'a réalisé !!) à savoir avec un inter (ON/OFF) qui pilote une sortie.

Tu trouveras ci-dessous le programme d'origine :
https://github.com/DomoticDIY/MQTT-ESP8 ... relais.ino

Dans mon cas, je veux commander 2 sorties via un sélecteur depuis Domoticz. (donc 4 entrées pour 2 sorties).
A partir du prégramme d'origine, j'ai juste déclaré mes 2 sorties, le idxdevice, et dans le void callback j'ai décris mes 4 états (entrées) qui pilotent mes 2 sorties.
Mais, visiblement, c'était beaucoup trop simple !!

Voici ce qui se passe lorsque je commande l'arrêt, le moniteur série m'affiche :

11:01:02.990 -> Message arrivé [domoticz/out] {
11:01:02.990 -> "Battery" : 255,
11:01:02.990 -> "LevelActions" : "|||",
11:01:02.990 -> "LevelNames" : "ARRET|HORS GEL|ECONOMIE|CONFORT",
11:01:02.990 -> "LevelOffHidden" : "false",
11:01:02.990 -> "RSSI" : 12,
11:01:02.990 -> "SelectorStyle" : "0",
11:01:02.990 -> "description" : "",
11:01:02.990 -> "dtype" : "Light/Switch",
11:01:02.990 -> "hwid" : "4",
11:01:02.990 -> "id" : "0001405B",
11:01:02.990 -> "idx" : 11,
11:01:02.990 -> "name" : "Chauffage",
11:01:02.990 -> "nvalue" : 0,
11:01:02.990 -> "stype" : "Selector Switch",
11:01:02.990 -> "svalue1" : "0",
11:01:02.990 -> "switchType" : "Selector",
11:01:03.036 -> "unit" : 1
11:01:03.036 -> }
11:01:03.036 ->
11:01:03.036 -> Erreur de lecture du JSON !

Lorsque je commande le mode Hors Gel, voici ce que cela m'affiche :

11:02:42.499 -> Message arrivé [domoticz/out] {
11:02:42.499 -> "Battery" : 255,
11:02:42.499 -> "LevelActions" : "|||",
11:02:42.499 -> "LevelNames" : "ARRET|HORS GEL|ECONOMIE|CONFORT",
11:02:42.499 -> "LevelOffHidden" : "false",
11:02:42.499 -> "RSSI" : 12,
11:02:42.499 -> "SelectorStyle" : "0",
11:02:42.499 -> "description" : "",
11:02:42.499 -> "dtype" : "Light/Switch",
11:02:42.499 -> "hwid" : "4",
11:02:42.499 -> "id" : "0001405B",
11:02:42.499 -> "idx" : 11,
11:02:42.545 -> "name" : "Chauffage",
11:02:42.545 -> "nvalue" : 2,
11:02:42.545 -> "stype" : "Selector Switch",
11:02:42.545 -> "svalue1" : "10",
11:02:42.545 -> "switchType" : "Selector",
11:02:42.545 -> "unit" : 1
11:02:42.545 -> }
11:02:42.545 ->
11:02:42.545 -> Erreur de lecture du JSON !

Et effectivement, je te confirme que la "nvalue" est toujours égale à 2 quelque soit les modes suivants sélectionnés (Eco et Confort).

Au final, je ne sais pas si le problème vient du programme ou du sélecteur créer dans Domoticz. Je pencherai plutôt sur le programme et cela m'échappe totalement.

Je t'en remercie par avance si tu trouves la solution.

piper
Raspinaute
Messages : 645
Enregistré le : sam. 5 juin 2021 18:57

Re: MQTT ESP8266

Message par piper » dim. 24 oct. 2021 11:56

La structure json semble correcte.

Comme tu n'as pas mis ton code en entier difficile de dire .....

Dans ton code perso , cette partie :

Code : Tout sélectionner

} else {
      Serial.println ( " Erreur de lecture du JSON ! " );
    }
Est-ce bien le else correspondant dans le code d'origine à

Code : Tout sélectionner

if (root.success ()) {
Le mieux serait que tu fournisses ton code modifié en entier.
3 Pi4 : Emby / Samba , Librelec, Android TV
3 Pi3 : Hifiberry /OSMC, Games station, Samba / VPN / HotSpot Wifi
2 Pi2 : RFID, radio reveil (PiReveil)
1 Pi0 : traker GPS et acquisitions
1 Pi0 2W : tests divers
5 Arduinos dont 4 nanos et 1 Mega
1 ESP32

78fred
Messages : 8
Enregistré le : sam. 9 oct. 2021 17:31

Re: MQTT ESP8266

Message par 78fred » dim. 24 oct. 2021 12:55

Voice ci-dessous le code entier

// Inclure les librairies.
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>

// Déclaration des constantes, données à adapter à votre réseau.
// ------------------------------------------------------------
const char * ssid = "xxxxxxxxx" ; // SSID du réseau Wifi
const char * password = "xxxxxxxxxxx" ; // Mot de passe du réseau Wifi.
const char * mqtt_server = "xxxxxxxxxxx" ; // Adresse IP ou DNS du Broker.
const int mqtt_port = 1883 ; // Port du Brocker MQTT
const char * mqtt_login = "xxxxxxx" ; // Login de connexion à MQTT.
const char * mqtt_password = "xxxxxxxxxxxxxx" ; // Mot de passe de connexion à MQTT.
// ------------------------------------------------------------
// Variables et constantes utilisateur :
String nomModule = "Chauffage chamb"; // Nom usuel de ce module.
char* topicIn = "domoticz/out"; // Nom du topic envoyé par Domoticz
char* topicOut = "domoticz/in"; // Nom du topic écouté par Domoticz
int MOCP = 0 ; // Pin sur lequel est connecté la commande de l'alternance POSITIVE.
int MOCN = 2 ; // Pin sur lequel est connecté la commande de l'alternance NEGATIVE.
int idxDevice = 11; // Index du Device à actionner.
// ------------------------------------------------------------


WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;


void setup() {
//pinMode(pinRelais, OUTPUT);
pinMode(MOCP, OUTPUT);
digitalWrite(MOCP, LOW); // Mise à l'état des sorties à 0 pour éviter l'appel de courant et désactiver le wifi de l'ESP
pinMode(MOCN, OUTPUT);
digitalWrite(MOCN, LOW);
delay(100);
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}

void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();

}


void setup_wifi() {
// Connexion au réseau Wifi
delay(10);
Serial.println();
Serial.print("Connection au réseau : ");
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
// Tant que l'on est pas connecté, on boucle.
delay(500);
Serial.print(".");
}
// Initialise la séquence Random
randomSeed(micros());

Serial.println("");
Serial.println("WiFi connecté");
Serial.print("Addresse IP : ");
Serial.println(WiFi.localIP());

// Mise à l'état mode ARRET
digitalWrite(MOCP, HIGH);
}

void callback(char* topic, byte* payload, unsigned int length) {
// Message reçu du Broker.
String string;
// On vérifie qu'il vient bien de Domoticz.
int valeur = strcmp(topic, topicIn);
if (valeur == 0) {
Serial.print("Message arrivé [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
string+=((char)payload);
}
// Affiche le message entrant - display incoming message
Serial.println(string);

// Parse l'objet JSON nommé "root"
StaticJsonBuffer<512> jsonBuffer;
JsonObject &root = jsonBuffer.parseObject(string);
if (root.success()) {
int idx = root["idx"];
int nvalue = root["nvalue"];

if (idx == idxDevice && nvalue == 0) {
digitalWrite(MOCP, HIGH);
digitalWrite(MOCN, LOW);
Serial.print("Device ");
Serial.print(idx);
Serial.println(" sur ARRET " );
} else if (idx == idxDevice && nvalue == 10) {
digitalWrite(MOCP, LOW);
digitalWrite(MOCN, HIGH);
Serial.print("Device " );
Serial.print(idx);
Serial.println(" sur HORS GEL " );
} else if (idx == idxDevice && nvalue == 20) {
digitalWrite(MOCP, HIGH);
digitalWrite(MOCN, HIGH);
Serial.print("Device " );
Serial.print(idx);
Serial.println(" sur ECONOMIE " );
} else if (idx == idxDevice && nvalue == 30 ) {
digitalWrite(MOCP, LOW);
digitalWrite(MOCN, LOW);
Serial.print( "Device " );
Serial.print(idx);
Serial.println( " sur CONFORT " );

} else if (idx != idxDevice) {
Serial.print( "Reçu informations du Device : " );
Serial.println(idx);
}

} else {
Serial.println("Erreur de lecture du JSON !");
}
}

}

void reconnect() {
// Boucle jusqu'à la connexion MQTT
while (!client.connected()) {
Serial.print("Tentative de connexion MQTT...");
// Création d'un ID client aléatoire
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);

// Tentative de connexion
if (client.connect(clientId.c_str(), mqtt_login, mqtt_password)) {
Serial.println("connecté");

// Connexion effectuée, publication d'un message...
String message = "Connexion MQTT de "+ nomModule + " réussi sous référence technique : " + clientId + ".";
// String message = "Connexion MQTT de "+ nomModule + " réussi.";
StaticJsonBuffer<256> jsonBuffer;
// Parse l'objet root
JsonObject &root = jsonBuffer.createObject();
// On renseigne les variables.
root["command"] = "addlogmessage";
root["message"] = message;

// On sérialise la variable JSON
String messageOut;
if (root.printTo(messageOut) == 0) {
Serial.println("Erreur lors de la création du message de connexion pour Domoticz");
} else {
// Convertion du message en Char pour envoi dans les Log Domoticz.
char messageChar[messageOut.length()+1];
messageOut.toCharArray(messageChar,messageOut.length()+1);
client.publish(topicOut, messageChar);
}

// On souscrit (écoute)
client.subscribe("#");
} else {
Serial.print("Erreur, rc=");
Serial.print(client.state());
Serial.println(" prochaine tentative dans 5s");
// Pause de 5 secondes
delay(5000);
}
}
}

Répondre

Retourner vers « Des interfaces pour le Raspberry Pi »