Conception d’un dispositif de collecte de données par MQTT

Conception d’un dispositif de collecte de données par MQTT

26 août 2022 0 Par FlorianT

Bonjour à tous,

Aujourd’hui, pour mon second article, je vais vous présenter les résultats de mes travaux effectués dans le cadre de mon stage de fin d’études au G2Elab. Ces travaux portent sur la miniaturisation d’un dispositif de collecte et d’envoi de données à l’aide d’une carte Wemos D1 mini.

1. Liste des composants

Dans le cadre de la production d’énergie verte de particulier, la réinsertion dans le réseau de cette énergie est un enjeu important. Ce processus a pour but de permettre l’échange d’énergie entre particuliers et ainsi de réaliser des économies. Le G2ELab a ainsi conçu un dispositif permettant de relier la production d’un particulier vers un réseau électrique intelligent : l’Energy Box.

Une Energy Box a pour but de piloter une charge de manière à optimiser sa consommation. Pour cela, le dispositif collecte des données sur l’état du réseau et l’état de la charge et indique ainsi à l’utilisateur la marche à suivre pour optimiser ses dépenses énergétiques. Ce dispositif regroupe donc plusieurs composants :

Un compteur d’énergie : Schneider A9MEM2050. Il est alimenté en 230V via le réseau et possède une sortie pour les données en Modbus RTU avec une vitesse de transmission de 9600 baud/s. Ce compteur a été choisi car il était le plus compact (9x6x1.5cm)

Une alimentation pour la raspberry Pi : MeanWell HDR-15-5.
Elle fournit une tension de 5V et un courant entre 0 A et 2.4 A, avec en entrée la tension du réseau. Cette alimentation a également été choisi pour son aspect compact (mêmes dimensions que le compteur Schneider).

Une carte Raspberry Pi 3b+.
Les cartes Raspberry Pi permettent de collecter et traiter des informations de manière efficace tout en étant une solution compacte. Ici, elle récupère ainsi les données du compteur et les envoie par MQTT à un serveur qui se chargera de les traiter. Ce serveur intervient également dans le pilotage de la charge, puisqu’il peut indiquer à la carte lorsque l’utilisateur veut ou non activer celle-ci.

Un relais finder 34.51 couplé à un contacteur
Les relais électromécaniques permettent de commuter l’état d’une charge d’un état haut à un état bas. Cette commande se fait grâce à un potentiel faible, ici par exemple on le pilote en 5V. De plus, ce composant permet un isolement entre l’Energy Box et la charge, ce qui garantit une sécurité supplémentaire.

Ce stage ayant pour but la miniaturisation de la partie de collecte et envoi des données et de pilotage de la charge, j’ai également été amené à modifier les composants présents et à en utiliser de nouveaux, voici la liste ci-dessous:

Une carte Arduino programmable Wemos D1 mini.
La carte Wemos D1 mini est une carte Arduino qui possède 4MB de mémoire flash. Elle est alimentée en 5V, et permet d’effectuer des calculs simples rapidement.

Un convertisseur MAX485TTL.
Ce convertisseur est un module d’interface MAX485 TTL vers RS-485 qui permet au microcontrôleur (la Wemos) d’utiliser la signalisation différentielle RS-485 pour des communications série robustes sur de longues distances. Ici, le convertisseur va ainsi permettre de récupérer les données du compteur par une communication Modbus série.

2. Branchement du dispositif

Afin de pouvoir récupérer les données du compteur, nous allons utiliser le convertisseur RS485. Nous allons donc devoir le connecter à notre carte Wemos.

Pour commencer, il faut alimenter le convertisseur via les pins 5V et GND (fils noirs et rouges). Ensuite, on s’occupe de la transmission de données, qui se fait par les autres pins du MAX485. Tout d’abord la réception des données envoyées par le compteur sous protocole Modbus est assurée par les entrées A et B sur le bornier. Ensuite, la transmission de ces données est assurée par les pins DE et DI qui sont connectées aux pins D3 et D4 de la Wemos (fils jaunes et bleus). J’ai choisi d’utiliser les pins D3 et D4 car les pins D0 et D1 sont prévues pour assurer une liaison I2C qui sert surtout pour le stockage et le traitement de données.

Les pins TX et RX de la Wemos sont utilisés pour la mise en place de la communication série entre la carte et l’ordinateur que l’on va utiliser pour implémenter le code. Cette communication se fait par câble USB, et permet d’afficher sur un moniteur des messages qui pourront servir pour vérifier le bon fonctionnement de notre code.

