ESPHome 2026.5.1
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::initializer_list<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::initializer_list<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(const 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 protected:
71 void play(const Ts &...x) override { /* ignore - see play_complex */
72 }
73
74 void stop() override {
75 this->sent_.stop();
76 this->error_.stop();
77 }
78
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 protected:
93 void play(const 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 protected:
103 void play(const 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 TEMPLATABLE_VALUE(uint8_t, channel)
111
112 protected:
113 void play(const Ts &...x) override {
114 if (this->parent_->is_wifi_enabled()) {
115 return;
116 }
117 this->parent_->set_wifi_channel(this->channel_.value(x...));
118 this->parent_->apply_wifi_channel();
119 }
120};
121
122class OnReceiveTrigger : public Trigger<const ESPNowRecvInfo &, const uint8_t *, uint8_t>,
124 public:
125 explicit OnReceiveTrigger(std::array<uint8_t, ESP_NOW_ETH_ALEN> address) : has_address_(true) {
126 memcpy(this->address_, address.data(), ESP_NOW_ETH_ALEN);
127 }
128
129 explicit OnReceiveTrigger() {}
130
131 bool on_receive(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) override {
132 bool match = !this->has_address_ || (memcmp(this->address_, info.src_addr, ESP_NOW_ETH_ALEN) == 0);
133 if (!match)
134 return false;
135
136 this->trigger(info, data, size);
137 return false; // Return false to continue processing other internal handlers
138 }
139
140 protected:
141 bool has_address_{false};
142 uint8_t address_[ESP_NOW_ETH_ALEN]{};
143};
144class OnUnknownPeerTrigger : public Trigger<const ESPNowRecvInfo &, const uint8_t *, uint8_t>,
146 public:
147 bool on_unknown_peer(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) override {
148 this->trigger(info, data, size);
149 return false; // Return false to continue processing other internal handlers
150 }
151};
152class OnBroadcastTrigger : public Trigger<const ESPNowRecvInfo &, const uint8_t *, uint8_t>,
154 public:
155 explicit OnBroadcastTrigger(std::array<uint8_t, ESP_NOW_ETH_ALEN> address) : has_address_(true) {
156 memcpy(this->address_, address.data(), ESP_NOW_ETH_ALEN);
157 }
158 explicit OnBroadcastTrigger() {}
159
160 bool on_broadcast(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) override {
161 bool match = !this->has_address_ || (memcmp(this->address_, info.src_addr, ESP_NOW_ETH_ALEN) == 0);
162 if (!match)
163 return false;
164
165 this->trigger(info, data, size);
166 return false; // Return false to continue processing other internal handlers
167 }
168
169 protected:
170 bool has_address_{false};
171 uint8_t address_[ESP_NOW_ETH_ALEN]{};
172};
173
174} // namespace esphome::espnow
175
176#endif // USE_ESP32
uint8_t address
Definition bl0906.h:4
void add_action(Action< Ts... > *action)
Definition automation.h:576
void add_actions(const std::initializer_list< Action< Ts... > * > &actions)
Definition automation.h:583
Helper class to easily give an object a parent of type T.
Definition helpers.h:1861
void play(const Ts &...x) override
Definition automation.h:93
void play(const Ts &...x) override
Definition automation.h:103
Handler interface for receiving ESPNow broadcast packets Components should inherit from this class to...
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_broadcast(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) override
Definition automation.h:160
OnBroadcastTrigger(std::array< uint8_t, ESP_NOW_ETH_ALEN > address)
Definition automation.h:155
bool on_receive(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) override
Definition automation.h:131
OnReceiveTrigger(std::array< uint8_t, ESP_NOW_ETH_ALEN > address)
Definition automation.h:125
bool on_unknown_peer(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) override
Definition automation.h:147
ActionList< Ts... > sent_
Definition automation.h:79
void play(const Ts &...x) override
Definition automation.h:71
void play_complex(const Ts &...x) override
Definition automation.h:39
void add_on_error(const std::initializer_list< Action< Ts... > * > &actions)
Definition automation.h:23
ActionList< Ts... > error_
Definition automation.h:80
void set_wait_for_sent(bool wait_for_sent)
Definition automation.h:36
void add_on_sent(const std::initializer_list< Action< Ts... > * > &actions)
Definition automation.h:17
struct esphome::espnow::SendAction::@84 flags_
void set_continue_on_error(bool continue_on_error)
Definition automation.h:37
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
uint16_t size
Definition helpers.cpp:25
uint8_t src_addr[ESP_NOW_ETH_ALEN]
Source address of ESPNOW packet.
uint16_t x
Definition tt21100.cpp:5