ESPHome 2025.10.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.c_str());
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.c_str());
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.c_str());
63 }
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 sntp
105} // 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::vector< std::string > 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