On connecte ensuite les bornes A et B du convertisseur aux bornes A et B du compteur Schneider.

3. Initialisation du programme

Maintenant que les composants sont correctement alimentés, je peux passer à la rédaction du programme.

Pour chaque programme que j’ai codé, j’ai tout d’abord établi un cahier des charges pour lister les fonctions que doit remplir ce dernier. Ainsi, pour la première version du code les objectifs étaient :

  • Connexion de la Wemos au réseau Wifi utilisé par l’ordinateur pour assurer l’échange de données.
  • Collecte des données du compteur Schneider.
  • Envoi des données et affichage simple : ici, j’ai choisi de les afficher via un URL.

Pour réaliser ces tâches, j’ai choisi d’utiliser la librairie « ModbusMaster », qui va permettre d’établir une connexion Modbus RTU entre la Wemos et notre ordinateur et ainsi échanger les données et la librairie « ESP8266WiFi » qui va permettre à la carte de se connecter au réseau Wifi. On intègre également la librairie « SoftwareSerial », qui permettra de mettre en place une communication via le moniteur série et donc, comme expliquer précédemment, de corriger d’éventuelles erreurs.

Je peux ensuite définir les pins de communication utilisés sur la Wemos et les identifiants wifi.

#include <ModbusMaster.h>
#include <ESP8266WiFi.h>  //Enables the ESP8266 to connect to the local network via WiFi
#include <SoftwareSerial.h>

// Declaration des pins
#define MAX485_DE      0
#define MAX485_RE_NEG  2

Une fois toutes les variables utiles déclarées, je peux me concentrer sur le corps du programme : récupérer les données du compteur et les envoyer pour les afficher via un URL.

4. Affichage de données via un URL

Pour commencer, il faut écrire une fonction qui va collecter les valeurs des variables que l’on souhaite afficher. Pour cela, on doit utiliser des numéros de registres prédéfinis par le fabricant. Ces valeurs de registres se trouvent dans la documentation technique du compteur dans la catégorie communication Modbus et chaque registre contient la valeur associée à une variable. On y retrouve également le type de ces données. Comme la communication Modbus transmet les données en hexadécimal, il faudra aussi mettre au point un convertisseur d’hexadécimal vers le type de la donnée souhaitée pour pouvoir l’exploiter.

Ainsi, on va relever les valeurs de la tension (registre 3028), de la fréquence (registre 3110), de la puissance (registre 3054), du courant (registre 3000) et de l’énergie consommée (registre 3212). On remarque également que les variables sont de type float32, sauf l’énergie qui est de type int64. Lors du relevé, je vais faire en sorte de stocker les différentes valeurs du même type dans un tableau, on aura donc un tableau de float32, avec 4 valeurs et un tableau d’int64 avec une valeur. Il faudra également prendre en compte la taille de nos données : le type float32 est, comme son nom l’indique, codé sur 32 bits. Chaque registre faisant 16 bits, il faudra lire 2 registres pour récupérer l’information souhaitée. Pour lire la valeur d’un int64, soit 64 bits, il faudra donc prendre 4 registres.

Une fois qu’on a relevé nos valeurs, on peut les afficher via un URL, en utilisant la fonction client.println, on obtient ainsi le code suivant :

#include <ModbusMaster.h>
#include <ESP8266WiFi.h>  //Enables the ESP8266 to connect to the local network via WiFi
#include <SoftwareSerial.h>
#include "config_EB.h"

#define baud 9600
#define timeout 100
#define  polling 100
#define retry_count 10
ModbusMaster node;

#define MAX485_DE      0
#define MAX485_RE_NEG  2

// set wifi IDs
const char* ssid = "XXX";
const char* password = "XXX";
WiFiServer server(80);

// Initialise the WiFi and MQTT Client objects
WiFiClient wifiClient;

void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
}

void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
}

//------------------------------------------------
// Convent 32bit to float
//------------------------------------------------
float HexTofloat(uint32_t x) 
{
  return (*(float*)&x);
}

uint32_t FloatTohex(float x) 
{
  return (*(uint32_t*)&x);
}
//------------------------------------------------

