Vérifier que le temps d'un serveur NTP a bien été acquis (avec la librairie Time.h)

Bonsoir !

J'ai sur un ESP32 un croquis dans lequel je vais "chercher" le temps unix sur un serveur NTP, pour l'afficher et m'en servir pour calculer les heures de lever et de coucher du soleil, entre autres.

Tout cela fonctionne très bien, à part si au lancement du programme l'acquisition du temps sur le serveur est un peu longue, auquel cas, la date et l'heure n'étant pas encore à jour mon croquis me calcule les heures de lever et de coucher du soleil du 1er janvier 1970, début du temps unix ! (et me les affiche jusqu'à minuit, moment où ces heures sont recalculées pour le jour suivant)

Comme "palliatif" à mon problème je commence mon "loop" comme cela :

void loop()
{
  ArduinoOTA.handle();                               // Surveillance des demandes de mise à jour OTA (au début de loop)

  if (FirstCycleDone == false) delay(4000);          // Attente pour la mise à jour de l'heure NTP au 1er cycle
  
  extract_temps();                                   // Extraction des données de temps à partir de ntpServer

  if (FirstCycleDone == false) ephemerides();        // Lecture des éphémérides au démarrage du programme

La variable FirstCycleDone est passée à "true" à la fin du premier cycle de loop, donc au premier cycle je mets un délais de 4 secondes entre la connexion au WiFi (dans le setup) et le passage à la fonction extract_temps(); ce qui laisse (jusqu'à présent) le temps pour l'acquisition de la date et de l'heure.

J'utilise les fonctions de la librairie time.h pour acquérir le temps, ma fonction extract_temps() ressemble à ça :

void extract_temps()
{
  moment = time(NULL);                              // Mise de la date et heure du moment au format unix dans variable "moment"
  loc = localtime(&moment);                         // Mise dans la structure loc des éléments de date et d'heure
                                                    // corrigés des informations de décalage horaire contenues dans
                                                    // la commande "configTzTime" dans le setup (commande localtime)
}

Ça fonctionne comme ça mais ce n'est pas très "noble" comme solution.
En fait je voudrais que ma fonction "extract_temps()" ne me renvoie quelque chose que lorsque l'ESP a vraiment acquis le temps. Un peu comme lors de la connexion au WiFi où on fait un test
while (WiFi.status() != WL_CONNECTED)

Et j'avoue que là je sèche un peu pour trouver une solution...

Roland

avec quel code ?
cette fonction pourrait maintenir une variable booléenne globale

bool tempsNtpOK = false;

et vous pourriez transformer votre fonction pour qu'elle retourne un bool

bool extract_temps()
{
  if (! tempsNtpOK) return false;

  moment = time(NULL);                              // Mise de la date et heure du moment au format unix dans variable "moment"
  loc = localtime(&moment);                         // Mise dans la structure loc des éléments de date et d'heure
                                                    // corrigés des informations de décalage horaire contenues dans
                                                    // la commande "configTzTime" dans le setup (commande localtime)
  return true;
}

Salut.
Il serait bien de savoir comment tu paramètres NTP dans setup().
Supposons, comme tu as besoin de l'heure locale, comme ceci :

  configTzTime("CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00", ntpServer);

Ensuite pour la synchro :

  sntp_set_time_sync_notification_cb(time_sync_notification);

time_sync_notification étant une fonction callback :

bool timeSync;

void time_sync_notification(struct timeval *tv)
{
  Serial.println("time synchronization event");
  timeSync = True;
}

Dans cette fonction, positionne une variable globale booléenne que tu consultes ensuite dans la loop().

Bonjour !

Pour répondre à JML et hbachetti :

J'utilise les fonctions intégrées à time.h

Au début je définis bien sûr mon serveur par
const char* ntpServer = "pool.ntp.org";

Dans la partie setup j'ai mis cette commande après l'obtention de la connexion WiFi :
configTzTime("CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00", ntpServer);

C'est bien pris en compte l'heure affichée est correcte.

Par contre je n'ai pas mis de ligne dans le genre
sntp_set_time_sync_notification_cb(time_sync_notification);
avec la fonction qu'elle appelle.

Je vais essayer !

Edit :
après essai, à la compilation (avec l'IDE Arduino 1.8.19) cela me met :
'sntp_set_time_sync_notification_cb' was not declared in this scope'

Sachant que jai mis la ligne sntp_set_time_sync_notification_cb(time_sync_notification); dans la partie setup directement après la ligne 'configTzTime...'

Merci à vous deux, Roland

vous avez un #include "esp_sntp.h" au début du code ?

Ah non je ne l'avais pas, et avec c'est déjà bien mieux.
J'ai fait un test sur l'état de timeSync comme dans l'exemple donné par hbachetti, cela fonctionne !

Est-il normal que sans cette bibliothèque l'acquisition de l'heure (faite par la bibliothèque "Time.lib" si j'ai bien compris) fonctionnait quand même ?

Roland

Roland

oui esp_sntp.h rajoute la connaissance d'autres fonctions comme notamment sntp_set_time_sync_notification_cb()

OK merci !
Il faudra un jour que je me penche plus en profondeur dans les entrailles de esp-idf, mais que c'est touffu...

Merci encore à vous et hbachetti !

Roland