mirror of
https://github.com/esphome/esphome.git
synced 2026-09-28 07:20:24 +00:00
[datetime] Use register_apply_action for date.set, time.set and datetime.set (#19513)
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
from collections.abc import Callable
|
||||
|
||||
from esphome import automation
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import mqtt, time, web_server
|
||||
@@ -21,13 +23,13 @@ from esphome.const import (
|
||||
CONF_WEB_SERVER,
|
||||
CONF_YEAR,
|
||||
)
|
||||
from esphome.core import CORE, ID, CoroPriority, coroutine_with_priority
|
||||
from esphome.core import CORE, CoroPriority, coroutine_with_priority
|
||||
from esphome.core.entity_helpers import (
|
||||
entity_duplicate_validator,
|
||||
queue_entity_register,
|
||||
setup_entity,
|
||||
)
|
||||
from esphome.cpp_generator import MockObj, MockObjClass, TemplateArgsType
|
||||
from esphome.cpp_generator import MockObj, MockObjClass
|
||||
from esphome.types import ConfigType, SafeExpType
|
||||
|
||||
CODEOWNERS = ["@rfdarter", "@jesserockz"]
|
||||
@@ -40,11 +42,6 @@ DateEntity = datetime_ns.class_("DateEntity", DateTimeBase)
|
||||
TimeEntity = datetime_ns.class_("TimeEntity", DateTimeBase)
|
||||
DateTimeEntity = datetime_ns.class_("DateTimeEntity", DateTimeBase)
|
||||
|
||||
# Actions
|
||||
DateSetAction = datetime_ns.class_("DateSetAction", automation.Action)
|
||||
TimeSetAction = datetime_ns.class_("TimeSetAction", automation.Action)
|
||||
DateTimeSetAction = datetime_ns.class_("DateTimeSetAction", automation.Action)
|
||||
|
||||
DateTimeStateTrigger = datetime_ns.class_(
|
||||
"DateTimeStateTrigger", automation.Trigger.template(cg.ESPTime)
|
||||
)
|
||||
@@ -181,118 +178,64 @@ async def to_code(config: ConfigType) -> None:
|
||||
cg.add_global(datetime_ns.using)
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"datetime.date.set",
|
||||
DateSetAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(DateEntity),
|
||||
cv.Required(CONF_DATE): cv.Any(
|
||||
cv.returning_lambda, cv.date_time(date=True, time=False)
|
||||
),
|
||||
}
|
||||
),
|
||||
synchronous=True,
|
||||
)
|
||||
async def datetime_date_set_to_code(
|
||||
config: ConfigType,
|
||||
action_id: ID,
|
||||
template_arg: cg.TemplateArguments,
|
||||
args: TemplateArgsType,
|
||||
) -> MockObj:
|
||||
action_var = cg.new_Pvariable(action_id, template_arg)
|
||||
await cg.register_parented(action_var, config[CONF_ID])
|
||||
|
||||
date_config = config[CONF_DATE]
|
||||
if cg.is_template(date_config):
|
||||
template_ = await cg.templatable(date_config, args, cg.ESPTime)
|
||||
cg.add(action_var.set_date(template_))
|
||||
else:
|
||||
date_struct = cg.StructInitializer(
|
||||
cg.ESPTime,
|
||||
("day_of_month", date_config[CONF_DAY]),
|
||||
("month", date_config[CONF_MONTH]),
|
||||
("year", date_config[CONF_YEAR]),
|
||||
def _esptime_initializer(
|
||||
members: tuple[tuple[str, str], ...],
|
||||
) -> Callable[[ConfigType, ConfigType], str]:
|
||||
def const_fn(config: ConfigType, value: ConfigType) -> str:
|
||||
return str(
|
||||
cg.StructInitializer(
|
||||
cg.ESPTime, *((member, value[key]) for member, key in members)
|
||||
)
|
||||
)
|
||||
template_ = await cg.templatable(date_struct, args, cg.ESPTime)
|
||||
cg.add(action_var.set_date(template_))
|
||||
return action_var
|
||||
|
||||
return const_fn
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"datetime.time.set",
|
||||
TimeSetAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(TimeEntity),
|
||||
cv.Required(CONF_TIME): cv.Any(
|
||||
cv.returning_lambda, cv.date_time(date=False, time=True)
|
||||
),
|
||||
}
|
||||
# ESPTime member order, so the designated initializer compiles.
|
||||
_TIME_MEMBERS = (("second", CONF_SECOND), ("minute", CONF_MINUTE), ("hour", CONF_HOUR))
|
||||
_DATE_MEMBERS = (("day_of_month", CONF_DAY), ("month", CONF_MONTH), ("year", CONF_YEAR))
|
||||
|
||||
for _name, _entity, _key, _target, _date, _time, _members in (
|
||||
(
|
||||
"datetime.date.set",
|
||||
DateEntity,
|
||||
CONF_DATE,
|
||||
"set_date",
|
||||
True,
|
||||
False,
|
||||
_DATE_MEMBERS,
|
||||
),
|
||||
synchronous=True,
|
||||
)
|
||||
async def datetime_time_set_to_code(
|
||||
config: ConfigType,
|
||||
action_id: ID,
|
||||
template_arg: cg.TemplateArguments,
|
||||
args: TemplateArgsType,
|
||||
) -> MockObj:
|
||||
action_var = cg.new_Pvariable(action_id, template_arg)
|
||||
await cg.register_parented(action_var, config[CONF_ID])
|
||||
|
||||
time_config = config[CONF_TIME]
|
||||
if cg.is_template(time_config):
|
||||
template_ = await cg.templatable(time_config, args, cg.ESPTime)
|
||||
cg.add(action_var.set_time(template_))
|
||||
else:
|
||||
time_struct = cg.StructInitializer(
|
||||
cg.ESPTime,
|
||||
("second", time_config[CONF_SECOND]),
|
||||
("minute", time_config[CONF_MINUTE]),
|
||||
("hour", time_config[CONF_HOUR]),
|
||||
)
|
||||
template_ = await cg.templatable(time_struct, args, cg.ESPTime)
|
||||
cg.add(action_var.set_time(template_))
|
||||
return action_var
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"datetime.datetime.set",
|
||||
DateTimeSetAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(DateTimeEntity),
|
||||
cv.Required(CONF_DATETIME): cv.Any(
|
||||
cv.returning_lambda, cv.date_time(date=True, time=True)
|
||||
),
|
||||
},
|
||||
(
|
||||
"datetime.time.set",
|
||||
TimeEntity,
|
||||
CONF_TIME,
|
||||
"set_time",
|
||||
False,
|
||||
True,
|
||||
_TIME_MEMBERS,
|
||||
),
|
||||
synchronous=True,
|
||||
)
|
||||
async def datetime_datetime_set_to_code(
|
||||
config: ConfigType,
|
||||
action_id: ID,
|
||||
template_arg: cg.TemplateArguments,
|
||||
args: TemplateArgsType,
|
||||
) -> MockObj:
|
||||
action_var = cg.new_Pvariable(action_id, template_arg)
|
||||
await cg.register_parented(action_var, config[CONF_ID])
|
||||
|
||||
datetime_config = config[CONF_DATETIME]
|
||||
if cg.is_template(datetime_config):
|
||||
template_ = await cg.templatable(datetime_config, args, cg.ESPTime)
|
||||
cg.add(action_var.set_datetime(template_))
|
||||
else:
|
||||
datetime_struct = cg.StructInitializer(
|
||||
cg.ESPTime,
|
||||
("second", datetime_config[CONF_SECOND]),
|
||||
("minute", datetime_config[CONF_MINUTE]),
|
||||
("hour", datetime_config[CONF_HOUR]),
|
||||
("day_of_month", datetime_config[CONF_DAY]),
|
||||
("month", datetime_config[CONF_MONTH]),
|
||||
("year", datetime_config[CONF_YEAR]),
|
||||
)
|
||||
template_ = await cg.templatable(datetime_struct, args, cg.ESPTime)
|
||||
cg.add(action_var.set_datetime(template_))
|
||||
return action_var
|
||||
(
|
||||
"datetime.datetime.set",
|
||||
DateTimeEntity,
|
||||
CONF_DATETIME,
|
||||
"set_datetime",
|
||||
True,
|
||||
True,
|
||||
_TIME_MEMBERS + _DATE_MEMBERS,
|
||||
),
|
||||
):
|
||||
automation.register_apply_action(
|
||||
_name,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(_entity),
|
||||
cv.Required(_key): cv.Any(
|
||||
cv.returning_lambda, cv.date_time(date=_date, time=_time)
|
||||
),
|
||||
}
|
||||
),
|
||||
automation.ApplyField(
|
||||
_key, _target, cg.ESPTime, const_fn=_esptime_initializer(_members)
|
||||
),
|
||||
call="make_call",
|
||||
)
|
||||
|
||||
@@ -98,20 +98,6 @@ class DateCall {
|
||||
|
||||
inline DateCall DateEntity::make_call() { return DateCall(this); }
|
||||
|
||||
template<typename... Ts> class DateSetAction final : public Action<Ts...>, public Parented<DateEntity> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(ESPTime, date)
|
||||
|
||||
void play(const Ts &...x) override {
|
||||
auto call = this->parent_->make_call();
|
||||
|
||||
if (this->date_.has_value()) {
|
||||
call.set_date(this->date_.value(x...));
|
||||
}
|
||||
call.perform();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace esphome::datetime
|
||||
|
||||
#endif // USE_DATETIME_DATE
|
||||
|
||||
@@ -123,20 +123,6 @@ class DateTimeCall {
|
||||
|
||||
inline DateTimeCall DateTimeEntity::make_call() { return DateTimeCall(this); }
|
||||
|
||||
template<typename... Ts> class DateTimeSetAction final : public Action<Ts...>, public Parented<DateTimeEntity> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(ESPTime, datetime)
|
||||
|
||||
void play(const Ts &...x) override {
|
||||
auto call = this->parent_->make_call();
|
||||
|
||||
if (this->datetime_.has_value()) {
|
||||
call.set_datetime(this->datetime_.value(x...));
|
||||
}
|
||||
call.perform();
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef USE_TIME
|
||||
class OnDateTimeTrigger final : public Trigger<>, public Component, public Parented<DateTimeEntity> {
|
||||
public:
|
||||
|
||||
@@ -100,20 +100,6 @@ class TimeCall {
|
||||
|
||||
inline TimeCall TimeEntity::make_call() { return TimeCall(this); }
|
||||
|
||||
template<typename... Ts> class TimeSetAction final : public Action<Ts...>, public Parented<TimeEntity> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(ESPTime, time)
|
||||
|
||||
void play(const Ts &...x) override {
|
||||
auto call = this->parent_->make_call();
|
||||
|
||||
if (this->time_.has_value()) {
|
||||
call.set_time(this->time_.value(x...));
|
||||
}
|
||||
call.perform();
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef USE_TIME
|
||||
class OnTimeTrigger final : public Trigger<>, public Component, public Parented<TimeEntity> {
|
||||
public:
|
||||
|
||||
@@ -1,3 +1,43 @@
|
||||
esphome:
|
||||
on_boot:
|
||||
then:
|
||||
- datetime.date.set:
|
||||
id: datetime_test_date
|
||||
date:
|
||||
year: 2021
|
||||
month: 1
|
||||
day: 1
|
||||
- datetime.date.set:
|
||||
id: datetime_test_date
|
||||
date: !lambda "return {.day_of_month = 1, .month = 1, .year = 2021};"
|
||||
- datetime.time.set:
|
||||
id: datetime_test_time
|
||||
time: "12:34:56"
|
||||
- datetime.time.set:
|
||||
id: datetime_test_time
|
||||
time: !lambda "return {.second = 56, .minute = 34, .hour = 12};"
|
||||
- datetime.datetime.set:
|
||||
id: datetime_test_datetime
|
||||
datetime: "2021-01-01 12:34:56"
|
||||
- datetime.datetime.set:
|
||||
id: datetime_test_datetime
|
||||
datetime: !lambda "return {.second = 56, .minute = 34, .hour = 12, .day_of_month = 1, .month = 1, .year = 2021};"
|
||||
|
||||
datetime:
|
||||
- platform: template
|
||||
name: Datetime Test Date
|
||||
id: datetime_test_date
|
||||
type: date
|
||||
optimistic: true
|
||||
- platform: template
|
||||
name: Datetime Test Time
|
||||
id: datetime_test_time
|
||||
type: time
|
||||
optimistic: true
|
||||
- platform: template
|
||||
name: Datetime Test DateTime
|
||||
id: datetime_test_datetime
|
||||
type: datetime
|
||||
optimistic: true
|
||||
|
||||
time:
|
||||
|
||||
Reference in New Issue
Block a user