float Read_Meter_float(char addr , uint16_t  REG)
{
  float i = 0;
  uint8_t result,j;

  uint16_t data[2];
  uint32_t value = 0;
  node.begin(ID_slave,Serial);
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);

  result = node.readHoldingRegisters(REG,2); ///< Modbus function 0x03 Read Holding Registers
  delay(500);
  if (result == node.ku8MBSuccess) 
  {
    for (j = 0; j < 2; j++)
    {
      data[j] = (node.getResponseBuffer(j));
    }
    value = data[0];
    value = value << 16;
    value = value + data[1];
    i = HexTofloat(value);
    return i;
  } else
  {
    delay(1000);
    return 0;
  }
}

void GET_METER_FLOAT() 
{     // Update read all data
  delay(1000);                            
    for (char i = 0; i < Total_of_Reg_float ; i++)
    {
      DATA_METER_FLOAT [i] = Read_Meter_float(ID_slave, Reg_float_addr[i]);
    } 
}

float Read_Meter_int64(char addr , uint16_t  REG) 
{
  uint64_t i = 0;
  uint8_t result,j;

  uint16_t data[4];
  uint32_t value = 0;
  node.begin(ID_slave,Serial);
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);
  
  result = node.readHoldingRegisters(REG,4); ///< Modbus function 0x03 Read Holding Registers
  delay(500);
  if (result == node.ku8MBSuccess) 
  {
    for (j = 0; j < 4; j++)
    {
      data[j] = (node.getResponseBuffer(j));
    }

    value = data[0];
    for (j = 1; j < 4; j++)
    {
      value = value << 16;
      value = value + data[j];
    }
    i = value;
    return i;
  } else 
  {
    delay(1000); 
    return 0;
  }
}

void GET_METER_INT64() 
{     // Update read all data
  delay(1000);                            
    for (char i = 0; i < Total_of_Reg_int64 ; i++)
    {
      DATA_METER_INT64 [i] = Read_Meter_int64(ID_slave, Reg_int64_addr[i]);
    } 
}

//**************************************************************************************************************
void setup() 
{
  Serial.begin(baud);

  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

  // Connect to WiFi network
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
  
  // Start the server
  server.begin();

  delay(1);
}

void loop() 
{
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
 
  // Wait until the client sends some data
  while(!client.available()){
    delay(1);
  }
 
  // Read the first line of the request
  String request = client.readStringUntil('\r');
//  Serial.println(request);
  client.flush();

  GET_METER_FLOAT();
  GET_METER_INT64();

  Serial.print("Tension: ");
  Serial.print(DATA_METER_FLOAT[0],3);
  Serial.println("V");

  Serial.print("Frequence: ");
  Serial.print(DATA_METER_FLOAT[1],3);
  Serial.println("Hz");

  Serial.print("Puissance active: ");
  Serial.print(DATA_METER_FLOAT[2],3);
  Serial.println("W");

  Serial.print("Courant: ");
  Serial.print(DATA_METER_FLOAT[3],3);
  Serial.println("A");

  Serial.print("Energie: ");
  Serial.print(DATA_METER_INT64[0],3);
  Serial.println("Wh");

  Serial.println("<br><br>");
  Serial.println("<a href=\"/Refresh\"\"><button>Refresh </button></a>");
  Serial.println("</html>");
  
  delay(1);
}

Si l’on compile et qu’on lance le code, on obtient bien nos données en cherchant l’URL sur notre navigateur :

Capture d’écran des données affichées via un URL

5. Envoi de données sous MQTT non sécurisé

Maintenant que l’on récupère et affiche bien nos données, on va pouvoir robustifier notre dispositif. Pour ce faire on va utiliser le protocole MQTT pour envoyer nos données.

Comme précédemment, je définis les fonctions que le code doit remplir :

  • Connexion de la Wemos au réseau Wifi auquel est connecté le serveur(=broker) MQTT.
  • Connexion au serveur MQTT.
  • Récupération des données via le convertisseur RS485 TTL MAX485.
  • Envoi des données sous protocole MQTT au serveur MQTT.

Pour réaliser ces tâches, j’utilise la librairie “PubSubClient” et la librairie “EspMQTTClient”. On peut reprendre la structure de notre code de collecte des données et y rajouter les fonctions nécessaires pour le protocole MQTT.

Il va falloir déclarer les noms des topics que l’on va transmettre au serveur MQTT, de façon à identifier nos différentes données. Ensuite on pourra établir la connexion avec le serveur MQTT et publier nos données via la fonction publish().

