configs/common/time.yaml

102 lines
3.5 KiB
YAML

# https://community.home-assistant.io/t/display-manually-set-rtc-ds3231-time-in-esphome-sntp-sync-every-12-hours-need-help-with-web-interface/868801
# miloit
time:
- platform: sntp
id: sntp_time
web_server:
port: 80
custom_component:
- lambda: |-
class DS3231Component : public PollingComponent {
public:
DS3231Component(esphome::time::RealTimeClock *rtc) : PollingComponent(10000), rtc_(rtc) {}
void setup() override {
if (!Wire.requestFrom(0x68, 1)) {
ESP_LOGE("DS3231", "RTC not found at I2C address 0x68");
return;
}
ESP_LOGI("DS3231", "RTC found at I2C address 0x68");
auto now = this->rtc_->now();
if (now.is_valid()) {
set_time(now.year, now.month, now.day_of_month, now.hour, now.minute, now.second, now.day_of_week);
ESP_LOGI("DS3231", "RTC time set to %04d-%02d-%02d %02d:%02d:%02d",
now.year, now.month, now.day_of_month, now.hour, now.minute, now.second);
} else {
ESP_LOGE("DS3231", "SNTP time is not valid; cannot set RTC");
}
}
void update() override {
auto time = get_time();
if (time.year > 0) {
ESP_LOGI("DS3231", "Current RTC Time: %04d-%02d-%02d %02d:%02d:%02d",
time.year, time.month, time.day, time.hour, time.minute, time.second);
} else {
ESP_LOGE("DS3231", "Failed to read time from RTC");
}
}
void set_time(int year, int month, int day, int hour, int minute, int second, int day_of_week) {
Wire.beginTransmission(0x68);
Wire.write(0); // Start at register 0
Wire.write(dec_to_bcd(second)); // Seconds
Wire.write(dec_to_bcd(minute)); // Minutes
Wire.write(dec_to_bcd(hour)); // Hours
Wire.write(dec_to_bcd(day_of_week)); // Day of the week
Wire.write(dec_to_bcd(day)); // Day of the month
Wire.write(dec_to_bcd(month)); // Month
Wire.write(dec_to_bcd(year - 2000)); // Year
Wire.endTransmission();
}
struct Time {
int year;
int month;
int day;
int hour;
int minute;
int second;
int day_of_week;
};
Time get_time() {
Wire.beginTransmission(0x68);
Wire.write(0); // Start at register 0
Wire.endTransmission();
if (Wire.requestFrom(0x68, 7) != 7) {
ESP_LOGE("DS3231", "Failed to read time registers");
return Time{0, 0, 0, 0, 0, 0, 0};
}
uint8_t second = bcd_to_dec(Wire.read());
uint8_t minute = bcd_to_dec(Wire.read());
uint8_t hour = bcd_to_dec(Wire.read());
uint8_t day_of_week = bcd_to_dec(Wire.read());
uint8_t day = bcd_to_dec(Wire.read());
uint8_t month = bcd_to_dec(Wire.read());
uint16_t year = bcd_to_dec(Wire.read()) + 2000;
return Time{year, month, day, hour, minute, second, day_of_week};
}
private:
esphome::time::RealTimeClock *rtc_;
uint8_t dec_to_bcd(int val) {
return ((val / 10 * 16) + (val % 10));
}
int bcd_to_dec(uint8_t val) {
return ((val / 16 * 10) + (val % 16));
}
};
auto my_rtc = new DS3231Component(id(sntp_time));
App.register_component(my_rtc);
return {};