| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- #pragma once
- #include "esphome/core/automation.h"
- #include "esphome/core/component.h"
- namespace esphome {
- template<typename... Ts> class AndCondition : public Condition<Ts...> {
- public:
- explicit AndCondition(const std::vector<Condition<Ts...> *> &conditions) : conditions_(conditions) {}
- bool check(Ts... x) override {
- for (auto *condition : this->conditions_) {
- if (!condition->check(x...))
- return false;
- }
- return true;
- }
- protected:
- std::vector<Condition<Ts...> *> conditions_;
- };
- template<typename... Ts> class OrCondition : public Condition<Ts...> {
- public:
- explicit OrCondition(const std::vector<Condition<Ts...> *> &conditions) : conditions_(conditions) {}
- bool check(Ts... x) override {
- for (auto *condition : this->conditions_) {
- if (condition->check(x...))
- return true;
- }
- return false;
- }
- protected:
- std::vector<Condition<Ts...> *> conditions_;
- };
- template<typename... Ts> class NotCondition : public Condition<Ts...> {
- public:
- explicit NotCondition(Condition<Ts...> *condition) : condition_(condition) {}
- bool check(Ts... x) override { return !this->condition_->check(x...); }
- protected:
- Condition<Ts...> *condition_;
- };
- template<typename... Ts> class LambdaCondition : public Condition<Ts...> {
- public:
- explicit LambdaCondition(std::function<bool(Ts...)> &&f) : f_(std::move(f)) {}
- bool check(Ts... x) override { return this->f_(x...); }
- protected:
- std::function<bool(Ts...)> f_;
- };
- template<typename... Ts> class ForCondition : public Condition<Ts...>, public Component {
- public:
- explicit ForCondition(Condition<> *condition) : condition_(condition) {}
- TEMPLATABLE_VALUE(uint32_t, time);
- void loop() override { this->check_internal(); }
- float get_setup_priority() const override { return setup_priority::DATA; }
- bool check_internal() {
- bool cond = this->condition_->check();
- if (!cond)
- this->last_inactive_ = millis();
- return cond;
- }
- bool check(Ts... x) override {
- if (!this->check_internal())
- return false;
- return millis() - this->last_inactive_ >= this->time_.value(x...);
- }
- protected:
- Condition<> *condition_;
- uint32_t last_inactive_{0};
- };
- class StartupTrigger : public Trigger<>, public Component {
- public:
- explicit StartupTrigger(float setup_priority) : setup_priority_(setup_priority) {}
- void setup() override { this->trigger(); }
- float get_setup_priority() const override { return this->setup_priority_; }
- protected:
- float setup_priority_;
- };
- class ShutdownTrigger : public Trigger<>, public Component {
- public:
- void on_shutdown() override { this->trigger(); }
- };
- class LoopTrigger : public Trigger<>, public Component {
- public:
- void loop() override { this->trigger(); }
- float get_setup_priority() const override { return setup_priority::DATA; }
- };
- template<typename... Ts> class DelayAction : public Action<Ts...>, public Component {
- public:
- explicit DelayAction() = default;
- TEMPLATABLE_VALUE(uint32_t, delay)
- void play_complex(Ts... x) override {
- auto f = std::bind(&DelayAction<Ts...>::play_next_, this, x...);
- this->num_running_++;
- this->set_timeout(this->delay_.value(x...), f);
- }
- float get_setup_priority() const override { return setup_priority::HARDWARE; }
- void play(Ts... x) override { /* ignore - see play_complex */
- }
- void stop() override { this->cancel_timeout(""); }
- };
- template<typename... Ts> class LambdaAction : public Action<Ts...> {
- public:
- explicit LambdaAction(std::function<void(Ts...)> &&f) : f_(std::move(f)) {}
- void play(Ts... x) override { this->f_(x...); }
- protected:
- std::function<void(Ts...)> f_;
- };
- template<typename... Ts> class IfAction : public Action<Ts...> {
- public:
- explicit IfAction(Condition<Ts...> *condition) : condition_(condition) {}
- 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->play_next_(x...); }));
- }
- void add_else(const std::vector<Action<Ts...> *> &actions) {
- this->else_.add_actions(actions);
- this->else_.add_action(new LambdaAction<Ts...>([this](Ts... x) { this->play_next_(x...); }));
- }
- void play_complex(Ts... x) override {
- this->num_running_++;
- bool res = this->condition_->check(x...);
- if (res) {
- if (this->then_.empty()) {
- this->play_next_(x...);
- } else if (this->num_running_ > 0) {
- this->then_.play(x...);
- }
- } else {
- if (this->else_.empty()) {
- this->play_next_(x...);
- } else if (this->num_running_ > 0) {
- this->else_.play(x...);
- }
- }
- }
- void play(Ts... x) override { /* ignore - see play_complex */
- }
- void stop() override {
- this->then_.stop();
- this->else_.stop();
- }
- protected:
- Condition<Ts...> *condition_;
- ActionList<Ts...> then_;
- ActionList<Ts...> else_;
- };
- template<typename... Ts> class WhileAction : public Action<Ts...> {
- public:
- WhileAction(Condition<Ts...> *condition) : condition_(condition) {}
- void add_then(const std::vector<Action<Ts...> *> &actions) {
- this->then_.add_actions(actions);
- this->then_.add_action(new LambdaAction<Ts...>([this](Ts... x) {
- if (this->num_running_ > 0 && this->condition_->check_tuple(this->var_)) {
- // play again
- if (this->num_running_ > 0) {
- this->then_.play_tuple(this->var_);
- }
- } else {
- // condition false, play next
- this->play_next_tuple_(this->var_);
- }
- }));
- }
- void play_complex(Ts... x) override {
- this->num_running_++;
- // Store loop parameters
- this->var_ = std::make_tuple(x...);
- // Initial condition check
- if (!this->condition_->check_tuple(this->var_)) {
- // If new condition check failed, stop loop if running
- this->then_.stop();
- this->play_next_tuple_(this->var_);
- return;
- }
- if (this->num_running_ > 0) {
- this->then_.play_tuple(this->var_);
- }
- }
- void play(Ts... x) override { /* ignore - see play_complex */
- }
- void stop() override { this->then_.stop(); }
- protected:
- Condition<Ts...> *condition_;
- ActionList<Ts...> then_;
- std::tuple<Ts...> var_{};
- };
- template<typename... Ts> class WaitUntilAction : public Action<Ts...>, public Component {
- public:
- WaitUntilAction(Condition<Ts...> *condition) : condition_(condition) {}
- void play_complex(Ts... x) override {
- this->num_running_++;
- // Check if we can continue immediately.
- if (this->condition_->check(x...)) {
- if (this->num_running_ > 0) {
- this->play_next_(x...);
- }
- return;
- }
- this->var_ = std::make_tuple(x...);
- this->loop();
- }
- void loop() override {
- if (this->num_running_ == 0)
- return;
- if (!this->condition_->check_tuple(this->var_)) {
- return;
- }
- this->play_next_tuple_(this->var_);
- }
- float get_setup_priority() const override { return setup_priority::DATA; }
- void play(Ts... x) override { /* ignore - see play_complex */
- }
- protected:
- Condition<Ts...> *condition_;
- std::tuple<Ts...> var_{};
- };
- template<typename... Ts> class UpdateComponentAction : public Action<Ts...> {
- public:
- UpdateComponentAction(PollingComponent *component) : component_(component) {}
- void play(Ts... x) override { this->component_->update(); }
- protected:
- PollingComponent *component_;
- };
- } // namespace esphome
|