#include <ModbusMaster.h>
#include <ESP8266WiFi.h>  //Enables the ESP8266 to connect to the local network via WiFi
#include <SoftwareSerial.h>
#include <PubSubClient.h> //Connect andpublish to the MQTT broker
#include "config_EB.h"

#define baud 9600
#define timeout 100
#define  polling 100
#define retry_count 10
ModbusMaster node;

#define MAX485_DE      0  //D3 = 0
#define MAX485_RE_NEG  2  //D4 = 2

// set wifi IDs
const char* ssid = "XXX";
const char* password = "XXX";
WiFiServer server(80);

// MQTT
const char* mqtt_server = "XXX.XXX.XXX.XXX";  //IP of the MQTT Broker : 
const char* voltage_topic = "EB3/voltage";
const char* frequence_topic = "EB3/frequence";
const char* active_power_topic = "EB3/active_power";
const char* current_topic = "EB3/current";
const char* energy_topic = "EB3/energy";
const char* mqtt_username = "admin";    //MQTT username
const char* mqtt_password = "XXX";    //MQTT password
const char* clientID = "client_local";         //MQTT client ID


// Initialise the WiFi and MQTT Client objects
WiFiClient wifiClient;
// 1883 is the listener port for the Broker
PubSubClient client(mqtt_server, 1883, wifiClient);

void connect_Wifi_MQTT() {
  // Connect to WiFi network
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }

  // Connect to MQTT Broker
  // client.connect returns a boolean value to let us know if the connection was successful.
  // If the connection is failing, make sure you are using the correct MQTT Username and Password (Setup Earlier in the Instructable)
  if (client.connect(clientID, mqtt_username, mqtt_password)) {
    Serial.println("Connected to MQTT Broker!");
  }
  else {
    Serial.println("Connection to MQTT Broker failed...");
  }
}

void check_wifi() {
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Wait until the client sends some data
  while (!client.available()) {
    delay(1);
  }

  // Read the first line of the request
  String request = client.readStringUntil('\r');
  //  Serial.println(request);
  client.flush();
}

// Rajouter les fonctions de collecte des données !!

void setup()
{
  Serial.begin(baud, SERIAL_8E1);

  connect_Wifi_MQTT();

  // Start the server
  server.begin();

  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);
  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

}

void loop()
{
  check_wifi();

  GET_METER_FLOAT();
  GET_METER_INT64();

  //MQTT can only transmit strings
  String voltage = String((float)DATA_METER_FLOAT[0]);
  String frequence = String((float)DATA_METER_FLOAT[1]);
  String active_power = String((float)DATA_METER_FLOAT[2]);
  String current = String((float)DATA_METER_FLOAT[3]);
  String energy = String((float)DATA_METER_INT64[0]);

  // Check if we publish to the MQTT Broker
  if (client.publish(voltage_topic, String(DATA_METER_FLOAT[0]).c_str())) {
    Serial.println("Voltage sent!");
    Serial.println(DATA_METER_FLOAT[0]);
  }
  if (client.publish(frequence_topic, String(DATA_METER_FLOAT[1]).c_str())) {
    Serial.println(DATA_METER_FLOAT[1]);
  }
  if (client.publish(active_power_topic, String(DATA_METER_FLOAT[2]).c_str())) {
    Serial.println(DATA_METER_FLOAT[2]);
  }
  if (client.publish(current_topic, String(DATA_METER_FLOAT[3]).c_str())) {
    Serial.println(DATA_METER_FLOAT[3]);
  }
  if (client.publish(energy_topic, String(DATA_METER_INT64[0]).c_str())) {
    Serial.println(DATA_METER_INT64[0]);
  }

  delay(1);
}

6. Affichage via un interface Jeedom

En ce qui concerne la configuration de Jeedom, vous pouvez aller voir l’article suivant qui lui est consacré:

7. Pilotage de charge

Le pilotage du relais est actuellement géré par la Raspberry Pi et est régulé en mode ON/OFF. Pour reprendre ce concept, j’ai écrit un petit programme qui va tout simplement passer à l’état haut ou bas un pin donné dans un pas de temps défini.

Pour ce faire, je vais donc tout d’abord définir le pin que je vais utiliser pour piloter le relais. Je choisis arbitrairement le pin D8 (numéro 15 dans la déclaration), car il n’est pas affilié à une fonction particulière de la Wemos.

Ensuite, je vais déclarer ce pin en tant que sortie, pour indiquer que son état va changer et dans la section loop() de mon programme je vais modifier cet état grâce à la fonction digitalWrite(), qui permet de passer du mode « haut » au mode « bas » sur le pin.

