mirror of
https://github.com/esphome/esphome.git
synced 2026-09-27 23:10:21 +00:00
[RX8025T] add RX8025T realtime clock (#13274)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: J. Nick Koston <nick@home-assistant.io> Co-authored-by: J. Nick Koston <nick@koston.org> Co-authored-by: J. Nick Koston <nick+github@koston.org>
This commit is contained in:
co-authored by
pre-commit-ci-lite[bot]
Claude Sonnet 4.6
J. Nick Koston
J. Nick Koston
J. Nick Koston
parent
35607e99a7
commit
f6e97b7ada
@@ -457,6 +457,7 @@ esphome/components/rtl87xx/* @kuba2k2
|
||||
esphome/components/rtttl/* @glmnet @ximex
|
||||
esphome/components/runtime_image/* @clydebarrow @guillempages @kahrendt
|
||||
esphome/components/runtime_stats/* @bdraco
|
||||
esphome/components/rx8025t/* @remcom
|
||||
esphome/components/rx8130/* @beormund
|
||||
esphome/components/safe_mode/* @jsuanet @kbx81 @paulmonigatti
|
||||
esphome/components/scd4x/* @martgras @sjtrny
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
#include "rx8025t.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
// Datasheet:
|
||||
// - https://support.epson.biz/td/api/doc_check.php?dl=app_RX8025T
|
||||
|
||||
namespace esphome::rx8025t {
|
||||
|
||||
static constexpr uint8_t RX8025T_REG_SEC = 0x00;
|
||||
static constexpr uint8_t RX8025T_REG_FLAG = 0x0E;
|
||||
static constexpr uint8_t RX8025T_FLAG_VDET = 0x01;
|
||||
static constexpr uint8_t RX8025T_FLAG_VLF = 0x02;
|
||||
|
||||
static const char *const TAG = "rx8025t";
|
||||
|
||||
constexpr uint8_t bcd2dec(uint8_t val) { return (val >> 4) * 10 + (val & 0x0f); }
|
||||
constexpr uint8_t dec2bcd(uint8_t val) { return ((val / 10) << 4) + (val % 10); }
|
||||
|
||||
void RX8025TComponent::setup() {
|
||||
uint8_t flags;
|
||||
if (!this->read_flags_(&flags)) {
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags & RX8025T_FLAG_VLF) {
|
||||
ESP_LOGW(TAG, "VLF flag is set - Loss of oscillator detected. Time may be invalid.");
|
||||
}
|
||||
}
|
||||
|
||||
void RX8025TComponent::update() { this->read_time(); }
|
||||
|
||||
void RX8025TComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "RX8025T:");
|
||||
LOG_I2C_DEVICE(this);
|
||||
if (this->is_failed()) {
|
||||
ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
|
||||
}
|
||||
time::RealTimeClock::dump_config();
|
||||
}
|
||||
|
||||
bool RX8025TComponent::read_flags_(uint8_t *flags) {
|
||||
if (!this->read_byte(RX8025T_REG_FLAG, flags)) {
|
||||
ESP_LOGE(TAG, "Can't read flag register.");
|
||||
this->status_set_warning(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RX8025TComponent::read_time() {
|
||||
uint8_t flags;
|
||||
if (!this->read_flags_(&flags)) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t date[7];
|
||||
if (!this->read_bytes(RX8025T_REG_SEC, date, sizeof(date))) {
|
||||
ESP_LOGE(TAG, "Can't read I2C data.");
|
||||
this->status_set_warning(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
|
||||
return;
|
||||
}
|
||||
this->status_clear_warning();
|
||||
|
||||
if (flags & RX8025T_FLAG_VLF) {
|
||||
ESP_LOGW(TAG, "VLF flag is set - time data may be invalid, not syncing to system clock.");
|
||||
return;
|
||||
}
|
||||
|
||||
ESPTime rtc_time{
|
||||
.second = bcd2dec(date[0] & 0x7f),
|
||||
.minute = bcd2dec(date[1] & 0x7f),
|
||||
.hour = bcd2dec(date[2] & 0x3f),
|
||||
.day_of_week = static_cast<uint8_t>((date[3] & 0x7f) ? __builtin_ctz(date[3] & 0x7f) + 1 : 1),
|
||||
.day_of_month = bcd2dec(date[4] & 0x3f),
|
||||
.day_of_year = 1,
|
||||
.month = bcd2dec(date[5] & 0x1f),
|
||||
.year = static_cast<uint16_t>(bcd2dec(date[6]) + 2000),
|
||||
.is_dst = false,
|
||||
.timestamp = 0,
|
||||
};
|
||||
rtc_time.recalc_timestamp_utc(false);
|
||||
if (!rtc_time.is_valid(/*check_day_of_week=*/true, /*check_day_of_year=*/false)) {
|
||||
ESP_LOGE(TAG, "Invalid RTC time, not syncing to system clock.");
|
||||
return;
|
||||
}
|
||||
ESP_LOGD(TAG, "Read UTC time: %04d-%02d-%02d %02d:%02d:%02d VDET:%s", rtc_time.year, rtc_time.month,
|
||||
rtc_time.day_of_month, rtc_time.hour, rtc_time.minute, rtc_time.second, ONOFF(flags & RX8025T_FLAG_VDET));
|
||||
this->synchronize_epoch_(rtc_time.timestamp);
|
||||
}
|
||||
|
||||
void RX8025TComponent::write_time() {
|
||||
auto now = this->utcnow();
|
||||
if (!now.is_valid()) {
|
||||
ESP_LOGE(TAG, "Invalid system time, not syncing to RTC.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t buff[7];
|
||||
buff[0] = dec2bcd(now.second);
|
||||
buff[1] = dec2bcd(now.minute);
|
||||
buff[2] = dec2bcd(now.hour);
|
||||
buff[3] = 1 << (now.day_of_week - 1);
|
||||
buff[4] = dec2bcd(now.day_of_month);
|
||||
buff[5] = dec2bcd(now.month);
|
||||
buff[6] = dec2bcd(now.year % 100);
|
||||
if (!this->write_bytes(RX8025T_REG_SEC, buff, sizeof(buff))) {
|
||||
ESP_LOGE(TAG, "Can't write I2C data.");
|
||||
this->status_set_warning(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
|
||||
return;
|
||||
}
|
||||
ESP_LOGD(TAG, "Wrote UTC time: %04d-%02d-%02d %02d:%02d:%02d", now.year, now.month, now.day_of_month, now.hour,
|
||||
now.minute, now.second);
|
||||
|
||||
// Clear VLF and VDET flags via read-modify-write of flag register
|
||||
uint8_t flags;
|
||||
if (!this->read_flags_(&flags)) {
|
||||
return;
|
||||
}
|
||||
flags &= ~(RX8025T_FLAG_VLF | RX8025T_FLAG_VDET);
|
||||
if (!this->write_byte(RX8025T_REG_FLAG, flags)) {
|
||||
this->status_set_warning(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
|
||||
return;
|
||||
}
|
||||
this->status_clear_warning();
|
||||
}
|
||||
|
||||
} // namespace esphome::rx8025t
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/components/i2c/i2c.h"
|
||||
#include "esphome/components/time/real_time_clock.h"
|
||||
|
||||
namespace esphome::rx8025t {
|
||||
|
||||
class RX8025TComponent : public time::RealTimeClock, public i2c::I2CDevice {
|
||||
public:
|
||||
void setup() override;
|
||||
void update() override;
|
||||
void dump_config() override;
|
||||
void read_time();
|
||||
void write_time();
|
||||
|
||||
protected:
|
||||
bool read_flags_(uint8_t *flags);
|
||||
};
|
||||
|
||||
} // namespace esphome::rx8025t
|
||||
@@ -0,0 +1,42 @@
|
||||
from esphome import automation
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import i2c, time
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID
|
||||
from esphome.types import ConfigType
|
||||
|
||||
CODEOWNERS = ["@remcom"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
rx8025t_ns = cg.esphome_ns.namespace("rx8025t")
|
||||
RX8025TComponent = rx8025t_ns.class_(
|
||||
"RX8025TComponent", time.RealTimeClock, i2c.I2CDevice
|
||||
)
|
||||
CONFIG_SCHEMA = time.TIME_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(RX8025TComponent),
|
||||
}
|
||||
).extend(i2c.i2c_device_schema(0x32))
|
||||
|
||||
|
||||
for _name, _call in (
|
||||
("rx8025t.write_time", "write_time()"),
|
||||
("rx8025t.read_time", "read_time()"),
|
||||
):
|
||||
automation.register_apply_action(
|
||||
_name,
|
||||
automation.maybe_simple_id(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(RX8025TComponent),
|
||||
}
|
||||
),
|
||||
automation.ApplyCall(_call),
|
||||
)
|
||||
|
||||
|
||||
async def to_code(config: ConfigType) -> None:
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
|
||||
await cg.register_component(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
await time.register_time(var, config)
|
||||
@@ -0,0 +1,12 @@
|
||||
esphome:
|
||||
on_boot:
|
||||
then:
|
||||
- rx8025t.write_time: rx8025t_time
|
||||
- rx8025t.read_time:
|
||||
id: rx8025t_time
|
||||
|
||||
time:
|
||||
- platform: rx8025t
|
||||
i2c_id: i2c_bus
|
||||
id: rx8025t_time
|
||||
update_interval: never
|
||||
@@ -0,0 +1,4 @@
|
||||
packages:
|
||||
i2c: !include ../../test_build_components/common/i2c/esp32-idf.yaml
|
||||
|
||||
<<: !include common.yaml
|
||||
@@ -0,0 +1,4 @@
|
||||
packages:
|
||||
i2c: !include ../../test_build_components/common/i2c/esp8266-ard.yaml
|
||||
|
||||
<<: !include common.yaml
|
||||
@@ -0,0 +1,4 @@
|
||||
packages:
|
||||
i2c: !include ../../test_build_components/common/i2c/nrf52.yaml
|
||||
|
||||
<<: !include common.yaml
|
||||
@@ -0,0 +1,4 @@
|
||||
packages:
|
||||
i2c: !include ../../test_build_components/common/i2c/rp2040-ard.yaml
|
||||
|
||||
<<: !include common.yaml
|
||||
Reference in New Issue
Block a user