102 lines
3.5 KiB
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 {}; |