#define Relay 15                 // Digital pin D8
int switch_HL = 0;

void setup() {
  Serial.begin(9600);
  pinMode(Relay, OUTPUT);       // declare Relay as output
}

void loop() {
  if (switch_HL == 0) {
    digitalWrite (Relay, HIGH);
    switch_HL = 1;
  }
  else if (switch_HL == 1) {
    digitalWrite (Relay, LOW);
    switch_HL = 0;
  }
  delay(5000); 
}

8. Réalisation d’un circuit imprimé

Après avoir développé la partie programmation du dispositif, je me suis intéressé à la partie matérielle et plus précisément à la réalisation d’un circuit imprimé. Ce circuit permettra donc de remplacer les fils par des chemins de cuivres, qui seront donc plus performants, mais également de mettre au point une alimentation par le secteur pour le dispositif et ainsi s’assurer qu’il puisse fonctionner en permanence. Pour cela j’ai utilisé un convertisseur 220V-5V auquel j’ai ajouté un bornier pour recevoir et transmettre le 220V. Pour réaliser ce circuit imprimé et toujours dans l’idée open source de notre projet, j’ai utilisé la suite logicielle Kicad. Etant libre de droit, il existe de nombreux tutoriels et exemples accessibles en ligne pour comprendre les logiciels de schématique et de circuit imprimé et ainsi prendre en main et apprendre à utiliser ces outils.

Pour commencer, il a fallu créer des empreintes pour chacun de nos composants et ensuite nous avons pu passer à l’assemblage.

Le circuit imprimé doit répondre à plusieurs critères et règles d’usages :

  • Le circuit doit effectuer les connexions entre les différents pins pour permettre au dispositif de fonctionner correctement.
  • Sur chaque composant, les soudures doivent se faire sur la même face, les circuits doivent donc également être reliés aux pins sur la même face pour chaque composant. On utilise donc des via pour faire passer le fil d’une face à l’autre du circuit.
  • Le but de notre dispositif étant la miniaturisation, il est donc important de réduire au maximum la taille du circuit, ce qui représentera aussi une diminution du coût du circuit, car moins de cuivre utilisé.
  • Les fils de cuivres devront avoir une épaisseur adaptée au voltage qu’ils transportent. En effet, pour les fils conduisant du 220V il faudra une épaisseur plus importante (2 mm) que pour ceux conduisant du 5V (1 mm). Enfin pour compléter cette sécurité, on utilisera des plans de masses autour des fils du 5 V, et on isolera les fils de 220V sans rien autour.

Après plusieurs tests et prototypes, j’ai finalement choisi un circuit sur une face et qui est le plus optimal d’un point de vue dimensions.

Capture d’écran du PCB sur le logiciel Kicad

Au final, le dispositif ressemble à cela

9. Problèmes rencontrés et conseils

  1. Branchement du dispositif

L’un des premiers problèmes rencontrés était lors du chargement de mon code sur la Wemos. En effet, les pins RX et TX sont responsables de la communication série entre la carte Wemos et les autres dispositifs. Ainsi, lorsque je veux téléverser mon code sur la carte, il faut débrancher ses fils du convertisseur le temps du téléchargement (clignotement de la LED) du code, pour éviter un conflit entre les différents flux de données (de la communication série et du port micro USB).

Un autre problème que j’ai rencontré au cours de ce projet était un problème de détection de la Wemos par l’ordinateur que j’utilisais. En effet, la carte n’était plus détectée sur l’IDE Arduino, ni dans les périphériques USB, alors que cette dernière était bien alimentée et en fonctionnement.

D’après les informations que j’ai pu trouver, il pourrait s’agir d’un problème de driver, j’ai donc essayé de les mettre à jour et de reconnecter la carte, mais le problème persiste. J’ai également essayé de désinstaller-réinstaller l’IDE Arduino mais impossible de me connecter à la carte.

Malgré le fait que je n’ai pas réussi à repérer le problème, j’ai essayé de comprendre ce qui avait pu poser ce dysfonctionnement. J’ai ainsi remarqué que les plans de masses sur le PCB ne correspondaient pas : en effet, on a 5V en entrée des composants sur une face et de l’autre on a -3V, ce qui a pu être à l’origine du dysfonctionnement. Pour résoudre ce problème, j’ai modifié le PCB pour relier les deux plans de masses.

