Add repeat action for automations (#2538)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
Oxan van Leeuwen 2021-11-10 19:30:07 +01:00 committed by GitHub
parent 15f9677d33
commit d8e33c5a69
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 0 deletions

View file

@ -3,6 +3,7 @@ import esphome.config_validation as cv
from esphome.const import (
CONF_AUTOMATION_ID,
CONF_CONDITION,
CONF_COUNT,
CONF_ELSE,
CONF_ID,
CONF_THEN,
@ -66,6 +67,7 @@ DelayAction = cg.esphome_ns.class_("DelayAction", Action, cg.Component)
LambdaAction = cg.esphome_ns.class_("LambdaAction", Action)
IfAction = cg.esphome_ns.class_("IfAction", Action)
WhileAction = cg.esphome_ns.class_("WhileAction", Action)
RepeatAction = cg.esphome_ns.class_("RepeatAction", Action)
WaitUntilAction = cg.esphome_ns.class_("WaitUntilAction", Action, cg.Component)
UpdateComponentAction = cg.esphome_ns.class_("UpdateComponentAction", Action)
Automation = cg.esphome_ns.class_("Automation")
@ -241,6 +243,25 @@ async def while_action_to_code(config, action_id, template_arg, args):
return var
@register_action(
"repeat",
RepeatAction,
cv.Schema(
{
cv.Required(CONF_COUNT): cv.templatable(cv.positive_not_null_int),
cv.Required(CONF_THEN): validate_action_list,
}
),
)
async def repeat_action_to_code(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
count_template = await cg.templatable(config[CONF_COUNT], args, cg.uint32)
cg.add(var.set_count(count_template))
actions = await build_action_list(config[CONF_THEN], template_arg, args)
cg.add(var.add_then(actions))
return var
def validate_wait_until(value):
schema = cv.Schema(
{

View file

@ -224,6 +224,39 @@ template<typename... Ts> class WhileAction : public Action<Ts...> {
std::tuple<Ts...> var_{};
};
template<typename... Ts> class RepeatAction : public Action<Ts...> {
public:
TEMPLATABLE_VALUE(uint32_t, count)
void add_then(const std::vector<Action<Ts...> *> &actions) {
this->then_.add_actions(actions);
this->then_.add_action(new LambdaAction<Ts...>([this](Ts... x) {
this->iteration_++;
if (this->iteration_ == this->count_.value(x...))
this->play_next_tuple_(this->var_);
else
this->then_.play_tuple(this->var_);
}));
}
void play_complex(Ts... x) override {
this->num_running_++;
this->var_ = std::make_tuple(x...);
this->iteration_ = 0;
this->then_.play_tuple(this->var_);
}
void play(Ts... x) override { /* ignore - see play_complex */
}
void stop() override { this->then_.stop(); }
protected:
uint32_t iteration_;
ActionList<Ts...> then_;
std::tuple<Ts...> var_;
};
template<typename... Ts> class WaitUntilAction : public Action<Ts...>, public Component {
public:
WaitUntilAction(Condition<Ts...> *condition) : condition_(condition) {}

View file

@ -173,3 +173,11 @@ sensor:
uart_id: uart2
co2:
name: CO2 Sensor
script:
- id: automation_test
then:
- repeat:
count: 5
then:
- logger.log: "looping!"