ESPHome 2025.9.0-dev
Loading...
Searching...
No Matches
automation.h
Go to the documentation of this file.
1#pragma once
2
3#ifdef USE_ESP32
4
5#include "espnow_component.h"
6
9
10namespace esphome::espnow {
11
12template<typename... Ts> class SendAction : public Action<Ts...>, public Parented<ESPNowComponent> {
13 TEMPLATABLE_VALUE(peer_address_t, address);
14 TEMPLATABLE_VALUE(std::vector<uint8_t>, data);
15
16 public:
17 void add_on_sent(const std::vector<Action<Ts...> *> &actions) {
18 this->sent_.add_actions(actions);
19 if (this->flags_.wait_for_sent) {
20 this->sent_.add_action(new LambdaAction<Ts...>([this](Ts... x) { this->play_next_(x...); }));
21 }
22 }
23 void add_on_error(const std::vector<Action<Ts...> *> &actions) {
24 this->error_.add_actions(actions);
25 if (this->flags_.wait_for_sent) {
26 this->error_.add_action(new LambdaAction<Ts...>([this](Ts... x) {
27 if (this->flags_.continue_on_error) {
28 this->play_next_(x...);
29 } else {
30 this->stop_complex();
31 }
32 }));
33 }
34 }
35
36 void set_wait_for_sent(bool wait_for_sent) { this->flags_.wait_for_sent = wait_for_sent; }
37 void set_continue_on_error(bool continue_on_error) { this->flags_.continue_on_error = continue_on_error; }
38
39 void play_complex(Ts... x) override {
40 this->num_running_++;
41 send_callback_t send_callback = [this, x...](esp_err_t status) {
42 if (status == ESP_OK) {
43 if (!this->sent_.empty()) {
44 this->sent_.play(x...);
45 } else if (this->flags_.wait_for_sent) {
46 this->play_next_(x...);
47 }
48 } else {
49 if (!this->error_.empty()) {
50 this->error_.play(x...);
51 } else if (this->flags_.wait_for_sent) {
52 if (this->flags_.continue_on_error) {
53 this->play_next_(x...);
54 } else {
55 this->stop_complex();
56 }
57 }
58 }
59 };
60 peer_address_t address = this->address_.value(x...);
61 std::vector<uint8_t> data = this->data_.value(x...);
62 esp_err_t err = this->parent_->send(address.data(), data, send_callback);
63 if (err != ESP_OK) {
64 send_callback(err);
65 } else if (!this->flags_.wait_for_sent) {
66 this->play_next_(x...);
67 }
68 }
69
70 void play(Ts... x) override { /* ignore - see play_complex */
71 }
72
73 void stop() override {
74 this->sent_.stop();
75 this->error_.stop();
76 }
77
78 protected:
81
82 struct {
83 uint8_t wait_for_sent : 1; // Wait for the send operation to complete before continuing automation
84 uint8_t continue_on_error : 1; // Continue automation even if the send operation fails
85 uint8_t reserved : 6; // Reserved for future use
86 } flags_{0};
87};
88
89template<typename... Ts> class AddPeerAction : public Action<Ts...>, public Parented<ESPNowComponent> {
90 TEMPLATABLE_VALUE(peer_address_t, address);
91
92 public:
93 void play(Ts... x) override {
94 peer_address_t address = this->address_.value(x...);
95 this->parent_->add_peer(address.data());
96 }
97};
98
99template<typename... Ts> class DeletePeerAction : public Action<Ts...>, public Parented<ESPNowComponent> {
100 TEMPLATABLE_VALUE(peer_address_t, address);
101
102 public:
103 void play(Ts... x) override {
104 peer_address_t address = this->address_.value(x...);
105 this->parent_->del_peer(address.data());
106 }
107};
108
109template<typename... Ts> class SetChannelAction : public Action<Ts...>, public Parented<ESPNowComponent> {
110 public:
111 TEMPLATABLE_VALUE(uint8_t, channel)
112 void play(Ts... x) override {
113 if (this->parent_->is_wifi_enabled()) {
114 return;
115 }
116 this->parent_->set_wifi_channel(this->channel_.value(x...));
117 this->parent_->apply_wifi_channel();
118 }
119};
120
121class OnReceiveTrigger : public Trigger<const ESPNowRecvInfo &, const uint8_t *, uint8_t>,
123 public:
124 explicit OnReceiveTrigger(std::array<uint8_t, ESP_NOW_ETH_ALEN> address) : has_address_(true) {
125 memcpy(this->address_, address.data(), ESP_NOW_ETH_ALEN);
126 }
127
128 explicit OnReceiveTrigger() : has_address_(false) {}
129
130 bool on_received(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) override {
131 bool match = !this->has_address_ || (memcmp(this->address_, info.src_addr, ESP_NOW_ETH_ALEN) == 0);
132 if (!match)
133 return false;
134
135 this->trigger(info, data, size);
136 return false; // Return false to continue processing other internal handlers
137 }
138
139 protected:
140 bool has_address_{false};
141 const uint8_t *address_[ESP_NOW_ETH_ALEN];
142};
143class OnUnknownPeerTrigger : public Trigger<const ESPNowRecvInfo &, const uint8_t *, uint8_t>,
145 public:
146 bool on_unknown_peer(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) override {
147 this->trigger(info, data, size);
148 return false; // Return false to continue processing other internal handlers
149 }
150};
151class OnBroadcastedTrigger : public Trigger<const ESPNowRecvInfo &, const uint8_t *, uint8_t>,
153 public:
154 explicit OnBroadcastedTrigger(std::array<uint8_t, ESP_NOW_ETH_ALEN> address) : has_address_(true) {
155 memcpy(this->address_, address.data(), ESP_NOW_ETH_ALEN);
156 }
157 explicit OnBroadcastedTrigger() : has_address_(false) {}
158
159 bool on_broadcasted(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) override {
160 bool match = !this->has_address_ || (memcmp(this->address_, info.src_addr, ESP_NOW_ETH_ALEN) == 0);
161 if (!match)
162 return false;
163
164 this->trigger(info, data, size);
165 return false; // Return false to continue processing other internal handlers
166 }
167
168 protected:
169 bool has_address_{false};
170 const uint8_t *address_[ESP_NOW_ETH_ALEN];
171};
172
173} // namespace esphome::espnow
174
175#endif // USE_ESP32
uint8_t address
Definition bl0906.h:4
void add_action(Action< Ts... > *action)
Definition automation.h:238
void add_actions(const std::vector< Action< Ts... > * > &actions)
Definition automation.h:246
Helper class to easily give an object a parent of type T.
Definition helpers.h:656
void play(Ts... x) override
Definition automation.h:93
void play(Ts... x) override
Definition automation.h:103
Handler interface for receiving broadcasted ESPNow packets Components should inherit from this class ...
Handler interface for receiving ESPNow packets Components should inherit from this class to handle in...
Handler interface for receiving ESPNow packets from unknown peers Components should inherit from this...
bool on_broadcasted(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) override
Definition automation.h:159
OnBroadcastedTrigger(std::array< uint8_t, ESP_NOW_ETH_ALEN > address)
Definition automation.h:154
bool on_received(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) override
Definition automation.h:130
OnReceiveTrigger(std::array< uint8_t, ESP_NOW_ETH_ALEN > address)
Definition automation.h:124
bool on_unknown_peer(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) override
Definition automation.h:146
ActionList< Ts... > sent_
Definition automation.h:79
void play(Ts... x) override
Definition automation.h:70
void play_complex(Ts... x) override
Definition automation.h:39
ActionList< Ts... > error_
Definition automation.h:80
void add_on_sent(const std::vector< Action< Ts... > * > &actions)
Definition automation.h:17
void set_wait_for_sent(bool wait_for_sent)
Definition automation.h:36
struct esphome::espnow::SendAction::@81 flags_
void add_on_error(const std::vector< Action< Ts... > * > &actions)
Definition automation.h:23
void set_continue_on_error(bool continue_on_error)
Definition automation.h:37
TEMPLATABLE_VALUE(uint8_t, channel) void play(Ts... x) override
Definition automation.h:111
std::array< uint8_t, ESP_NOW_ETH_ALEN > peer_address_t
void esp_now_send_status_t status
std::function< void(esp_err_t)> send_callback_t
uint8_t src_addr[ESP_NOW_ETH_ALEN]
Source address of ESPNOW packet.
uint16_t x
Definition tt21100.cpp:5