2. Affichage des données via URL

Lors de la première exécution de mon code, j’ai remarqué un problème dans la communication série. En effet, malgré le fait que les données étaient correctement affichées via l’URL, la communication série n’affichait pas les messages pour aider au débogage.

Capture d’écran où l’on voit la bonne réception de données via l’URL, et les messages erronés du terminal série

Le problème ici est la vitesse de transmission pour la communication série. Comme expliqué précédemment, la communication série se fait à une vitesse de 9600 baud/s. On peut la modifier directement sur le moniteur série et, en effet, elle était réglée par défaut à 11500 baud/s. Une fois la vitesse changée, on a bien nos messages de débogage qui s’affichent.

3. Envoi de données sous MQTT

Les principaux problèmes que j’ai rencontrés étaient d’utiliser la bonne syntaxe dans l’appel des fonctions existantes des librairies. Ainsi il fallait que je me renseigne bien au préalable sur les arguments que chaque fonction nécessite. Avec l’aide de nombreux exemples trouvés en ligne j’ai pu me débloquer lorsque c’était nécessaire. Aussi, comme les bibliothèques Arduino évoluent dans le temps il est parfois arrivé qu’un code qui fonctionne présente une nouvelle erreur quelques semaines plus tard.

En effet, j’ai donc rencontré un problème lorsque je définissais la communication série. De base la fonction que j’utilisais « Serial.begin() » ne prenait en argument que la vitesse de transmission. Mais désormais, il faut rajouter un mode de fonctionnement qui définira le nombre de bits, la parité et le bit de stop des messages que l’on va transmettre. Dans mon cas, je dois régler à 8 bits de données, pas de parité et 1 bit de stop, ce qui correspondra à « SERIAL_8E1 ».

10. Perspectives d’amélioration

Je vais maintenant vous présenter des perspectives qui selon moi seraient intéressantes à suivre et à mettre en place pour améliorer le dispositif.

Tout d’abord, il serait intéressant et cela apporterait une vraie plus-value, de réussir à mettre en place la communication par MQTT sécurisée, qui permettrait d’assurer que les données personnelles des utilisateurs soient protégées.

Ensuite, le pilotage du relais couplé à la collecte et l’envoi de données dans un seul programme serait également une fonctionnalité très utile, car il permettrait à l’utilisateur de pouvoir gérer tout le dispositif depuis l’interface de Jeedom.

En plus de cela, l’affichage des données pourrait être sous forme graphique, afin d’avoir un aperçu plus global de sa consommation dans le temps. En effet, si l’on arrivait à récupérer l’heure de mesure des variables, on pourrait ainsi tracer une courbe d’énergie consommée dans la journée ou encore la semaine et en la comparant avec la fréquence du réseau, identifier des schémas récurrents de surproduction ou sous-production pour optimiser la consommation du client. Cet affichage pourrait se faire en utilisant Grafana, qui est un logiciel pour la conception de diagramme et de courbes que l’on peut coupler à Jeedom.

Toujours dans cette optique d’optimiser la consommation par rapport à la fréquence réseau, il pourrait être utile d’écrire un algorithme qui analyserai la fréquence en temps réel et préviendrait automatiquement l’utilisateur en cas de variation importante. Pour cela, il existe des librairies et des fonctions sur Arduino qui peuvent permettre d’envoyer des messages sous formes de SMS, ou de notifications par mail.

Un autre aspect qui pourrait être intéressant serait de rendre le pilotage de la charge linéaire et non pas juste commutatif. Ainsi, plutôt que d’allumer ou d’éteindre une charge, on pourrait adapter la consommation de manière plus précise et cela permettrait de piloter plus de charge, comme des pompes par exemple.

11. Conclusion

Pour conclure cet article, j’ai pu apporter au projet Energy Box une version miniature de la collecte et de l’envoi de données et également de la documentation ainsi que des prototypes pour continuer sur des voies d’amélioration du dispositif.

En effet, j’ai d’abord pu adapter les parties de récupération et de transmission des données par protocole MQTT. Ensuite, j’ai conçu un circuit imprimé pour optimiser la taille de mon dispositif et faire en sorte qu’il soit alimenté par le réseau. J’ai pu tester par la suite la mise en place de la transmission des données à l’aide d’InfluxdB et la mise en place d’un protocole MQTT sécurisé. Il m’a également été possible de piloter une charge via un code Arduino.

Florian Thiebaut