elrebo-de/esp_time_adjust

1.0.2

Latest
uploaded 3 days ago
Time synchronisation component (with manual adjustment) for ESP-IDF version 5.5.0+ using a C++ class

Readme

# Time Synchronisation Component (with Manual Adjustment)

A simple Time Synchronization (with manual adjustment) as an ESP-IDF component. It runs on any ESP32 processor and is built using the ESP-IDF build system in version 5.5+.

The component is implemented as C++ class `TimeAdjust`.

This component can be used to synchronize system time with an external time provider like a GNSS receiver.

## Connecting the Component and Usage

You need to include ```time_adjust.hpp``` and initialize the class `TimeAdjust`.

In addition you can provide a function ```timeTask``` for a task which checks for synchronization and then reports the time periodically. To enable this, you have to create the timeTask.

To synchronize the time the method `adjustTime` must be called with the current UTC date and time.

```
/*
 * Example program to use time_adjust functionality with elrebo-de/esp_time_adjust
 */

#include <string>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"

#include "time_adjust.hpp"

static const char *tag = "time adjust test";

static void timeTask(void *pc){
    TimeAdjust* timeAdjust = &TimeAdjust::getInstance();

    // wait until time is synchronized
    while(!timeAdjust->isSynchronized()) {
        timeAdjust->obtainTime();
    };

    // Print calendar every sync interval
    while (1)
    {
        timeAdjust->printCalendar();
        vTaskDelay(pdMS_TO_TICKS(timeAdjust->getSyncIntervalMs()));
    }
}

extern "C" void app_main(void)
{
    // short delay to reconnect logging
    vTaskDelay(pdMS_TO_TICKS(500)); // delay 0.5 seconds

    ESP_LOGI(tag, "Example Program");

    /* Initialize TimeAdjust class */
    ESP_LOGI(tag, "TimeAdjust");
    TimeAdjust* timeAdjust = &timeAdjust->getInstance();
    // set timezone for Germany (CET/CEST incl. rules for switching)
    // "CET-1CEST,M3.5.0,M10.5.0" means:
    // - Normal time is CET (UTC+1)
    // - Daylight saving time is CEST (UTC+2)
    // - switch to CEST: March (3), last sunday (.5.0)
    // - switch to CET: October (10), last sunday (.5.0)
    timeAdjust->setTimezone(std::string("CET-1CEST,M3.5.0,M10.5.0"));
    timeAdjust->setSyncIntervalMs(30000); // syncIntervalMs set to 30 sec, default for normal operation is 5 mins

    ESP_LOGI(tag, "Create TimeTask");
    xTaskCreate(timeTask, "timeTask", 4096, NULL, 5, NULL);

    vTaskDelay(pdMS_TO_TICKS(60000)); // delay 60 seconds
    ESP_LOGI(tag, "AdjustTime 13:01");
    std::string currentTime = timeAdjust->adjustTime(std::string("17.10.26"), std::string("13:01:00"));

    vTaskDelay(pdMS_TO_TICKS(20000)); // delay 20 seconds
    ESP_LOGI(tag, "AdjustTime 15:01");
    currentTime = timeAdjust->adjustTime(std::string("17.10.26"), std::string("15:01:00"));

    vTaskDelay(pdMS_TO_TICKS(20000)); // delay 20 seconds
    ESP_LOGI(tag, "SetTimezone UTC");
    timeAdjust->setTimezone(std::string("UTC"));

    vTaskDelay(pdMS_TO_TICKS(20000)); // delay 20 seconds
}
```

## API
The API of the component is located in the include directory ```include/time_adjust.hpp``` and defines the
C++ class ```TimeAdjust```. 

```TimeAdjust``` is a Singleton class.

With this call you get a pointer to the Singleton instance:

```C++
    TimeAdjust* timeAdjust = &timeAdjust->getInstance();
```
To initialize the class, you use these methods:
* `setTimezone()` to set the timezone. The default is the current value of the environment variable TZ.
* `setSyncIntervalMs()` to set the synchronization interval. The default is 5 minutes. You can use this value through method `getSyncIntervalMs()` in your own code which calls method `adjustTime()` to adjust the system time.
* Method `obtainTime` can be used to wait for synchronization and set the privat flag `timeSynchronized`. This flag can be retrieved by method `isSynchronized()`.

In addition there is a method `printCalendar()` to report the current system time.

### External Effects

* Usage of method `adjustTime()` changes the system time and temporarily resets the environment variable `TZ`.
* Usage of method `setTimezone()` changes the environment variable `TZ`.

```C++
/* class TimeAdjust
   Class to synchronize time with a provided UTC date and time

   The original code is inspired from the GitHub repository https://github.com/sachin42/idfcomponents.git
   from file HTTPClient/main.cpp.

   Source of Singleton class structure - https://stackoverflow.com/a/1008289
   Posted by Loki Astari, modified by community. See post 'Timeline' for change history
   Retrieved 2026-02-01, License - CC BY-SA 4.0
*/

class TimeAdjust
{
    public:
        static TimeAdjust& getInstance();
        void setTimezone(std::string timezone);
        void setSyncIntervalMs(uint32_t syncIntervalMs);

        uint32_t getSyncIntervalMs();
        bool isSynchronized();

        std::string adjustTime(std::string date, std::string time);
        void obtainTime(void);
        void printCalendar();

    private:
        TimeAdjust(); // Constructor
        time_t mySafeTimegm(struct tm*);

        std::string tag = "TimeAdjust";
        uint32_t syncIntervalMs = 300000;
        bool timeSynchronized = false;

        // Global Mutex for Timezone switch (used in mySafeTimegm)
        StaticSemaphore_t mutex_buffer;
        SemaphoreHandle_t tz_mutex;

    public:
        TimeAdjust(TimeAdjust const&) = delete;
        void operator=(TimeAdjust const&) = delete;
};
```

Because the method `adjustTime()` resets the environment variable `TZ` temporarily, it is protected by a global mutex semaphore `tz_mutex`. The same mutex protects method `setTimezone()`.

When using this class you should always use TimeAdjust::setTimezone() to change the environment variable `TZ`.

# License
This component is provided under the Apache-2.0 license.

Links

Supports all targets

Maintainer

  • Christoph Oberle <christoph.oberle@elrebo.de>
To add this component to your project, run:

idf.py add-dependency "elrebo-de/esp_time_adjust^1.0.2"

download archive

Stats

  • Archive size
    Archive size ~ 70.94 KB
  • Downloaded in total
    Downloaded in total 5 times
  • Weekly Downloads Weekly Downloads (All Versions)
  • Downloaded this version
    This version: 1 time

Badge

elrebo-de/esp_time_adjust version: 1.0.2
|