ESPHome 2025.9.0-dev
Loading...
Searching...
No Matches
espnow_component.h
Go to the documentation of this file.
1#pragma once
2
5
6#ifdef USE_ESP32
7
10#include "espnow_packet.h"
11
12#include <esp_idf_version.h>
13
14#include <esp_mac.h>
15#include <esp_now.h>
16
17#include <array>
18#include <map>
19#include <memory>
20#include <string>
21#include <vector>
22
23namespace esphome::espnow {
24
25// Maximum size of the ESPNow event queue - must be power of 2 for lock-free queue
26static constexpr size_t MAX_ESP_NOW_SEND_QUEUE_SIZE = 16;
27static constexpr size_t MAX_ESP_NOW_RECEIVE_QUEUE_SIZE = 16;
28
29using peer_address_t = std::array<uint8_t, ESP_NOW_ETH_ALEN>;
30
31enum class ESPNowTriggers : uint8_t {
32 TRIGGER_NONE = 0,
33 ON_NEW_PEER = 1,
34 ON_RECEIVED = 2,
36 ON_SUCCEED = 10,
37 ON_FAILED = 11,
38};
39
48
49struct ESPNowPeer {
50 uint8_t address[ESP_NOW_ETH_ALEN]; // MAC address of the peer
51
52 bool operator==(const ESPNowPeer &other) const { return memcmp(this->address, other.address, ESP_NOW_ETH_ALEN) == 0; }
53 bool operator==(const uint8_t *other) const { return memcmp(this->address, other, ESP_NOW_ETH_ALEN) == 0; }
54};
55
59 public:
65 virtual bool on_unknown_peer(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) = 0;
66};
67
71 public:
77 virtual bool on_received(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) = 0;
78};
82 public:
88 virtual bool on_broadcasted(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) = 0;
89};
90
91class ESPNowComponent : public Component {
92 public:
94 void setup() override;
95 void loop() override;
96 void dump_config() override;
97
98 float get_setup_priority() const override { return setup_priority::LATE; }
99
100 // Add a peer to the internal list of peers
102 ESPNowPeer peer;
103 memcpy(peer.address, address.data(), ESP_NOW_ETH_ALEN);
104 this->peers_.push_back(peer);
105 }
106 // Add a peer with the esp_now api and add to the internal list if doesnt exist already
107 esp_err_t add_peer(const uint8_t *peer);
108 // Remove a peer with the esp_now api and remove from the internal list if exists
109 esp_err_t del_peer(const uint8_t *peer);
110
111 void set_wifi_channel(uint8_t channel) { this->wifi_channel_ = channel; }
112 void apply_wifi_channel();
113 uint8_t get_wifi_channel();
114
115 void set_auto_add_peer(bool value) { this->auto_add_peer_ = value; }
116
117 void enable();
118 void disable();
119 bool is_disabled() const { return this->state_ == ESPNOW_STATE_DISABLED; };
120 void set_enable_on_boot(bool enable_on_boot) { this->enable_on_boot_ = enable_on_boot; }
121 bool is_wifi_enabled();
122
132 esp_err_t send(const uint8_t *peer_address, const std::vector<uint8_t> &payload,
133 const send_callback_t &callback = nullptr) {
134 return this->send(peer_address, payload.data(), payload.size(), callback);
135 }
136 esp_err_t send(const uint8_t *peer_address, const uint8_t *payload, size_t size,
137 const send_callback_t &callback = nullptr);
138
141 this->unknown_peer_handlers_.push_back(handler);
142 }
144 this->broadcasted_handlers_.push_back(handler);
145 }
146
147 protected:
148 friend void on_data_received(const esp_now_recv_info_t *info, const uint8_t *data, int size);
149#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
150 friend void on_send_report(const esp_now_send_info_t *info, esp_now_send_status_t status);
151#else
152 friend void on_send_report(const uint8_t *mac_addr, esp_now_send_status_t status);
153#endif
154
155 void enable_();
156 void send_();
157
158 std::vector<ESPNowUnknownPeerHandler *> unknown_peer_handlers_;
159 std::vector<ESPNowReceivedPacketHandler *> received_handlers_;
160 std::vector<ESPNowBroadcastedHandler *> broadcasted_handlers_;
161
162 std::vector<ESPNowPeer> peers_{};
163
164 uint8_t own_address_[ESP_NOW_ETH_ALEN]{0};
167
170 ESPNowSendPacket *current_send_packet_{nullptr}; // Currently sending packet, nullptr if none
171
172 uint8_t wifi_channel_{0};
174
175 bool auto_add_peer_{false};
176 bool enable_on_boot_{true};
177};
178
179extern ESPNowComponent *global_esp_now; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
180
181} // namespace esphome::espnow
182
183#endif // USE_ESP32
uint8_t address
Definition bl0906.h:4
Handler interface for receiving broadcasted ESPNow packets Components should inherit from this class ...
virtual bool on_broadcasted(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size)=0
Called when a broadcasted ESPNow packet is received.
esp_err_t send(const uint8_t *peer_address, const std::vector< uint8_t > &payload, const send_callback_t &callback=nullptr)
Queue a packet to be sent to a specific peer address.
LockFreeQueue< ESPNowSendPacket, MAX_ESP_NOW_SEND_QUEUE_SIZE > send_packet_queue_
void add_peer(peer_address_t address)
std::vector< ESPNowUnknownPeerHandler * > unknown_peer_handlers_
EventPool< ESPNowSendPacket, MAX_ESP_NOW_SEND_QUEUE_SIZE > send_packet_pool_
std::vector< ESPNowPeer > peers_
friend void on_send_report(const esp_now_send_info_t *info, esp_now_send_status_t status)
std::vector< ESPNowBroadcastedHandler * > broadcasted_handlers_
friend void on_data_received(const esp_now_recv_info_t *info, const uint8_t *data, int size)
void set_wifi_channel(uint8_t channel)
friend void on_send_report(const uint8_t *mac_addr, esp_now_send_status_t status)
EventPool< ESPNowPacket, MAX_ESP_NOW_RECEIVE_QUEUE_SIZE > receive_packet_pool_
void set_enable_on_boot(bool enable_on_boot)
esp_err_t del_peer(const uint8_t *peer)
void register_unknown_peer_handler(ESPNowUnknownPeerHandler *handler)
std::vector< ESPNowReceivedPacketHandler * > received_handlers_
LockFreeQueue< ESPNowPacket, MAX_ESP_NOW_RECEIVE_QUEUE_SIZE > receive_packet_queue_
void register_broadcasted_handler(ESPNowBroadcastedHandler *handler)
float get_setup_priority() const override
uint8_t own_address_[ESP_NOW_ETH_ALEN]
void register_received_handler(ESPNowReceivedPacketHandler *handler)
Handler interface for receiving ESPNow packets Components should inherit from this class to handle in...
virtual bool on_received(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size)=0
Called when an ESPNow packet is received.
Handler interface for receiving ESPNow packets from unknown peers Components should inherit from this...
virtual bool on_unknown_peer(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size)=0
Called when an ESPNow packet is received from an unknown peer.
@ ESPNOW_STATE_ENABLED
ESPNOW is enabled.
@ ESPNOW_STATE_OFF
Nothing has been initialized yet.
@ ESPNOW_STATE_DISABLED
ESPNOW is disabled.
std::array< uint8_t, ESP_NOW_ETH_ALEN > peer_address_t
ESPNowComponent * global_esp_now
void esp_now_send_status_t status
std::function< void(esp_err_t)> send_callback_t
const float LATE
For components that should be initialized at the very end of the setup process.
Definition component.cpp:59
bool operator==(const uint8_t *other) const
bool operator==(const ESPNowPeer &other) const
uint8_t address[ESP_NOW_ETH_ALEN]