Compare commits

...

2 commits

3 changed files with 121 additions and 6 deletions

View file

@ -116,6 +116,39 @@ bool PCF85063Component::write_timer_interval(uint16_t interval_seconds) {
return this->write_timer_(); return this->write_timer_();
} }
#define PCF85063_READ_REG(reg, len) \
if (!this->read_bytes(reg, &this->pcf85063_.raw[reg], len)) { \
ESP_LOGE(TAG, "Can't read I2C data."); \
return false; \
}
#define PCF85063_WRITE_REG(reg, len) \
if (!this->write_bytes(reg, &this->pcf85063_.raw[reg], len)) { \
ESP_LOGE(TAG, "Can't write I2C data."); \
return false; \
}
bool PCF85063Component::clear_timer_flag() {
PCF85063_READ_REG(0x01, 1);
this->pcf85063_.reg.timer_flag = 0;
PCF85063_WRITE_REG(0x01, 1);
return true;
}
bool PCF85063Component::clear_alarm_flag() {
PCF85063_READ_REG(0x01, 1);
this->pcf85063_.reg.alarm_flag = 0;
PCF85063_WRITE_REG(0x01, 1);
return true;
}
bool PCF85063Component::write_clockout_frequency(uint8_t freq) {
PCF85063_READ_REG(0x01, 1);
this->pcf85063_.reg.clkout_control = freq & 0b111;
PCF85063_WRITE_REG(0x01, 1);
return true;
}
void PCF85063Component::set_timer_interrupt_enable_(bool state) { void PCF85063Component::set_timer_interrupt_enable_(bool state) {
pcf85063_.reg.timer_interrupt_enable = state; pcf85063_.reg.timer_interrupt_enable = state;
} }
@ -125,10 +158,7 @@ void PCF85063Component::set_timer_interrupt_mode_(PCF85063ATimerInterruptMode_t
} }
bool PCF85063Component::write_timer_() { bool PCF85063Component::write_timer_() {
if (!this->write_bytes(0x10, &this->pcf85063_.raw[0x03], 2)) { PCF85063_WRITE_REG(0x10, 2);
ESP_LOGE(TAG, "Can't write I2C data.");
return false;
}
ESP_LOGD(TAG, "Write timer %s %0u CLOCK=%0u IR=%s %0u", ESP_LOGD(TAG, "Write timer %s %0u CLOCK=%0u IR=%s %0u",
ONOFF(pcf85063_.reg.timer_enable), pcf85063_.reg.timer_value, pcf85063_.reg.timer_clock_frequency, ONOFF(pcf85063_.reg.timer_enable), pcf85063_.reg.timer_value, pcf85063_.reg.timer_clock_frequency,
ONOFF(pcf85063_.reg.timer_interrupt_enable), pcf85063_.reg.timer_interrupt_mode); ONOFF(pcf85063_.reg.timer_interrupt_enable), pcf85063_.reg.timer_interrupt_mode);

View file

@ -32,6 +32,9 @@ class PCF85063Component : public time::RealTimeClock, public i2c::I2CDevice {
//bool set_timer_interval_us(uint64_t interval_us); //bool set_timer_interval_us(uint64_t interval_us);
bool write_timer_interval(uint16_t interval); bool write_timer_interval(uint16_t interval);
bool clear_timer_flag();
bool clear_alarm_flag();
bool write_clockout_frequency(uint8_t freq);
void set_timer_interrupt_enable_(bool state); void set_timer_interrupt_enable_(bool state);
void set_timer_interrupt_mode_(PCF85063ATimerInterruptMode_t mode); void set_timer_interrupt_mode_(PCF85063ATimerInterruptMode_t mode);
@ -152,6 +155,24 @@ template<typename... Ts> class StartTimerAction : public Action<Ts...>, public P
} }
}; };
template<typename... Ts> class SetClockoutFrequencyAction : public Action<Ts...>, public Parented<PCF85063Component> {
public:
TEMPLATABLE_VALUE(uint8_t, freq);
void play(Ts... x) override {
this->parent_->write_clockout_frequency(this->freq_.value(x...));
}
};
template<typename... Ts> class ClearTimerFlagAction : public Action<Ts...>, public Parented<PCF85063Component> {
public:
void play(Ts... x) override { this->parent_->clear_timer_flag(); }
};
template<typename... Ts> class ClearAlarmFlagAction : public Action<Ts...>, public Parented<PCF85063Component> {
public:
void play(Ts... x) override { this->parent_->clear_alarm_flag(); }
};
template<typename... Ts> class WriteAction : public Action<Ts...>, public Parented<PCF85063Component> { template<typename... Ts> class WriteAction : public Action<Ts...>, public Parented<PCF85063Component> {
public: public:
void play(Ts... x) override { this->parent_->write_time(); } void play(Ts... x) override { this->parent_->write_time(); }

View file

@ -2,7 +2,7 @@ import esphome.config_validation as cv
import esphome.codegen as cg import esphome.codegen as cg
from esphome import automation from esphome import automation
from esphome.components import i2c, time from esphome.components import i2c, time
from esphome.const import CONF_ID, CONF_INTERVAL from esphome.const import CONF_ID, CONF_INTERVAL, CONF_VALUE
CODEOWNERS = ["@brogon"] CODEOWNERS = ["@brogon"]
@ -14,7 +14,9 @@ PCF85063Component = pcf85063_ns.class_(
WriteAction = pcf85063_ns.class_("WriteAction", automation.Action) WriteAction = pcf85063_ns.class_("WriteAction", automation.Action)
ReadAction = pcf85063_ns.class_("ReadAction", automation.Action) ReadAction = pcf85063_ns.class_("ReadAction", automation.Action)
StartTimerAction = pcf85063_ns.class_("StartTimerAction", automation.Action) StartTimerAction = pcf85063_ns.class_("StartTimerAction", automation.Action)
ClearTimerFlagAction = pcf85063_ns.class_("ClearTimerFlagAction", automation.Action)
ClearAlarmFlagAction = pcf85063_ns.class_("ClearAlarmFlagAction", automation.Action)
SetClockoutFrequencyAction = pcf85063_ns.class_("SetClockoutFrequencyAction", automation.Action)
CONFIG_SCHEMA = time.TIME_SCHEMA.extend( CONFIG_SCHEMA = time.TIME_SCHEMA.extend(
{ {
@ -22,6 +24,7 @@ CONFIG_SCHEMA = time.TIME_SCHEMA.extend(
} }
).extend(i2c.i2c_device_schema(0x51)) ).extend(i2c.i2c_device_schema(0x51))
#####
@automation.register_action( @automation.register_action(
"pcf85063.write_time", "pcf85063.write_time",
@ -37,6 +40,7 @@ async def pcf85063_write_time_to_code(config, action_id, template_arg, args):
await cg.register_parented(var, config[CONF_ID]) await cg.register_parented(var, config[CONF_ID])
return var return var
#####
@automation.register_action( @automation.register_action(
"pcf85063.read_time", "pcf85063.read_time",
@ -52,6 +56,7 @@ async def pcf85063_read_time_to_code(config, action_id, template_arg, args):
await cg.register_parented(var, config[CONF_ID]) await cg.register_parented(var, config[CONF_ID])
return var return var
#####
def validate_timer_seconds(value): def validate_timer_seconds(value):
value: cv.TimePeriodSeconds = cv.positive_time_period_seconds(value) value: cv.TimePeriodSeconds = cv.positive_time_period_seconds(value)
@ -87,6 +92,65 @@ async def pcf85063_start_timer_to_code(config, action_id, template_arg, args):
await cg.register_parented(var, config[CONF_ID]) await cg.register_parented(var, config[CONF_ID])
return var return var
#####
def validate_clockout_frequency(value):
value = cv.int_range(0b000, 0b111)(value)
return value
@automation.register_action(
"pcf85063.clockout_frequency",
SetClockoutFrequencyAction,
cv.Schema(
{
cv.GenerateID(): cv.use_id(PCF85063Component),
cv.Required(CONF_VALUE): cv.templatable(validate_clockout_frequency),
}
),
)
async def pcf85063_clockout_frequency_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
template_ = await cg.templatable(config[CONF_VALUE], args, type(int))
cg.add(var.set_freq(template_))
await cg.register_parented(var, config[CONF_ID])
return var
#####
@automation.register_action(
"pcf85063.clear_timer_flag",
ClearTimerFlagAction,
cv.Schema(
{
cv.GenerateID(): cv.use_id(PCF85063Component),
}
),
)
async def pcf85063_clear_timer_flag_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
#####
@automation.register_action(
"pcf85063.clear_alarm_flag",
ClearAlarmFlagAction,
cv.Schema(
{
cv.GenerateID(): cv.use_id(PCF85063Component),
}
),
)
async def pcf85063_clear_alarm_flag_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
return var
#####
async def to_code(config): async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID]) var = cg.new_Pvariable(config[CONF_ID])