Aide : Base de données DHT sur SD + serveur

Me revoila

Voici ma nouvelle "demande"

J'ai donc réussi à faire apparaitre sur une page HTML les données recus par le DHT22 à partir de ce Tuto de base en y apportant quelques modification pour le faire fonctionner avec un DHT22 au lieu d'un BME280

Une capture du résultat obtenue :

Le code à ma sauce : surement avec quelques coquilles ...

// Import required libraries
#ifdef ESP32
  #include <WiFi.h>
  #include <ESPAsyncWebServer.h>
  #include <SPIFFS.h>
#else
  #include <Arduino.h>
  #include <ESP8266WiFi.h>
  #include <Hash.h>
  #include <ESPAsyncTCP.h>
  #include <ESPAsyncWebServer.h>
  #include <FS.h>
#endif
#include <Wire.h>
#include <Adafruit_Sensor.h>


#include "DHT.h"//bibliothéque
#define DHTPIN 2 // connexion de la pin digital du capteur sur la broche n°2
#define DHTTYPE DHT22   // on appelle le capteur dht22 dans la bibliothèque

DHT dht(DHTPIN, DHTTYPE); // I2C

// Replace with your network credentials
const char* ssid = "*******";
const char* password = "*******";

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

String readDHTTemperature() {
  // Read temperature as Celsius (the default)
  float temperature = dht.readTemperature();
  if (isnan(temperature)) {    
    Serial.println("Failed to read from DHT22 sensor!");
    return "";
  }
  else {
    Serial.println(temperature);
    return String(temperature);
  }
}

String readDHTHumidity() {
  float humidity = dht.readHumidity();
  if (isnan(humidity)) {
    Serial.println("Failed to read from DHT22 sensor!");
    return "";
  }
  else {
    Serial.println(humidity);
    return String(humidity);
  }
}

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);
 
  bool status; 

  // Initialize SPIFFS
  if(!SPIFFS.begin()){
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }

  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Connecting to WiFi..");
  }

  // Print ESP32 Local IP Address
  Serial.println(WiFi.localIP());

  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/index.html");
  });
  server.on("/temperature", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readDHTTemperature().c_str());
  });
  server.on("/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/plain", readDHTHumidity().c_str());
  });
 

  // Start server
  server.begin();

dht.begin();

}
 
void loop(){
}

Le code HTML

<!DOCTYPE HTML><html>
<!-- Rui Santos - Complete project details at https://RandomNerdTutorials.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. -->
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://code.highcharts.com/highcharts.js"></script>
  <style>
    body {
      min-width: 310px;
    	max-width: 800px;
    	height: 400px;
      margin: 0 auto;
    }
    h2 {
      font-family: Arial;
      font-size: 2.5rem;
      text-align: center;
    }
  </style>
</head>
<body>
  <h2>ESP Weather Station</h2>
  <div id="chart-temperature" class="container"></div>
  <div id="chart-humidity" class="container"></div>
</body>
<script>
var chartT = new Highcharts.Chart({
  chart:{ renderTo : 'chart-temperature' },
  title: { text: 'DHT22 Temperature' },
  series: [{
    showInLegend: false,
    data: []
  }],
  plotOptions: {
    line: { animation: false,
      dataLabels: { enabled: true }
    },
    series: { color: '#059e8a' }
  },
  xAxis: { type: 'datetime',
    dateTimeLabelFormats: { second: '%H:%M:%S' }
  },
  yAxis: {
    title: { text: 'Temperature (Celsius)' }
    //title: { text: 'Temperature (Fahrenheit)' }
  },
  credits: { enabled: false }
});
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var x = (new Date()).getTime(),
          y = parseFloat(this.responseText);
      //console.log(this.responseText);
      if(chartT.series[0].data.length > 40) {
        chartT.series[0].addPoint([x, y], true, true, true);
      } else {
        chartT.series[0].addPoint([x, y], true, false, true);
      }
    }
  };
  xhttp.open("GET", "/temperature", true);
  xhttp.send();
}, 30000 ) ;

var chartH = new Highcharts.Chart({
  chart:{ renderTo:'chart-humidity' },
  title: { text: 'DHT22 Humidity' },
  series: [{
    showInLegend: false,
    data: []
  }],
  plotOptions: {
    line: { animation: false,
      dataLabels: { enabled: true }
    }
  },
  xAxis: {
    type: 'datetime',
    dateTimeLabelFormats: { second: '%H:%M:%S' }
  },
  yAxis: {
    title: { text: 'Humidity (%)' }
  },
  credits: { enabled: false }
});
setInterval(function ( ) {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var x = (new Date()).getTime(),
          y = parseFloat(this.responseText);
      //console.log(this.responseText);
      if(chartH.series[0].data.length > 40) {
        chartH.series[0].addPoint([x, y], true, true, true);
      } else {
        chartH.series[0].addPoint([x, y], true, false, true);
      }
    }
  };
  xhttp.open("GET", "/humidity", true);
  xhttp.send();
}, 30000 ) ;
</script>
</html>

