ESPHome 2026.8.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 final : 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 final : 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 final : 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 final : 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 final : public Trigger<const ESPNowRecvInfo &, const uint8_t *, uint16_t>,
123 public ESPNowReceivedPacketHandler {
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, uint16_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 final : public Trigger<const ESPNowRecvInfo &, const uint8_t *, uint16_t>,
145 public ESPNowUnknownPeerHandler {
146 public:
147 bool on_unknown_peer(const ESPNowRecvInfo &info, const uint8_t *data, uint16_t size) override {
148 this->trigger(info, data, size);
149 return false; // Return false to continue processing other internal handlers
150 }
151};
152class OnBroadcastTrigger final : public Trigger<const ESPNowRecvInfo &, const uint8_t *, uint16_t>,
153 public ESPNowBroadcastHandler {
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, uint16_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:555
void add_actions(const std::initializer_list< Action< Ts... > * > &actions)
Definition automation.h:562
Helper class to easily give an object a parent of type T.
Definition helpers.h:1907
void play(const Ts &...x) override
Definition automation.h:93
void play(const Ts &...x) override
Definition automation.h:103
bool on_broadcast(const ESPNowRecvInfo &info, const uint8_t *data, uint16_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, uint16_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, uint16_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
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