ESPHome 2025.12.0-dev
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 {
13namespace sntp {
14
15static const char *const TAG = "sntp";
16
17#if defined(USE_ESP32)
18SNTPComponent *SNTPComponent::instance = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
19#endif
20
22#if defined(USE_ESP32)
23 SNTPComponent::instance = this;
24 if (esp_sntp_enabled()) {
25 esp_sntp_stop();
26 }
27 esp_sntp_setoperatingmode(ESP_SNTP_OPMODE_POLL);
28 size_t i = 0;
29 for (auto &server : this->servers_) {
30 esp_sntp_setservername(i++, server);
31 }
32 esp_sntp_set_sync_interval(this->get_update_interval());
33 esp_sntp_set_time_sync_notification_cb([](struct timeval *tv) {
34 if (SNTPComponent::instance != nullptr) {
35 SNTPComponent::instance->defer([]() { SNTPComponent::instance->time_synced(); });
36 }
37 });
38 esp_sntp_init();
39#else
40 sntp_stop();
41 sntp_setoperatingmode(SNTP_OPMODE_POLL);
42
43 size_t i = 0;
44 for (auto &server : this->servers_) {
45 sntp_setservername(i++, server);
46 }
47
48#if defined(USE_ESP8266)
49 settimeofday_cb([this](bool from_sntp) {
50 if (from_sntp)
51 this->time_synced();
52 });
53#endif
54
55 sntp_init();
56#endif
57}
59 ESP_LOGCONFIG(TAG, "SNTP Time:");
60 size_t i = 0;
61 for (auto &server : this->servers_) {
62 ESP_LOGCONFIG(TAG, " Server %zu: '%s'", i++, server);
63 }
64 RealTimeClock::dump_config();
65}
67#if !defined(USE_ESP32)
68 // Some platforms currently cannot set the sync interval at runtime so we need
69 // to do the re-sync by hand for now.
70 if (sntp_enabled()) {
71 sntp_stop();
72 this->has_time_ = false;
73 sntp_init();
74 }
75#endif
76}
78// The loop is used to infer whether we have valid time on platforms where we
79// cannot tell whether SNTP has succeeded.
80// One limitation of this approach is that we cannot tell if it was the SNTP
81// component that set the time.
82// ESP-IDF and ESP8266 use callbacks from the SNTP task to trigger the
83// `on_time_sync` trigger on successful sync events.
84#if defined(USE_ESP32) || defined(USE_ESP8266)
85 this->disable_loop();
86#endif
87
88 if (this->has_time_)
89 return;
90
91 this->time_synced();
92}
93
95 auto time = this->now();
96 this->has_time_ = time.is_valid();
97 if (!this->has_time_)
98 return;
99
100 ESP_LOGD(TAG, "Synchronized time: %04d-%02d-%02d %02d:%02d:%02d", time.year, time.month, time.day_of_month, time.hour,
101 time.minute, time.second);
102 this->time_sync_callback_.call();
103}
104
105} // namespace sntp
106} // namespace esphome
void disable_loop()
Disable this component's loop.
void defer(const std::string &name, std::function< void()> &&f)
Defer a callback to the next loop() call.
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_
CallbackManager< void()> time_sync_callback_
ESPTime now()
Get the time in the currently defined timezone.
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7