Je voudrai aller plus loin en ayant aussi un historique des valeurs DHT, en parcourant ce même site il y a aussi un tuto pour enregistrer ces valeurs sur une base de données dans un hebergeur.
Ces hebergeurs sont pour la plus part payant.

Ayant une MicroSD de 32go, je pense que cela doit être possible de faire une base de données dessus, pour que je puisse les recupérer ensuite sur le HTML.
Non ?

Voici donc mes "demandes" :

  • Mon idée est-elle envisageable ?
  • Un coup de main pour un novice pour coder ça ( après si quelqu'un se sent de tout coder je prend aussi :wink: )
  • L'ascquisition des données ce fait toutes les 30 secondes, je voudrai inserrer une ligne me permetant de modifier ce temps

Merci et pardon d'avance si les thermes employés ne sont pas les bons ...

Je pense que cela doit exister mais ce ne doit pas être facile de gérer une base de donnée avec environs 3000 enregistrement par jour.
Surtout si tu veux filtrer les données dans tes dashboard.

Si tu utilise des brokers mqtt, il y en a plusieurs de gratuit, j'en avais testé un, mais je retrouve plus le nom :frowning:

Si tu as un rasberry ou un petit PC allumé en permanence, tu peux y installer une petite base de données.

Merci pour ton retour,
J'y connais pas grand chose, mais j'ai ouvert un compte sur Influxdb pour visualiser mes courbes dessus aussi.
C'est jouable d'enregistrer les données dessus et les récupérer ensuite ? ( attention si la réponse est oui, je vais demander comment :smile: :smile: )

Je me lance peut être dans quelque chose de trop compliqué pour mon niveau ( au risque d'inonder le forum de mes questions )

Bonjour

J'y connais pas grand chose, mais j'ai ouvert un compte sur Influxdb pour visualiser mes courbes dessus aussi.
C'est jouable d'enregistrer les données dessus et les récupérer ensuite ?

Il faut voir les conditions d'utilisation du compte InfluxData créé : volume de données stockées, durée de conservation, modalités de récupération...

Par contre si tu installes InfluxdB sur un petit Raspberry Pi (ou équivalent) tu fais ce que tu veux de tes données !! (InfluxDB est souvent couplé à Grafana pour la présentation des données, ça tourne même sur les premières générations de raspberry Pi)

Merci à toi aussi,

J'ai la version free, visiblement pas d'espace de stockage ... Mais 30 jours de conservation des données.
Je ne compte pas garder mes données du climat indéfiniment, c'est "simplement" pour visualiser l'historique des courbes, par exemple sur 1 semaine.

Avec la pénurie du moment et la hausse des prix ( x3 pour des rasperry parfois ) j'ai pris comme 1er controlleur un Arduino

Je n'ai pas en tête les limitations de la version gratuite de ThingSpeak (horodatage des données reçues , conservation, présentation + qq possibilités de traitement des données avec un Matlab gratuit en ligne

C'est il me semble un solution à examiner si la contrainte de cadence d'envoi des données de la version gratuite est compatible avec l'application.

Je suis plutôt 'touche à tout' en matière de solutions de conservation+présentation de données et revient toujours à ThingSpeak dont pour moi le seul défaut est la grande difficulté à installer localement bien que ce soit OpenSource et en théorie installable

des bouts de code Matlab permettent de faire du calcul et obtenir par exemple des graphes complémentaires qui en découlent : histogrammes, nuages de points....)

Voici les possibilités de la version gratuite de ThingSpeak

J'ai l'impression que je m'embarque dans un truc super compliqué pour un simple projet !!! :sweat_smile:

Moi j'utilise cayenne.mydevices.com, qui permet de visualiser tes métriques sur au moins 1 ans.
Je peux visualiser les données sur leur site WEB ou une application sur mon mobile.
Tu peux aussi définir des alertes.
Tu peux très facilement récupérer les données si tu veux historiser.

Merci je vais y jeter un oeil,
Si tu as un code pour m'aider a comprendre la strucure du programme pour que je puisse le mettre à ma sauce, je veux bien.

Enfin si tu peux et si tu veux surtout :wink:

Oui je peux, mais c'est en Lua :slight_smile:

Ha d'accord, je risque de rien comprendre avec ce language, déja que j'ai du mal à mis retrouver avec le C++ ... :sweat_smile: :sweat_smile: :sweat_smile:
Mais merci quand même

C'est pas que cela soit particulièrement difficile à comprendre, mais qu'il faudra le réécrire en c+.
Le mieux serait que tu trouve un exemple directement en C++

Pour quand même te donner une idée de ce qu'il y a faire.

    m = mqtt.Client(MqttClientID, 120, MqttUsername, MqttPassword)
    m:on("connect", function(con) print ("mqtt connected") end)
    m:on("offline", function(con) print ("mqtt offline") end)

    m:connect(MqttServer, MqttPort, false, function (conn)
        print("mqtt connected")
        m:publish(
            "v1/"..MqttUsername.."/things/"..MqttClientID.."/data/1",
            "temp,c="..temp,
            0, 0,
            function(conn)
                print("mqtt topic temp published", temp)
            end
        )
        m:publish(
            "v1/"..MqttUsername.."/things/"..MqttClientID.."/data/2",
            "rel_hum,p="..humi,
            1, 0,
            function(conn)
                print("mqtt topic humidite published")
            end
        )
        m:publish(
            "v1/"..MqttUsername.."/things/"..MqttClientID.."/data/3",
            "batt,v="..Uread,
            0, 0,
            function(conn)
                print("mqtt topic battery published")
            end
        )
    end)

Yes merci,
Je vais lui trouver un "google trad" :joy:

Merci j'ai reussi !!

Capture d’écran 2022-09-16 151526

Une chose bizarre, ou peut etre normal ?
Dans l'onglet data, chaque data est doublée ...

Pourtant dans le moniteur d'Arduino j'ai bien qu'une seule acquisition à la fois, chez toi aussi ?

Le site Web sur le téléphone est pas très ergonimique, je n'ai pas vu d'application " Cayenne ", tu utilises quelques choses en particulier ou une application que tu créés par toi même ?

Pour l'instant mon capteur n'est plus en fonction, donc je ne pourrais te dire maintenant, mais non ce n'est pas normal.
Tu es sûre de pas faire deux publish?
J'ai changé de téléphone depuis, mais de mémoire c'est une application android, mais ils ont du changer un peu l'apparence, car c'était beaucoup plus simpliste.

J'ai pas l'impression, mon code ;

//#define CAYENNE_DEBUG
#define CAYENNE_PRINT Serial
#include <CayenneMQTTESP32.h>

// WiFi network info.
char ssid[] = "********";
char wifiPassword[] = "*******";

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "**********";
char password[] = "**********";
char clientID[] = "***********";


void setup() {
  Serial.begin(9600);
  Cayenne.begin(username, password, clientID, ssid, wifiPassword);
}

void loop() {
  Cayenne.loop();
}

// Default function for sending sensor data at intervals to Cayenne.
// You can also use functions for specific channels, e.g CAYENNE_OUT(1) for sending channel 1 data.
CAYENNE_OUT_DEFAULT()
{
  // Write data to Cayenne here. This example just sends the current uptime in milliseconds on virtual channel 0.
  Cayenne.virtualWrite(0, millis());
  // Some examples of other functions you can use to send data.
  //Cayenne.celsiusWrite(1, 22.0);
  //Cayenne.luxWrite(2, 700);
  //Cayenne.virtualWrite(3, 50, TYPE_PROXIMITY, UNIT_CENTIMETER);
}

// Default function for processing actuator commands from the Cayenne Dashboard.
// You can also use functions for specific channels, e.g CAYENNE_IN(1) for channel 1 commands.
CAYENNE_IN_DEFAULT()
{
  CAYENNE_LOG("Channel %u, value %s", request.channel, getValue.asString());
  //Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
}

T'embete pas, je vais bien trouver d'où ca vient en bidouillant.

Autant pour moi je n'avais pas vu cette partie du site :pray: :+1:
Bad elle existe plus sur l'apple store francais, va falloir contourner les regles

Ils ont l'air de stoker le datetime à la second, tu es sûre que tu n'envois pas plusieurs fois en une seconde?

Pour l'application, c'est dommage, je l'a trouvais sympa.

Salut ... mon appli android ne répond plus non plus ... tu en as trouvé une autre qui correspond ?

Une application pour récupérer les données d’un capteur ?
Pas vraiment, j’attends désespérément la baisse de prix des raspberry pour utiliser home assistant.

J’ai trouvé une alternative, maintenant que je comprend un peu plus la programmation. Totalement gratuit.

J’envoie toutes mes données sur influxdb que je lie a grafana pour les regarder.
L’ergonomie de influxdb est mauvaise sur un telephone, avec grafana c’est beaucoup mieux.

Astuce pour iPhone avec safari : une fois sur le site grafana avec mes données, j’enregistre le favori sur ma page d’accueil, ça fait comme une application

Merci pour l'info .... l'appli Cayenne est HS depuis 2 ans et toujours rien pour la remplacer. pffff