![Stacks Image 9724](files/stacks-image-f76d68c-172x136.jpg)
Tuto spécial maker, nous allons réaliser une sonde température avec un microcontrôleur ESP 8266 nodeMCU et une sonde AM2302. Cette sonde se connectera au réseau Wifi. Elle sera interrogeable par un mini-serveur web ou par une requête SNMP. Cette dernière nous permettra de configurer notre serveur de supervision préféré Centreon. Ce tutoriel s'enrichira au fur et à mesure de mes travaux sur ce sujet.
1 Préparation d'Arduino IDE pour l'ESP 8266
Nous devons préparer le logiciel Arduino IDE pour programmer notre ESP 8266. Tout d'abord, installons la bibliothèque pour l'ESP. Sélectionnez Fichier -> Préférences :
![Stacks Image 37220](files/stacks-image-2bd9980-800x534.png)
Saisissez la ligne suivante :
http://arduino.esp8266.com/stable/package_esp8266com_index.json
Ensuite, sélectionnez Outils -> Type de Carte… -> Gestionnaire de carte. Dans le filtre de recherche, saisissez esp
![Stacks Image 37368](files/stacks-image-643263a-800x450.png)
Cliquez sur Installer. Ensuite, il faut installer la librairie pour la sonde de température. Dans le filtre de recherche, saisissez dht.
![Stacks Image 37371](files/stacks-image-8d2f989-800x448.png)
Installer les librairies DHT sensor Library et DHT sensor library for ESPx. Les librairies sont installées, vérifiez la connectivité de votre ESP. Assurez-vous d'avoir le bon câble pour envoyer et recevoir les données. De nombreux câbles d'alimentation de portables, par exemple, n'ont pas les liaisons de données. Lorsque vous branchez l'ESP, vous devriez avoir une nouvelle connexion USB dans le menu Outils -> Port comme la copie d'écran ci-contre.
![Stacks Image 37374](files/stacks-image-899475e.png)
Avec une machine sous Linux, nous aurons la connexion /dev/ttyUSB0. Nous finirons par la bibliothèque SNMP, il faut télécharger le fichier ZIP sur le GitHub https://github.com/0neblock/Arduino_SNMP. Il en existe bien d'autres, regardez le chapitre Mes sources. Une fois le fichier téléchargé, sélectionnez le menu Croquis -> Inclure une bibliothèque -> Ajouter la bibliothèque ZIP... Sélectionnez le fichier téléchargé Arduino_SNMP-master.zip et validez pour l'inclure pour vos projets.
1.1 Modification pour Linux
Si vous avez la chance de travailler sous Linux, il faut modifier le fichier Arduino_SNMP.h. En effet, Linux comme tout système Unix like est sensible à la casse des caractères. Il faut modifier la ligne suivante :
#include <UDP.h>
par
#include <Udp.h>
![Stacks Image 37381](files/stacks-image-c14461a-800x638.png)
2 Montage de la sonde de température
La sonde AM2302 est très facile à installer. Aucune résistance est requise, il se branche directement sur l'ESP. La sonde fonctionne en 5 Volts, nous utiliserons pour l'instant l'alimentation du connecteur USB de l'ESP. Le fil de données sera connecté au port D4.
![Stacks Image 37390](files/stacks-image-3048247-800x582.jpg)
![Stacks Image 37393](files/stacks-image-c194049.jpg)
3 Programmation de l'ESP
3.1 Fonctionnement de la sonde de température
Premier programme très simple permettant de vérifier le fonctionnement de la sonde de température avec le moniteur série.
#include "DHT.h"
#define DHTPIN 2 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
// Initialize DHT sensor.
DHT dht(DHTPIN, DHTTYPE);
float Temperature;
float Humidity;
void setup() {
Serial.begin(115200);
delay (100);
pinMode(DHTPIN, INPUT);
dht.begin();
}
void loop() {
server.handleClient();
// Wait a few seconds between measurements.
delay(2000);
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f = dht.readTemperature(true);
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
// Compute heat index in Fahrenheit (the default)
float hif = dht.computeHeatIndex(f, h);
// Compute heat index in Celsius (isFahreheit = false)
float hic = dht.computeHeatIndex(t, h, false);
Serial.print(F("Humidity: "));
Serial.print(h);
Serial.print(F("% Temperature: "));
Serial.print(t);
Serial.print(F(" C "));
Serial.print(f);
Serial.print(F(" F Heat index: "));
Serial.print(hic);
Serial.print(F(" C "));
Serial.print(hif);
Serial.println(F(" F"));
}
void handle_OnConnect() {
Temperature = dht.readTemperature(); // Gets the values of the temperature
Humidity = dht.readHumidity(); // Gets the values of the humidity
server.send(200, "text/html", SendHTML(Temperature,Humidity));
}
![Stacks Image 37437](files/stacks-image-71e6d14-800x268.png)
Attention lors des chargements de code, j'ai remarqué que la sonde de température ne fonctionnait qu'après un redémarrage électrique du montage.
3.2 Création d'un mini-serveur Web
Avec ce code, nous allons ajouter un mini-serveur Web qui nous affichera l'hygrométrie et la température de la sonde AM2302.
#include "DHT.h"
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#define DHTPIN 2 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
// Initialize DHT sensor.
DHT dht(DHTPIN, DHTTYPE);
/*Put your SSID & Password*/
const char* ssid = "ssid wifi"; // Enter SSID here
const char* password = "mdp wifi"; //Enter Password here
ESP8266WebServer server(80);
float Temperature;
float Humidity;
void setup() {
Serial.begin(115200);
delay (100);
pinMode(DHTPIN, INPUT);
dht.begin();
Serial.println("Connecting to ");
Serial.println(ssid);
//connect to your local wi-fi network
WiFi.begin(ssid, password);
//check wi-fi is connected to wi-fi network
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected..!");
Serial.print("Got IP: "); Serial.println(WiFi.localIP());
server.on("/", handle_OnConnect);
server.onNotFound(handle_NotFound);
server.begin();
Serial.println("HTTP server started");
}
void loop() {
server.handleClient();
// Wait a few seconds between measurements.
delay(2000);
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f = dht.readTemperature(true);
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
// Compute heat index in Fahrenheit (the default)
float hif = dht.computeHeatIndex(f, h);
// Compute heat index in Celsius (isFahreheit = false)
float hic = dht.computeHeatIndex(t, h, false);
Serial.print(F("Humidity: "));
Serial.print(h);
Serial.print(F("% Temperature: "));
Serial.print(t);
Serial.print(F(" C "));
Serial.print(f);
Serial.print(F(" F Heat index: "));
Serial.print(hic);
Serial.print(F(" C "));
Serial.print(hif);
Serial.println(F(" F"));
}
void handle_OnConnect() {
Temperature = dht.readTemperature(); // Gets the values of the temperature
Humidity = dht.readHumidity(); // Gets the values of the humidity
server.send(200, "text/html", SendHTML(Temperature,Humidity));
}
void handle_NotFound(){
server.send(404, "text/plain", "Not found");
}
String SendHTML(float Temperaturestat,float Humiditystat){
String ptr = "<!DOCTYPE html> <html>\n";
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<title>ESP8266 Weather Report</title>\n";
ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n";
ptr +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
ptr +="<div id=\"webpage\">\n";
ptr +="<h1>ESP8266 NodeMCU Weather Report</h1>\n";
ptr +="<p>Température: ";
ptr +=Temperaturestat;
ptr +=" ºC</p>";
ptr +="<p>Hygrométrie: ";
ptr +=Humiditystat;
ptr +=" %</p>";
ptr +="</div>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
L'affichage de la sonde via un navigateur
![Stacks Image 37442](files/stacks-image-1e3be43-800x244.png)
3.3 Utilisation du SNMP
Troisième modification du code, l'ajout de la fonctionnalité SNMP, très basique. Il y a seulement trois OID pour l'hygrométrie, la température en degré Celsius et Fahrenheit.
#include "DHT.h"
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <WiFiUdp.h>
#include <Arduino_SNMP.h>
#define DHTPIN 2 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
// Initialize DHT sensor.
DHT dht(DHTPIN, DHTTYPE);
/*Put your SSID & Password*/
const char* ssid = "Livebox-FA0A"; // Enter SSID here
const char* password = "DuGeerbq2yNGLHFNGs"; //Enter Password here
ESP8266WebServer server(80);
WiFiUDP udp;
SNMPAgent snmp = SNMPAgent("public"); // Starts an SMMPAgent instance with the community string 'public'
int TempSNMPC = 0;
int TempSNMPF = 0;
int TempHumidity = 0;
int settableNumber = 0;
float Temperature;
float Humidity;
void setup() {
Serial.begin(115200);
delay (100);
pinMode(DHTPIN, INPUT);
dht.begin();
Serial.println("Connecting to ");
Serial.println(ssid);
//connect to your local wi-fi network
WiFi.begin(ssid, password);
//check wi-fi is connected to wi-fi network
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected..!");
Serial.print("Got IP: "); Serial.println(WiFi.localIP());
server.on("/", handle_OnConnect);
server.onNotFound(handle_NotFound);
server.begin();
Serial.println("HTTP server started");
// give snmp a pointer to the UDP object
snmp.setUDP(&udp);
snmp.begin();
// add 'callback' for an OID - Temperature Celsius
snmp.addIntegerHandler(".1.3.6.1.3.2106.5.1.0", &TempSNMPC);
// add 'callback' for an OID - Temperature Farenheit
snmp.addIntegerHandler(".1.3.6.1.3.2106.5.1.1", &TempSNMPF);
// add 'callback' for an OID - Humidity
snmp.addIntegerHandler(".1.3.6.1.3.2106.5.1.2", &TempHumidity);
// you can accept SET commands with a pointer to an integer (or string)
snmp.addIntegerHandler(".1.3.6.1.3.2106.5.1.3", &settableNumber, true);
}
void loop() {
snmp.loop(); // must be called as often as possible
if(snmp.setOccurred){
Serial.printf("Number has been set to value: %i", settableNumber);
snmp.resetSetOccurred();
}
server.handleClient();
// Wait a few seconds between measurements.
delay(2000);
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f = dht.readTemperature(true);
TempSNMPC = int(t * 100) ;
TempSNMPF = int(f * 100) ;
TempHumidity = int(h * 100) ;
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}
// Compute heat index in Fahrenheit (the default)
float hif = dht.computeHeatIndex(f, h);
// Compute heat index in Celsius (isFahreheit = false)
float hic = dht.computeHeatIndex(t, h, false);
Serial.print(F("Humidity: "));
Serial.print(h);
Serial.print(F("% Temperature: "));
Serial.print(t);
Serial.print(F(" C "));
Serial.print(f);
Serial.print(F(" F Heat index: "));
Serial.print(hic);
Serial.print(F(" C "));
Serial.print(hif);
Serial.println(F(" F"));
}
void handle_OnConnect() {
Temperature = dht.readTemperature(); // Gets the values of the temperature
Humidity = dht.readHumidity(); // Gets the values of the humidity
server.send(200, "text/html", SendHTML(Temperature,Humidity));
}
void handle_NotFound(){
server.send(404, "text/plain", "Not found");
}
String SendHTML(float Temperaturestat,float Humiditystat){
String ptr = "<!DOCTYPE html> <html>\n";
ptr +="<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n";
ptr +="<title>ESP8266 Weather Report</title>\n";
ptr +="<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}\n";
ptr +="body{margin-top: 50px;} h1 {color: #444444;margin: 50px auto 30px;}\n";
ptr +="p {font-size: 24px;color: #444444;margin-bottom: 10px;}\n";
ptr +="</style>\n";
ptr +="</head>\n";
ptr +="<body>\n";
ptr +="<div id=\"webpage\">\n";
ptr +="<h1>ESP8266 NodeMCU Weather Report</h1>\n";
ptr +="<p>Température: ";
ptr +=Temperaturestat;
ptr +=" ºC</p>";
ptr +="<p>Hygrométrie: ";
ptr +=Humiditystat;
ptr +=" %</p>";
ptr +="</div>\n";
ptr +="</body>\n";
ptr +="</html>\n";
return ptr;
}
Nous pouvons récupérer les informations SNMP comme ceci :
température en Celsius
température en Fahrenheit
hygrométrie
[root@centreon2004pp ~]# snmpwalk -c public -v1 192.168.1.16 .1.3.6.1.3.2106.5.1.0
SNMPv2-SMI::experimental.2106.5.1.0 = INTEGER: 2360
température en Fahrenheit
[root@centreon2004pp ~]# snmpwalk -c public -v1 192.168.1.16 .1.3.6.1.3.2106.5.1.1
SNMPv2-SMI::experimental.2106.5.1.1 = INTEGER: 7448
hygrométrie
[root@centreon2004pp ~]# snmpwalk -c public -v1 192.168.1.16 .1.3.6.1.3.2106.5.1.2
SNMPv2-SMI::experimental.2106.5.1.2 = INTEGER: 6270
Comme vous le constatez les valeurs sont des integer, il faudra diviser par 100 pour avoir les bonnes valeurs. Heureusement, le plugin Centreon a prévu ce cas.
4 Intégration dans Centreon
Nous utiliserons la version open-source sans plugin-pack. Pour plus d'explication de la sonde Centreon, voir l'article lm-sensors.
4.1 Création de la commande
La commande utilisera le plugin centreon_generic_snmp.pl
![Stacks Image 37298](files/stacks-image-e6f8f56-800x310.jpg)
La commande est la suivante
$CENTREONPLUGINS$/centreon_generic_snmp.pl --plugin=apps::protocols::snmp::plugin --mode=numeric-value --hostname=$HOSTADDRESS$ --snmp-community='$_HOSTSNMPCOMMUNITY$' --snmp-version=$_HOSTSNMPVERSION$ --oid='$_SERVICEOID$' --format-custom='$_SERVICEFORMATCUSTOM$' --format='$_SERVICEFORMAT$' --perfdata-name='$_SERVICEPRFDATANAME$' --warning=$_SERVICEWARNING$ --critical=$_SERVICECRITICAL$ $_SERVICEOPTIONS$
4.2 Création du template de service
La création du template de service stpl-sonde-esp8266-temp-hygro ne présente aucune difficulté.
![Stacks Image 37303](files/stacks-image-ed286eb-800x508.jpg)
Nous rajouterons dans la macro OPTIONS, cette chaîne de caractères permettant de récupérer les valeurs hygrométriques et de température en degré celsius.
--config-json='[ { "oid": "1.3.6.1.3.2106.5.1.0","perfdata_name": "temp", "format": "temperature sonde : %s","format_custom": "/ 100","warning": "30","critical": "35"},{ "oid": "1.3.6.1.3.2106.5.1.2", "perfdata_name": "hygro","format": "hygrometrie sonde : %s","format_custom": "/ 100","warning": "65","critical": "70"} ]'
4.3 Création du Template d'hôte
Création du template d'hôte htpl-sonde_esp8266, nous associerons le template de service stpl-sonde-esp8266-temp-hygro
![Stacks Image 37414](files/stacks-image-d3afadc-800x308.jpg)
La relation
![Stacks Image 37419](files/stacks-image-1a7a27e-800x260.jpg)
4.4 Création du service
Nous avons besoin de l'adresse IP de notre sonde ESP 8266. Appliquons le modèle précédent htpl-sonde_esp8266. Les services seront automatiquement créés.
![Stacks Image 37308](files/stacks-image-03b2331-800x380.jpg)
Appliquez la configuration.
4.5 Vérification de la supervision.
Voici le résultat de la vérification par les sondes Centreon au bout de quelques minutes.
![Stacks Image 37424](files/stacks-image-b5b5538-800x290.jpg)
Et le graphe correspondant à la sonde de température.
![Stacks Image 37313](files/stacks-image-625b537-800x290.jpg)
5 Mes sources
- Le site incontournable de François Mocq : https://www.framboise314.fr/piloter-un-esp8266-via-une-page-web/
- Super site en Français sur l’ESP : https://michel.re/esp8266/
- Agent SNMP pour Arduino : https://github.com/0neblock/Arduino_SNMP
- Autre agent SNMP pour Arduino : https://github.com/CrientClash/Arduino-Snmp-Agent
- Exemple de montage snmp avec un ESP : https://www.instructables.com/id/Data-Center-Monitoring-by-IOT-ESP32/
- Utilisation du SNMP avec un arduino : https://www.engineersgarage.com/arduino/snmp-over-arduino-ethernet-shield/
Cet article n'est terminé, il va s'enrichir au fur et à mesure de mes travaux. bonne lecture.