Skip to content

Commit

Permalink
[ESP32] Add sntp support to get real time on esp32
Browse files Browse the repository at this point in the history
  • Loading branch information
jadhavrohit924 committed Feb 13, 2024
1 parent f216481 commit 959cc8e
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 4 deletions.
20 changes: 20 additions & 0 deletions config/esp32/components/chip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,26 @@ menu "CHIP Core"
Opens the commissioning window automatically at application boot time if
the node is not yet commissioned.

config ENABLE_SNTP_TIME_SYNC
bool "Enable sntp time synchronization"
default n
help
Enable this option to enable sntp time synchronization for example

config SNTP_SERVER_NAME
string "Name of the SNTP server"
depends on ENABLE_SNTP_TIME_SYNC
default "pool.ntp.org"
help
The name of the sntp server.

config SNTP_SYNC_INTERVAL_DAY
int "SNTP sync interval time in day"
depends on ENABLE_SNTP_TIME_SYNC
default 1
help
The interval between syncing device type with sntp server.

endmenu # "System Options"

menu "Security Options"
Expand Down
7 changes: 7 additions & 0 deletions examples/energy-management-app/esp32/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
#include <common/CHIPDeviceManager.h>
#include <common/Esp32AppServer.h>
#include <common/Esp32ThreadInit.h>
#if CONFIG_ENABLE_SNTP_TIME_SYNC
#include <common/TimeSync.h>
#endif
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
#include "spi_flash_mmap.h"
#else
Expand Down Expand Up @@ -146,6 +149,10 @@ static void InitServer(intptr_t context)

// Application code should always be initialised after the initialisation of server.
ApplicationInit();

#if CONFIG_ENABLE_SNTP_TIME_SYNC
Esp32Time::TimeSycnInit();
#endif
}

extern "C" void app_main()
Expand Down
3 changes: 3 additions & 0 deletions examples/energy-management-app/esp32/sdkconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,6 @@ CONFIG_DISABLE_READ_CLIENT=y

# Increase LwIP IPv6 address number
CONFIG_LWIP_IPV6_NUM_ADDRESSES=6

# Enable sntp time sync
CONFIG_ENABLE_SNTP_TIME_SYNC=y
99 changes: 99 additions & 0 deletions examples/platform/esp32/common/TimeSync.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
*
* Copyright (c) 2024 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <esp_err.h>
#include <esp_log.h>

#if CONFIG_ENABLE_SNTP_TIME_SYNC
#include <esp_sntp.h>

static const char * TAG = "ESP_TIME_SYNC";

#define REF_TIME 1546300800 /* 01-Jan-2019 00:00:00 */
/* Timer interval once every day (24 Hours) */
#define TIME_PERIOD (CONFIG_SNTP_SYNC_INTERVAL_DAY * 86400000ULL)

namespace Esp32Time {

esp_err_t GetLocalTimeString(char * buf, size_t buf_len)
{
struct tm timeinfo;
char strftime_buf[64];
time_t now;
time(&now);
localtime_r(&now, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%c %z[%Z]", &timeinfo);
size_t print_size = snprintf(buf, buf_len, "%s, DST: %s", strftime_buf, timeinfo.tm_isdst ? "Yes" : "No");
if (print_size >= buf_len)
{
ESP_LOGE(TAG, "Buffer size %d insufficient for localtime string. Required size: %d", buf_len, print_size);
return ESP_ERR_INVALID_ARG;
}
return ESP_OK;
}

bool ValidateTime(void)
{
time_t now;
time(&now);
if (now > REF_TIME)
{
return true;
}
return false;
}
static esp_err_t PrintCurrentTime(void)
{
char local_time[64];
if (GetLocalTimeString(local_time, sizeof(local_time)) == ESP_OK)
{
if (ValidateTime() == false)
{
ESP_LOGI(TAG, "Time not synchronised yet.");
}
ESP_LOGI(TAG, "The current time is: %s.", local_time);
return ESP_OK;
}
return ESP_FAIL;
}

static void TimeSyncCallback(struct timeval * tv)
{
ESP_LOGI(TAG, "SNTP Synchronised.");
PrintCurrentTime();
}

esp_err_t TimeSycnInit(void)
{
if (esp_sntp_enabled())
{
ESP_LOGI(TAG, "SNTP already initialized.");
return ESP_OK;
}
char * sntp_server_name = CONFIG_SNTP_SERVER_NAME;
ESP_LOGI(TAG, "Initializing SNTP. Using the SNTP server: %s", sntp_server_name);
esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
esp_sntp_setservername(0, sntp_server_name);
esp_sntp_set_sync_interval(TIME_PERIOD);
esp_sntp_init();
sntp_set_time_sync_notification_cb(TimeSyncCallback);
return ESP_OK;
}

} // namespace Esp32Time
#endif
29 changes: 29 additions & 0 deletions examples/platform/esp32/common/TimeSync.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
*
* Copyright (c) 2024 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once
#if CONFIG_ENABLE_SNTP_TIME_SYNC
#include <esp_err.h>
#include <esp_sntp.h>

namespace Esp32Time {

esp_err_t TimeSycnInit(void);

} // namespace Esp32Time
#endif
7 changes: 3 additions & 4 deletions src/platform/ESP32/SystemTimeSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,7 @@ Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void)

CHIP_ERROR ClockImpl::GetClock_RealTime(Microseconds64 & aCurTime)
{
// TODO(19081): This platform does not properly error out if wall clock has
// not been set. For now, short circuit this.
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
#if 0
#if CONFIG_ENABLE_SNTP_TIME_SYNC
struct timeval tv;
if (gettimeofday(&tv, nullptr) != 0)
{
Expand All @@ -70,6 +67,8 @@ CHIP_ERROR ClockImpl::GetClock_RealTime(Microseconds64 & aCurTime)
static_assert(CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD >= 0, "We might be letting through negative tv_sec values!");
aCurTime = Microseconds64((static_cast<uint64_t>(tv.tv_sec) * UINT64_C(1000000)) + static_cast<uint64_t>(tv.tv_usec));
return CHIP_NO_ERROR;
#else
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
#endif
}

Expand Down

0 comments on commit 959cc8e

Please sign in to comment.