85 lines
2.5 KiB
C++
85 lines
2.5 KiB
C++
#pragma once
|
|
|
|
#include <bitset>
|
|
#include <cstdlib>
|
|
#include "esphome/core/automation.h"
|
|
#include "esphome/core/component.h"
|
|
#include "esphome/core/helpers.h"
|
|
#include "esphome/core/time.h"
|
|
#ifdef USE_TIME_TIMEZONE
|
|
#include "posix_tz.h"
|
|
#endif
|
|
|
|
namespace esphome::time {
|
|
|
|
/// The RealTimeClock class exposes common timekeeping functions via the device's local real-time clock.
|
|
///
|
|
/// \note
|
|
/// The C library (newlib) available on ESPs only supports TZ strings that specify an offset and DST info;
|
|
/// you cannot specify zone names or paths to zoneinfo files.
|
|
/// \see https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
|
|
class RealTimeClock : public PollingComponent {
|
|
public:
|
|
explicit RealTimeClock();
|
|
|
|
#ifdef USE_TIME_TIMEZONE
|
|
/// Set the time zone from a POSIX TZ string.
|
|
void set_timezone(const char *tz) { this->apply_timezone_(tz); }
|
|
|
|
/// Set the time zone from a character buffer with known length.
|
|
/// The buffer does not need to be null-terminated.
|
|
void set_timezone(const char *tz, size_t len) {
|
|
if (tz == nullptr) {
|
|
this->apply_timezone_(nullptr);
|
|
return;
|
|
}
|
|
// Stack buffer - TZ strings from tzdata are typically short (< 50 chars)
|
|
char buf[128];
|
|
if (len >= sizeof(buf))
|
|
len = sizeof(buf) - 1;
|
|
memcpy(buf, tz, len);
|
|
buf[len] = '\0';
|
|
this->apply_timezone_(buf);
|
|
}
|
|
|
|
/// Set the time zone from a std::string.
|
|
void set_timezone(const std::string &tz) { this->apply_timezone_(tz.c_str()); }
|
|
#endif
|
|
|
|
/// Get the time in the currently defined timezone.
|
|
ESPTime now();
|
|
|
|
/// Get the time without any time zone or DST corrections.
|
|
ESPTime utcnow() { return ESPTime::from_epoch_utc(this->timestamp_now()); }
|
|
|
|
/// Get the current time as the UTC epoch since January 1st 1970.
|
|
time_t timestamp_now() { return ::time(nullptr); }
|
|
|
|
void add_on_time_sync_callback(std::function<void()> &&callback) {
|
|
this->time_sync_callback_.add(std::move(callback));
|
|
};
|
|
|
|
void dump_config() override;
|
|
|
|
protected:
|
|
/// Report a unix epoch as current time.
|
|
void synchronize_epoch_(uint32_t epoch);
|
|
|
|
#ifdef USE_TIME_TIMEZONE
|
|
void apply_timezone_(const char *tz);
|
|
#endif
|
|
|
|
LazyCallbackManager<void()> time_sync_callback_;
|
|
};
|
|
|
|
template<typename... Ts> class TimeHasTimeCondition : public Condition<Ts...> {
|
|
public:
|
|
TimeHasTimeCondition(RealTimeClock *parent) : parent_(parent) {}
|
|
bool check(const Ts &...x) override { return this->parent_->now().is_valid(); }
|
|
|
|
protected:
|
|
RealTimeClock *parent_;
|
|
};
|
|
|
|
} // namespace esphome::time
|