# 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 {};