ESPHome 2026.5.0b1
Loading...
Searching...
No Matches
sntp_component.cpp
Go to the documentation of this file.
1#include "sntp_component.h"
2#include "esphome/core/log.h"
3
4#ifdef USE_ESP32
5#include "esp_sntp.h"
6#elif USE_ESP8266
7#include "sntp.h"
8#else
9#include "lwip/apps/sntp.h"
10#endif
11
12namespace esphome::sntp {
13
14static const char *const TAG = "sntp";
15
16#if defined(USE_ESP32)
17SNTPComponent *SNTPComponent::instance = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
18#endif
19
21#if defined(USE_ESP32)
22 SNTPComponent::instance = this;
23 if (esp_sntp_enabled()) {
24 esp_sntp_stop();
25 }
26 esp_sntp_setoperatingmode(ESP_SNTP_OPMODE_POLL);
27 size_t i = 0;
28 for (auto &server : this->servers_) {
29 esp_sntp_setservername(i++, server);
30 }
31 esp_sntp_set_sync_interval(this->get_update_interval());
32 esp_sntp_set_time_sync_notification_cb([](struct timeval *tv) {
33 if (SNTPComponent::instance != nullptr) {
34 SNTPComponent::instance->defer([]() { SNTPComponent::instance->time_synced(); });
35 }
36 });
37 esp_sntp_init();
38#else
39 sntp_stop();
40 sntp_setoperatingmode(SNTP_OPMODE_POLL);
41
42 size_t i = 0;
43 for (auto &server : this->servers_) {
44 sntp_setservername(i++, server);
45 }
46
47#if defined(USE_ESP8266)
48 settimeofday_cb([this](bool from_sntp) {
49 if (from_sntp)
50 this->time_synced();
51 });
52#endif
53
54 sntp_init();
55#endif
56}
58 ESP_LOGCONFIG(TAG, "SNTP Time:");
59 size_t i = 0;
60 for (auto &server : this->servers_) {
61 ESP_LOGCONFIG(TAG, " Server %zu: '%s'", i++, server);
62 }
63 RealTimeClock::dump_config();
64}
66#if !defined(USE_ESP32)
67 // Some platforms currently cannot set the sync interval at runtime so we need
68 // to do the re-sync by hand for now.
69 if (sntp_enabled()) {
70 sntp_stop();
71 this->has_time_ = false;
72 sntp_init();
73 }
74#endif
75}
77// The loop is used to infer whether we have valid time on platforms where we
78// cannot tell whether SNTP has succeeded.
79// One limitation of this approach is that we cannot tell if it was the SNTP
80// component that set the time.
81// ESP-IDF and ESP8266 use callbacks from the SNTP task to trigger the
82// `on_time_sync` trigger on successful sync events.
83#if defined(USE_ESP32) || defined(USE_ESP8266)
84 this->disable_loop();
85#endif
86
87 if (this->has_time_)
88 return;
89
90 this->time_synced();
91}
92
94 auto time = this->now();
95 this->has_time_ = time.is_valid();
96 if (!this->has_time_)
97 return;
98
99 ESP_LOGD(TAG, "Synchronized time: %04d-%02d-%02d %02d:%02d:%02d", time.year, time.month, time.day_of_month, time.hour,
100 time.minute, time.second);
101 this->time_sync_callback_.call();
102}
103
104} // namespace esphome::sntp
ESPDEPRECATED("Use const char* overload instead. Removed in 2026.7.0", "2026.1.0") void defer(const std voi defer)(const char *name, std::function< void()> &&f)
Defer a callback to the next loop() call.
Definition component.h:560
void disable_loop()
Disable this component's loop.
virtual uint32_t get_update_interval() const
Get the update interval in ms of this sensor.
The SNTP component allows you to configure local timekeeping via Simple Network Time Protocol.
std::array< const char *, SNTP_SERVER_COUNT > servers_
ESPTime now()
Get the time in the currently defined timezone.
LazyCallbackManager< void()> time_sync_callback_