IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

MQTT et Données Horaires


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    971
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 971
    Par défaut MQTT et Données Horaires
    Bonjour à tous,

    je reviens vers vous car je n'arrive pas à résoudre mon problème de données horaires reçues via une liaison Thingspeak (channel)

    pour mémoire, j'envoie des données de température et d'humidité extérieures via une liaison MQTT
    puis je renvoie ces données sur un afficheur en local (pourquoi ? tout simplement parce qu'il me parait plus facile de stocker ces données sur Thingspeak qu'en local)

    Channel 1 => Thingspeak => Channel 2 => Affichage local

    Si je reçois correctement les valeurs en local sous cette forme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    15:13:46.348 -> -----------------------
    15:13:46.348 -> Message arrivé du topic: channels/2499901/subscribe
    15:13:46.348 -> Message:{"channel_id":2499901,"created_at":"2024-10-19T13:13:42Z","entry_id":49124,"field1":"23.10","field2":"52.60","field3":"94","field4":"25.19","field5":null,"field6":null,"field7":null,"field8":null,"latitude":null,"longitude":null,"elevation":null,"status":null}
    15:13:46.393 -> T° piscine = 25.19
    15:13:46.394 -> PLUS CHAUD
    15:13:46.394 -> T° Exterieur = 23
    15:13:46.394 -> Humidité Exterieure = 52
    15:13:46.394 -> Batterie = 94
    15:13:46.394 -> Mise à jour le  2024-10-19T13:13:42Z <=====================
    15:13:46.394 -> -----------------------
    Vous remarquerez que le champ "Created_at" créé par Thingspeak est lui formaté en heure UTC alors que tout le profil declaré est bien nommé "Europe/Paris"
    si j'effectue un export instantané des données via le fichier json , on remarque que les données sont bien émises sous format local et non UTC

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    99	
    created_at	"2024-10-19T15:13:42+02:00"   <=================
    entry_id	49124
    field1	"23.10"
    field2	"52.60"
    field3	"94"
    field4	"25.19"
    Tout ceci ne sera pas grave , si en plus de cela , l'émission des données ne s'arrêtait pas chaque jour à minuit (?)
    Il semblerait donc que le broker utilisé ici : mqtt3.thingspeak.com modifie la requête "subscribe" sans que je puisse en trouver la raison

    j'ai recherché sur le net toutes les solutions possibles mais je n'ai rien trouvé de concluant

    je sais que m'éloigne un peu du concept Arduino mais comme je n'arrive pas changer l'heure UTC , je me disais qu'il serait peut-être plus simple de "reformater"
    le champ "created_at" en heure locale
    c'est la raison pour laquelle je demande votre aide et vos conseils

    merci mille fois de m'avoir lu
    pascal
    Images attachées Images attachées  

  2. #2
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    13 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13 197
    Billets dans le blog
    47
    Par défaut
    Salut,

    On trouve ce genre de conversions avec des librairies spécialisées et qui tiennent aussi compte de l'heure d'été/hiver :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    #include <Timezone.h>
    #include <time.h>
     
    // Définir le fuseau horaire pour la France (UTC+1, UTC+2 en été)
    TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120}; // Heure d'été
    TimeChangeRule CET = {"CET", Last, Sun, Oct, 3, 60};    // Heure d'hiver
    Timezone France(CEST, CET);
     
    void setup() {
      Serial.begin(115200);
     
      // Exemple de chaîne de caractères contenant l'heure UTC
      char *utcString = "2024-10-19T15:29:37Z";
     
      time_t utc = convertToEpoch(utcString);
      time_t local = France.toLocal(utc);
     
      Serial.print("Heure UTC : ");
      Serial.println(ctime(&utc));
      Serial.print("Heure Locale : ");
      Serial.println(ctime(&local));
    }
     
    void loop() {
     
    }
     
    // Fonction pour convertir une chaîne de caractères en epoch time
    time_t convertToEpoch(const char* utcString) {
      int year, month, day, hour, minute, second;
      sscanf(utcString, "%4d-%2d-%2dT%2d:%2d:%2dZ", &year, &month, &day, &hour, &minute, &second);
     
      tmElements_t tm;
      tm.Year = year - 1970; // Année depuis 1970
      tm.Month = month;
      tm.Day = day;
      tm.Hour = hour;
      tm.Minute = minute;
      tm.Second = second;
     
      return makeTime(tm);
    }
    Heure UTC : Sat Oct 19 15:29:37 2024
    Heure Locale : Sat Oct 19 17:29:37 2024

  3. #3
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    13 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13 197
    Billets dans le blog
    47
    Par défaut
    Citation Envoyé par cobra38 Voir le message
    Tout ceci ne sera pas grave , si en plus de cela , l'émission des données ne s'arrêtait pas chaque jour à minuit (?)
    Voilà qui est étonnant ! Et il se remet à publier plus tard tout seul ? Je pencherais plutôt vers un problème de connexion.
    Peut-être des pistes ici Résoudre les problèmes de publication MQTT

  4. #4
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    971
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 971
    Par défaut
    Salut f-leb

    Merci pour les retours

    Voilà qui est étonnant ! Et il se remet à publier plus tard tout seul ? Je pencherais plutôt vers un problème de connexion.
    non, il se bloque lors de la dernière mise à jour UTC de la journée , çà fait quelques mois je tourne avec le projet et je suis obligé de le relancer chaque jour
    je pense que çà viens du broker mais je ne comprends pas
    Ce qui est étrange c'est que seules les données publiées (publish) sont renvoyées , la localisation pourtant inscrite dans le "channel1" d'origine ne l'est pas ce qui tant à penser qu'il aurait un "formatage"
    par ailleurs j'ai testé ceci
    sous l'application Matlab Analysis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    % Template MATLAB code for reading data from a private channel, analyzing
    % the data and storing the analyzed data in another channel.
     
    % Prior to running this MATLAB code template, assign the channel variables.
    % Set 'readChannelID' to the channel ID of the channel to read from. Since 
    % this is a private channel, also assign the read API Key to the 'readAPIKey'
    % variable. You can find the read API Key on the right side pane of this page.
     
    % To store the analyzed data, you will need to write it to a channel other
    % than the one you are reading data from. Assign this channel ID to the
    % 'writeChannelID' variable. Also assign the write API Key to the
    % 'writeAPIKey' variable below. You can find the write API Key in the right
    % side pane of this page.
     
    % TODO - Replace the [] with channel ID to read data from:
    readChannelID = [2499901];
    % TODO - Enter the Read API Key between the '' below:
    readAPIKey = 'xxxxxxxxxxxxxxx';
     
    % TODO - Replace the [] with channel ID to write data to:
    writeChannelID = [2499901];
    % TODO - Enter the Write API Key between the '' below:
    writeAPIKey = 'xxxxxxxxxxxxxxxx';
     
    %% Read Data %%
    data = thingSpeakRead(readChannelID, 'ReadKey', readAPIKey);
     
     
    %% Analyze Data %%
    % Add code in this section to analyze data and store the result in the
    % 'analyzedData' variable.
    analyzedData = data;
     
    %% Write Data %%
    tStamp = datetime('now')
    thingSpeakWrite(writeChannelID,'Location',[45,5,200],'WriteKey', writeAPIKey);
    la réponse est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    tStamp = 
     
      datetime
     
       19-Oct-2024 18:18:13
    et j'affiche correctement le champ "created_at" sous la forme : 2024-10-19T18:18:13:+2.00
    mais je perds mes données ....

  5. #5
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    13 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13 197
    Billets dans le blog
    47
    Par défaut
    Citation Envoyé par cobra38 Voir le message
    non, il se bloque lors de la dernière mise à jour UTC de la journée , çà fait quelques mois je tourne avec le projet et je suis obligé de le relancer chaque jour
    La dernière mise à jour UTC de la journée ? Je n'ai pas compris

    Je pense quand même qu'il y a moyen dans le code de tester la connexion et de la relancer si elle est coupée.

  6. #6
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    13 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13 197
    Billets dans le blog
    47
    Par défaut
    Je pense aussi à un truc à rajouter dans le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mqttClient.setKeepAlive(60);
    Le client envoie des messages de "maintien en vie" toutes les 15 secondes environ par défaut pour indiquer qu'il est toujours connecté. En augmentant à 60s (voire plus), je me dis que cela réduit la charge sur le broker qui ne se déconnectera plus.

    à voir...

  7. #7
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    971
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 971
    Par défaut
    Citation Envoyé par f-leb Voir le message
    Je pense aussi à un truc à rajouter dans le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mqttClient.setKeepAlive(60);
    Le client envoie des messages de "maintien en vie" toutes les 15 secondes environ par défaut pour indiquer qu'il est toujours connecté. En augmentant à 60s (voire plus), je me dis que cela réduit la charge sur le broker qui ne se déconnectera plus.

    à voir...

    Ok je vais l'essai demain ....

  8. #8
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    971
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 971
    Par défaut
    Citation Envoyé par f-leb Voir le message
    La dernière mise à jour UTC de la journée ? Je n'ai pas compris

    Je pense quand même qu'il y a moyen dans le code de tester la connexion et de la relancer si elle est coupée.

    En fait à partir du champ "created_at" , je détermine la date de mise à jour avec ce code :
    que j'affiche sur l'écran


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
    void mqttCallback(char *topic, byte *payload, unsigned int length) {
     
      Serial.println();
      Serial.println("-----------------------");
     
      Serial.print("Message arrivé du topic: ");
      Serial.println(topic);
      Serial.print("Message:");
      for (int i = 0; i < length; i++) {
        Serial.print((char)payload[i]);
      }
      JsonDocument doc;
      deserializeJson(doc, (unsigned char*)payload);
        Serial.println();
     
      piscine = doc["field4"];
      Serial.print("T° piscine = ");
      Serial.println(piscine);
     
      float temperatureActuelle = piscine ;
      if (temperatureActuelle > temperaturePrecedente ) {
          // on chauffe
          eteindre();
          digitalWrite(CYD_LED_RED, LOW);
          Serial.println("PLUS CHAUD");
      } else if (temperatureActuelle == temperaturePrecedente ) {
          // on est stable
          eteindre();
          digitalWrite(CYD_LED_GREEN, LOW);
          Serial.println("IDENTIQUE");
      } else {
          // on est plus froid
          eteindre();
          digitalWrite(CYD_LED_BLUE, LOW);
          Serial.println("PLUS FROID");
      }
      temperaturePrecedente = temperatureActuelle;
      //  stocker temperatureActuelle dans les préférences pour la prochaine fois si reboot
      prefs.putFloat(clef, temperatureActuelle); 
     
      TempExt = doc["field1"];
      Serial.print("T° Exterieur = ");
      Serial.println(TempExt,0);
     
      HumExt = doc["field2"];
      Serial.print("Humidité Exterieure = ");
      Serial.println(HumExt,0);
     
      Bat = doc["field3"];
      Serial.print("Batterie = ");
      Serial.println(Bat,0);
     
      const char* (maj) = doc["created_at"];
      //const char* (maj) = doc["updated_at"];
      Serial.print("Mise à jour le  ");
      Serial.println(maj);
      //strcpy(Miseajour, maj);
      strncpy(Miseajour, maj, sizeof(Miseajour));
      Miseajour[sizeof(Miseajour)-1]=0;
      Serial.println("-----------------------");
    ainsi tous les jours je constate la dernière date de mise à jour soit un peu avant 23h59 et les valeurs restent figées
    mais sur ThingSpeak , le channel1 continue à recevoir les données durant toute la nuit (?)

    Edit : j'ai aussi passé le module local en IP statique à voir ...

  9. #9
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 912
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 912
    Par défaut
    sur ESP32 j'utilise un code avec les callback du système pour suivre l'état de la connexion

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #include <WiFi.h>
     
    const char *wifiSSID = "*******";
    const char *wifiPassword = "******";
    bool wifiConnected = false;
     
    void onWiFiConnected(WiFiEvent_t event, WiFiEventInfo_t info) {
      Serial.println("...Network connection established");
    }
     
    void onWiFiGotIP(WiFiEvent_t event, WiFiEventInfo_t info) {
      Serial.print("Obtained IP address = ");
      Serial.println(WiFi.localIP());
      wifiConnected = true;
    }
     
    void onWiFiDisconnected(WiFiEvent_t event, WiFiEventInfo_t info) {
      wifiConnected = false;
      Serial.print("Network disconnected (reason: ");
      Serial.println(info.wifi_sta_disconnected.reason);
      Serial.println(")\nAttempting to reconnect.");
      WiFi.begin(wifiSSID, wifiPassword);
    }
     
    void setup() {
      Serial.begin(115200);
      Serial.println("Connecting to WiFi network");
      WiFi.onEvent(onWiFiConnected, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_CONNECTED);
      WiFi.onEvent(onWiFiGotIP, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_GOT_IP);
      WiFi.onEvent(onWiFiDisconnected, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED);
      WiFi.begin(wifiSSID, wifiPassword);
    }
     
    void loop() {
      if (wifiConnected) {
        // code requiring WiFi connection
        // ...
      }
      // code that does not require WiFi
    }

  10. #10
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    971
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 971
    Par défaut
    Bonjour Jay M

    Merci bien pour l’info , je vais essayer

    Juste une question pratique, sur perte Wifi, il vaut mieux faire :

    - ESP.restart();

    ou plus simplement

    - WiFi.begin(ssid, password);

  11. #11
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 912
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 912
    Par défaut
    restart() va redémarrer votre ESP alors que le begin() va essayer de se reconnecter sans perdre tout ce que vous avez en mémoire.. Donc c'est un peu suivant les cas, perso je préfère un begin() pour tenter une nouvelle connexion

  12. #12
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    971
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 971
    Par défaut
    merci Jay M

    c'est noté ..

    pour ce qui est la coupure , c'est bien la Box qui se coupe à heure fixe , pourquoi je ne sais pas (?)
    mais le fait de pouvoir me reconnecter automatiquement minimisera je crois le problème
    ce jour par ex , la connexion a fonctionné toute la journée

    je vais donc clôturer le post

    Un grand merci à tous pour votre aide

    pascal

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VB.NET] Import donnes d'excel : chiffres et lettres
    Par JohnGT dans le forum Windows Forms
    Réponses: 5
    Dernier message: 19/10/2004, 18h53
  2. est il possible de faire un trie sur un paramètre donné
    Par chtiboss dans le forum XSL/XSLT/XPATH
    Réponses: 8
    Dernier message: 17/03/2004, 11h51
  3. CComboBox::setCurSel ne donne rien
    Par jul54 dans le forum MFC
    Réponses: 5
    Dernier message: 11/02/2004, 13h55
  4. TreeView -> ajouter un child à un noeud donné
    Par fake dans le forum Composants VCL
    Réponses: 6
    Dernier message: 26/03/2003, 17h14
  5. connexion base de donné
    Par saidi dans le forum MFC
    Réponses: 3
    Dernier message: 07/08/2002, 22h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo