// Import des librairies
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
/******* PARAMÈTRES À MODIFIER SELON VOTRE CONFIG ********/
#define ssid "XXXXXXX" // votre ssid
#define password "YYYYYYYYYYYYYYYYYY" // votre mdp
#define mqtt_server "192.168.X.X" // ip du serveur MQTT mosquitto
#define mqtt_username "XXXX" // votre login mqtt
#define mqtt_password "XXXXXXXX" // votre mdp mqtt
#define mqtt_topic_in "domoticz/in"
#define mqtt_topic_out "domoticz/out"
#define bouton_IDX 2 // Doit être le même que le capteur virtuel dans Domotocz */
#define buttonPin 0 // D3
#define ledPin 2 // D4
int etat_led = LOW; // led éteinte au démarrage
boolean etat_change = true; // flag à true pour forcer l'envoie de l'etat de la led au démarrage (led off) sur domoticz
int etat_bouton = 0;
int ancien_etat_bouton = 0;
String etat_led_string = "Off";
WiFiClient nodemcuClient; // On crée l'objet WiFiClient
PubSubClient client(nodemcuClient); // On crée l'objet PubSubClient
// La fonction callback qui reçoit et traite les infos que domoticz a envoyé a MQTT
void callback(char* topic, byte* payload, unsigned int length) {
DynamicJsonDocument jsonBuffer(MQTT_MAX_PACKET_SIZE); // On déclare un buffer comme doc json
String msgEntrant="";
Serial.print("[callback()] Message entrant [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) { // on met ce qui arrive dans msgEntrant
msgEntrant+=((char)payload[i]);
}
Serial.print(msgEntrant); // on l'affiche
if ( strcmp(topic, mqtt_topic_out) == 0 ) { // si c'est bien le topic de domoticz
DeserializationError error = deserializeJson(jsonBuffer, msgEntrant); // on récupère les champs du json
if (error) {
Serial.print(F("[callback()] deserializeJson() --> echec : "));
Serial.println(error.f_str());
return;
}
String idx = String(jsonBuffer["idx"]); // le champs idx
String valeur = String(jsonBuffer["nvalue"]); // le champs nvalue
if ( idx == String(bouton_IDX)) {
if( valeur == "0") { // si nvalue vaut 0
if( etat_led = HIGH ) { // et que la led est allumé
digitalWrite(ledPin, LOW); // on éteint la led
etat_led = LOW;
etat_led_string = "Off";
}
} else { // sinon
digitalWrite(ledPin, HIGH); // on allume la led
etat_led = HIGH;
etat_led_string = "On";
}
Serial.printf("[callback()] La LED est sur : %s dans domoticz.\n", etat_led_string);
Serial.printf("[callback()] La vrai LED est sur : %s .\n", etat_led_string);
Serial.println();
}
}
delay(20);
}
// fonction qui connecte ou reconnecte le nodemcu au serveur MQTT
void MQTTconnect() {
while (!client.connected()) {
Serial.println("[MQTTconnect()] Attente de connexion ...");
if ( client.connect( "nodemcu", mqtt_username, mqtt_password) ) { // connexion au serveur
Serial.println("[MQTTconnect()] Connexion OK");
Serial.print("[MQTTconnect()] Abonnement au topic domoticz/out --> ");
if ( client.subscribe(mqtt_topic_out, 0) ) Serial.println("OK"); // abonnement au topic de domoticz
else Serial.println("KO");
Serial.println();
} else {
Serial.print("[MQTTconnect()] echec de connection : ");
Serial.print(client.state());
Serial.println(" nouvelle tentative dans 5 secondes");
Serial.println();
Serial.print("[MQTTconnect()] vérification etat led et ajustement avec domoticz: ");
BoutonPoussoir();
delay(5000);
}
}
}
// fonction qui écoute le bouton
void BoutonPoussoir() {
etat_bouton = digitalRead(buttonPin); // ecoute du bouton
if (etat_bouton != ancien_etat_bouton) { // si different de l'ancien état
ancien_etat_bouton = etat_bouton;
if (etat_bouton == LOW) {
etat_led = !etat_led;
etat_change = true;
etat_led ? etat_led_string = "On" : etat_led_string = "Off";
Serial.println("[BoutonPoussoir()] Bouton activé");
}
digitalWrite(ledPin, etat_led);
}
if(etat_change) {
char msgSortant[MQTT_MAX_PACKET_SIZE+1];
Serial.print("[loop()] Message à publier [domoticz/in] --> ");
sprintf(msgSortant, "{\"command\" : \"switchlight\", \"idx\" : %d, \"switchcmd\": \"%s\"}\n", bouton_IDX, etat_led_string);
Serial.println(msgSortant);
Serial.print("[loop()] Publication sur domoticz/in --> ");
if ( client.publish(mqtt_topic_in, msgSortant) ) {
etat_change = false;
Serial.println("OK");
Serial.println();
}
else {
Serial.println("KO");
Serial.println();
}
Serial.printf("[loop()] La vrai LED est sur %s \n", etat_led_string);
}
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println();
Serial.println("[setup()] Initialisation ...");
pinMode(ledPin,OUTPUT);
digitalWrite(ledPin, etat_led);
pinMode(buttonPin,INPUT);
Serial.print("[setup()] Connexion au WIFI -> ");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
Serial.println("OK");
Serial.print("[setup()] Adresse ip : ");
Serial.println(WiFi.localIP());
client.setServer(mqtt_server, 1883); // on défini le serveur MQTT
client.setCallback(callback); // on défini la fonction de callback
Serial.printf("[setup()] La LED est %s\n", etat_led_string);
Serial.println("[setup()] Initialisation OK");
Serial.println();
}
void loop() {
client.loop();
if (!client.connected()) {
MQTTconnect();
}
BoutonPoussoir();
}