boutons domotique WiFi MQTT piloté par ESP8266

Boutons domotique WiFi MQTT piloté par ESP8266

Tout petit rikiki

boutons domotique WiFi MQTT piloté par ESP8266

Ces boutons, qui ne mesurent que 6 x 4 cm, sont alimentés par USB.
Ils permettent de commander des points lumineux via MQTT sur la centrale domotique publiée dans cet article : Centrale domotique HomeAssistant à base d’un Raspberry Pi

Le besoin

Ma chère et tendre épouse souhaitait pouvoir allumer les spots des barbacanes et le lampadaire halogène de sa table de salon, sans se lever.
Vous le savez aussi bien que moi : que ce qu’épouse veut … 😉
Bref, pas le choix !

Point trop n’en faut

Le montage est des plus simple.
Il ne contient qu’un microcontrôleur et deux boutons poussoirs NO.
Les résistances de pull-up internes au 8266 permettent de n’avoir aucun composant externe.

Comment cela fonctionne-t-il ?

Le microcontrôleur se connecte en WiFi sur mon réseau IOT.
Il se connecte ensuite à mon serveur MQTT.
Un appui sur un bouton envoie un message MQTT à la centrale Home Assistant.
Celle-ci bascule le point lumineux correspondant.

boutons commande électronique 1

Le boîtier est basé sur ce modèle publié sur ce site. Je l’ai imprimé en PLA Creality High Speed noir.
J’ai ajouté les trous pour les poussoirs, le trou pour le connecteur USB et les ouies de ventilation.

J’utilise Platformio comme environnement de développement :

Le fichier platformio.ini

Ce fichier de définition correspond au microcontrôleur utilisé. A savoir, un Wemos D1 mini.
Si vous optez pour un autre microcontrôleur, il conviendra de l’adapter.

[env:d1_mini]
platform = espressif8266
board = d1_mini
framework = arduino
monitor_speed = 115200
lib_deps = 
	thomasfredericks/Bounce2@^2.72
	marvinroger/AsyncMqttClient@^0.9.0

Le fichier jagprod.h

Dans le code qui suit, il conviendra de remplacer les identifiants et mots de passes ainsi que les adresses IP en fonction de votre infrastructure !

#ifndef jagprod_h
#define jagprod_h

// WiFi
#define sid "votre SSID"
#define wifi_sesame "Votre mot de passe WiFi"

// IP (Si utilisation en DHCP, supprimer cette partie)
const uint8_t ip[4] = {Adresse IP de l'hôte dans votre réseau};
const uint8_t mask[4] = {Masque de sous-réseaux};
const uint8_t ns[4] = {Adresse IP du serveur DNS};
const uint8_t gw[4] = {Adresse de la passerelle};

// MQTT
const char *mqtt_serveur = "adresse IP du serveur MQTT";
const uint16_t mqtt_port = port MQTT;
const char *mqtt_identifiant = "identifiant MQTT";
const char *mqtt_sesame = "Mot de passe MQTT";

#endif

Le programme

La bibliothèque Bounce2 de Thomas Fredericks gère parfaitement l’action sur les boutons poussoirs et l’anti-rebond.
Pour la gestion du MQTT, j’utilise la bibliothèque AsyncMqttClient maintenue par Marvin Roger.

#include <Arduino.h>
#include <jagprod.h>

//-----WIFI-----
#include <ESP8266WiFi.h>
void WiFiEvent(WiFiEvent_t event);
bool wifi_statut = false;

void WiFiEvent(WiFiEvent_t event)
{
  switch (event)
  {
  case WIFI_EVENT_STAMODE_CONNECTED:
    Serial.println("Assoscié");
    break;
  case WIFI_EVENT_STAMODE_GOT_IP:
    Serial.println("Connecté");
    wifi_statut = true;
    break;
  case WIFI_EVENT_STAMODE_DISCONNECTED:
    Serial.println("Wifi perdu");
    wifi_statut = false;
    break;
  default:
    break;
  }
}

#include <Bounce2.h>
#define lampadaire_PIN D7
#define barbacanes_PIN D6
Bounce2::Button lampadaire = Bounce2::Button();
Bounce2::Button barbacanes = Bounce2::Button();
bool etatlampadaire = "false";
bool etatbarbacanes = "false";

//-----MQTT-----
#include <AsyncMqttClient.h>
AsyncMqttClient mqtt_client;
unsigned long derniere_connexion_mqtt = 0;
unsigned long mqtt_timeout = 5000;
bool mqtt_statut = false;
static String message;

// === MQTT EVENTS ===
void onMqttConnect(bool sessionPresent)
{
  Serial.println("✅ Connecté au broker MQTT !");
  mqtt_statut = true;
  mqtt_client.subscribe("homeassistant/status", 1); // QoS 1
}

void onMqttDisconnect(AsyncMqttClientDisconnectReason reason)
{
  Serial.printf("⚠️ Déconnecté du broker MQTT (raison: %d)\n", static_cast<uint8_t>(reason));
  mqtt_statut = false;
}

void onMqttPublish(uint16_t packetId)
{
  Serial.printf("📤 Publication MQTT confirmée (packetId: %u)\n", packetId);
}

void onMqttMessage(char *topic, char *payload, AsyncMqttClientMessageProperties properties, size_t len, size_t index, size_t total)
{
  message = "";
  for (size_t i = 0; i < len; i++)
  {
    message += (char)payload[i];
  }
  Serial.printf("📩 Message reçu [%s] : %s\n", topic, message.c_str());
  if (strcmp(topic, "homeassistant/status") == 0)
  {
    if (message == "online")
    {
        //mqtt_client.publish("iotmqtttest/connecte", 1, false, "online"); //ou pour un sensor, republier l'état
    }
}
}

void setup()
{
  Serial.begin(115200);
  delay(100);
  lampadaire.attach(lampadaire_PIN, INPUT_PULLUP);
  lampadaire.setPressedState(LOW);
  lampadaire.interval(5);
  barbacanes.attach(barbacanes_PIN, INPUT_PULLUP);
  barbacanes.setPressedState(LOW);
  barbacanes.interval(5);
  WiFi.setAutoReconnect(true);
  WiFi.setSleep(false);
  WiFi.config(ip, gw, mask, ns); // Mettre en remarque pour une utilisation en DHCP
  WiFi.onEvent(WiFiEvent);
  WiFi.begin(sid, wifi_sesame);
  // MQTT
  mqtt_client.setServer(mqtt_serveur, mqtt_port);
  mqtt_client.setCredentials(mqtt_identifiant, mqtt_sesame);
  mqtt_client.setClientId("BoutonSalon");
  mqtt_client.onConnect(onMqttConnect);
  mqtt_client.onDisconnect(onMqttDisconnect);
  mqtt_client.onMessage(onMqttMessage);
  mqtt_client.onPublish(onMqttPublish);
}

void loop()
{
     if (wifi_statut == true and mqtt_statut == false and millis() - derniere_connexion_mqtt > mqtt_timeout)
  {
    Serial.println("Tentative de connexion MQTT");
    mqtt_client.connect();
    derniere_connexion_mqtt = millis();
  }

  lampadaire.update();
  barbacanes.update();
  if (lampadaire.pressed())
  {
    mqtt_client.publish("BoutonsSalon/lampadaire", 1, false, "action");
  }
  if (barbacanes.pressed())
  {
    mqtt_client.publish("domestia/ida1", 1, false, "action");
  }
}

N’hésitez pas à laisser un commentaire ou poser vos questions via le formulaire ci-dessous

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *