ESPHome  2022.1.2
automation.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vector>
5 #include "esphome/core/helpers.h"
6 #include "esphome/core/defines.h"
8 
9 namespace esphome {
10 
11 #define TEMPLATABLE_VALUE_(type, name) \
12  protected: \
13  TemplatableValue<type, Ts...> name##_{}; \
14 \
15  public: \
16  template<typename V> void set_##name(V name) { this->name##_ = name; }
17 
18 #define TEMPLATABLE_VALUE(type, name) TEMPLATABLE_VALUE_(type, name)
19 
20 template<typename T, typename... X> class TemplatableValue {
21  public:
23 
24  template<typename F, enable_if_t<!is_invocable<F, X...>::value, int> = 0>
26 
27  template<typename F, enable_if_t<is_invocable<F, X...>::value, int> = 0>
29 
30  bool has_value() { return this->type_ != EMPTY; }
31 
32  T value(X... x) {
33  if (this->type_ == LAMBDA) {
34  return this->f_(x...);
35  }
36  // return value also when empty
37  return this->value_;
38  }
39 
41  if (!this->has_value()) {
42  return {};
43  }
44  return this->value(x...);
45  }
46 
47  T value_or(X... x, T default_value) {
48  if (!this->has_value()) {
49  return default_value;
50  }
51  return this->value(x...);
52  }
53 
54  protected:
55  enum {
59  } type_;
60 
61  T value_{};
62  std::function<T(X...)> f_{};
63 };
64 
69 template<typename... Ts> class Condition {
70  public:
72  virtual bool check(Ts... x) = 0;
73 
75  bool check_tuple(const std::tuple<Ts...> &tuple) {
76  return this->check_tuple_(tuple, typename gens<sizeof...(Ts)>::type());
77  }
78 
79  protected:
80  template<int... S> bool check_tuple_(const std::tuple<Ts...> &tuple, seq<S...>) {
81  return this->check(std::get<S>(tuple)...);
82  }
83 };
84 
85 template<typename... Ts> class Automation;
86 
87 template<typename... Ts> class Trigger {
88  public:
90  void trigger(Ts... x) {
91  if (this->automation_parent_ == nullptr)
92  return;
93  this->automation_parent_->trigger(x...);
94  }
95  void set_automation_parent(Automation<Ts...> *automation_parent) { this->automation_parent_ = automation_parent; }
96 
98  void stop_action() {
99  if (this->automation_parent_ == nullptr)
100  return;
101  this->automation_parent_->stop();
102  }
105  if (this->automation_parent_ == nullptr)
106  return false;
107  return this->automation_parent_->is_running();
108  }
109 
110  protected:
111  Automation<Ts...> *automation_parent_{nullptr};
112 };
113 
114 template<typename... Ts> class ActionList;
115 
116 template<typename... Ts> class Action {
117  public:
118  virtual void play_complex(Ts... x) {
119  this->num_running_++;
120  this->play(x...);
121  this->play_next_(x...);
122  }
123  virtual void stop_complex() {
124  if (num_running_) {
125  this->stop();
126  this->num_running_ = 0;
127  }
128  this->stop_next_();
129  }
131  virtual bool is_running() { return this->num_running_ > 0 || this->is_running_next_(); }
132 
136  int total = this->num_running_;
137  if (this->next_ != nullptr)
138  total += this->next_->num_running_total();
139  return total;
140  }
141 
142  protected:
143  friend ActionList<Ts...>;
144 
145  virtual void play(Ts... x) = 0;
146  void play_next_(Ts... x) {
147  if (this->num_running_ > 0) {
148  this->num_running_--;
149  if (this->next_ != nullptr) {
150  this->next_->play_complex(x...);
151  }
152  }
153  }
154  template<int... S> void play_next_tuple_(const std::tuple<Ts...> &tuple, seq<S...>) {
155  this->play_next_(std::get<S>(tuple)...);
156  }
157  void play_next_tuple_(const std::tuple<Ts...> &tuple) {
158  this->play_next_tuple_(tuple, typename gens<sizeof...(Ts)>::type());
159  }
160 
161  virtual void stop() {}
162  void stop_next_() {
163  if (this->next_ != nullptr) {
164  this->next_->stop_complex();
165  }
166  }
167 
169  if (this->next_ == nullptr)
170  return false;
171  return this->next_->is_running();
172  }
173 
174  Action<Ts...> *next_ = nullptr;
175 
178  int num_running_{0};
179 };
180 
181 template<typename... Ts> class ActionList {
182  public:
183  void add_action(Action<Ts...> *action) {
184  if (this->actions_end_ == nullptr) {
185  this->actions_begin_ = action;
186  } else {
187  this->actions_end_->next_ = action;
188  }
189  this->actions_end_ = action;
190  }
191  void add_actions(const std::vector<Action<Ts...> *> &actions) {
192  for (auto *action : actions) {
193  this->add_action(action);
194  }
195  }
196  void play(Ts... x) {
197  if (this->actions_begin_ != nullptr)
198  this->actions_begin_->play_complex(x...);
199  }
200  void play_tuple(const std::tuple<Ts...> &tuple) { this->play_tuple_(tuple, typename gens<sizeof...(Ts)>::type()); }
201  void stop() {
202  if (this->actions_begin_ != nullptr)
203  this->actions_begin_->stop_complex();
204  }
205  bool empty() const { return this->actions_begin_ == nullptr; }
206 
208  bool is_running() {
209  if (this->actions_begin_ == nullptr)
210  return false;
211  return this->actions_begin_->is_running();
212  }
214  int num_running() {
215  if (this->actions_begin_ == nullptr)
216  return false;
217  return this->actions_begin_->num_running_total();
218  }
219 
220  protected:
221  template<int... S> void play_tuple_(const std::tuple<Ts...> &tuple, seq<S...>) { this->play(std::get<S>(tuple)...); }
222 
223  Action<Ts...> *actions_begin_{nullptr};
224  Action<Ts...> *actions_end_{nullptr};
225 };
226 
227 template<typename... Ts> class Automation {
228  public:
229  explicit Automation(Trigger<Ts...> *trigger) : trigger_(trigger) { this->trigger_->set_automation_parent(this); }
230 
231  Action<Ts...> *add_action(Action<Ts...> *action) { this->actions_.add_action(action); }
232  void add_actions(const std::vector<Action<Ts...> *> &actions) { this->actions_.add_actions(actions); }
233 
234  void stop() { this->actions_.stop(); }
235 
236  void trigger(Ts... x) { this->actions_.play(x...); }
237 
238  bool is_running() { return this->actions_.is_running(); }
239 
241  int num_running() { return this->actions_.num_running(); }
242 
243  protected:
244  Trigger<Ts...> *trigger_;
246 };
247 
248 } // namespace esphome
virtual void stop()
Definition: automation.h:161
bool is_running_next_()
Definition: automation.h:168
void trigger(Ts... x)
Definition: automation.h:236
void add_action(Action< Ts... > *action)
Definition: automation.h:183
T value_or(X... x, T default_value)
Definition: automation.h:47
Action< Ts... > * next_
Definition: automation.h:174
virtual void play_complex(Ts... x)
Definition: automation.h:118
typename std::enable_if< B, T >::type enable_if_t
Definition: helpers.h:157
int num_running()
Return the number of actions in the action part of this automation that are currently running...
Definition: automation.h:241
virtual void stop_complex()
Definition: automation.h:123
int num_running_total()
The total number of actions that are currently running in this plus any of the following actions in t...
Definition: automation.h:135
void play_tuple_(const std::tuple< Ts... > &tuple, seq< S... >)
Definition: automation.h:221
bool check_tuple_(const std::tuple< Ts... > &tuple, seq< S... >)
Definition: automation.h:80
bool is_running()
Check if any action in this action list is currently running.
Definition: automation.h:208
bool is_action_running()
Returns true if any action connected to this trigger is running.
Definition: automation.h:104
void trigger(Ts... x)
Inform the parent automation that the event has triggered.
Definition: automation.h:90
void play_next_tuple_(const std::tuple< Ts... > &tuple)
Definition: automation.h:157
Trigger< Ts... > * trigger_
Definition: automation.h:244
void play(Ts... x)
Definition: automation.h:196
void stop_next_()
Definition: automation.h:162
void play_next_tuple_(const std::tuple< Ts... > &tuple, seq< S... >)
Definition: automation.h:154
void play_tuple(const std::tuple< Ts... > &tuple)
Definition: automation.h:200
Base class for all automation conditions.
Definition: automation.h:69
void add_actions(const std::vector< Action< Ts... > *> &actions)
Definition: automation.h:191
Action< Ts... > * add_action(Action< Ts... > *action)
Definition: automation.h:231
uint8_t type
std::function< T(X...)> f_
Definition: automation.h:62
ActionList< Ts... > actions_
Definition: automation.h:245
int num_running()
Return the number of actions in this action list that are currently running.
Definition: automation.h:214
optional< T > optional_value(X... x)
Definition: automation.h:40
bool check_tuple(const std::tuple< Ts... > &tuple)
Call check with a tuple of values as parameter.
Definition: automation.h:75
virtual bool is_running()
Check if this or any of the following actions are currently running.
Definition: automation.h:131
void set_automation_parent(Automation< Ts... > *automation_parent)
Definition: automation.h:95
Automation(Trigger< Ts... > *trigger)
Definition: automation.h:229
Library based on https://github.com/miguelbalboa/rfid and adapted to ESPHome by . ...
Definition: a4988.cpp:4
void play_next_(Ts... x)
Definition: automation.h:146
void add_actions(const std::vector< Action< Ts... > *> &actions)
Definition: automation.h:232
bool empty() const
Definition: automation.h:205
void stop_action()
Stop any action connected to this trigger.
Definition: automation.h:98
enum esphome::TemplatableValue::@66 type_