mirror of
https://github.com/esphome/esphome.git
synced 2024-11-27 17:27:59 +01:00
add peer class
add broadcast action
This commit is contained in:
parent
5e526e2a37
commit
de5519bcaa
4 changed files with 176 additions and 77 deletions
|
@ -11,6 +11,8 @@ ESPNowComponent = espnow_ns.class_("ESPNowComponent", cg.Component)
|
|||
ESPNowListener = espnow_ns.class_("ESPNowListener")
|
||||
|
||||
ESPNowPacket = espnow_ns.class_("ESPNowPacket")
|
||||
ESPNowPeer = espnow_ns.class_("Peer")
|
||||
|
||||
ESPNowPacketConst = ESPNowPacket.operator("const")
|
||||
|
||||
|
||||
|
@ -53,6 +55,20 @@ def validate_raw_data(value):
|
|||
)
|
||||
|
||||
|
||||
def validate_espnow_peer():
|
||||
return PEER_SCHEMA
|
||||
|
||||
|
||||
PEER_SCHEMA = cv.Any(
|
||||
{
|
||||
cv.templatable(validate_espnow_peer),
|
||||
cv.All(cv.string, cv.Length(min=8, max=8)),
|
||||
cv.mac_address,
|
||||
cv.uint64_t,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ESPNowComponent),
|
||||
|
@ -145,13 +161,26 @@ async def register_protocol(var, config):
|
|||
cg.add(now.register_protocol(var))
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"espnow.broatcast",
|
||||
SendAction,
|
||||
cv.maybe_simple_value(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(ESPNowComponent),
|
||||
cv.Optional(CONF_PEER, default=0xFFFFFFFFFFFF): cv.uint64_t,
|
||||
cv.Required(CONF_DATA): cv.templatable(validate_raw_data),
|
||||
cv.Optional(CONF_COMMAND): cv.templatable(cv.Range(min=16, max=255)),
|
||||
},
|
||||
key=CONF_DATA,
|
||||
),
|
||||
)
|
||||
@automation.register_action(
|
||||
"espnow.send",
|
||||
SendAction,
|
||||
cv.maybe_simple_value(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(ESPNowComponent),
|
||||
cv.Optional(CONF_PEER): cv.templatable(cv.mac_address),
|
||||
cv.Required(CONF_PEER): validate_espnow_peer,
|
||||
cv.Required(CONF_DATA): cv.templatable(validate_raw_data),
|
||||
cv.Optional(CONF_COMMAND): cv.templatable(cv.Range(min=16, max=255)),
|
||||
},
|
||||
|
@ -163,7 +192,7 @@ async def send_action(config, action_id, template_arg, args):
|
|||
await cg.register_parented(var, config[CONF_ID])
|
||||
if CONF_PEER in config:
|
||||
template_ = await cg.templatable(config[CONF_PEER].as_hex, args, cg.uint64)
|
||||
cg.add(var.set_mac(template_))
|
||||
cg.add(var.set_peer(template_))
|
||||
|
||||
if CONF_COMMAND in config:
|
||||
template_ = await cg.templatable(config[CONF_COMMAND], args, cg.uint8)
|
||||
|
@ -206,5 +235,5 @@ async def send_action(config, action_id, template_arg, args):
|
|||
async def del_peer_action(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
template_ = await cg.templatable(config[CONF_PEER].as_hex, args, cg.uint64)
|
||||
cg.add(var.set_mac(template_))
|
||||
cg.add(var.set_peer(template_))
|
||||
return var
|
||||
|
|
|
@ -36,7 +36,7 @@ ESPNowComponent::ESPNowComponent() { ESPNowComponent::static_ = this; } // NOLI
|
|||
void ESPNowComponent::dump_config() {
|
||||
ESP_LOGCONFIG(TAG, "esp_now:");
|
||||
|
||||
ESP_LOGCONFIG(TAG, " Own Peer Address: 0x%12llx.", this->own_peer_address_);
|
||||
ESP_LOGCONFIG(TAG, " Own Peer Address: %s.", decode_peer(this->own_peer_address_));
|
||||
ESP_LOGCONFIG(TAG, " Wifi channel: %d.", this->wifi_channel_);
|
||||
ESP_LOGCONFIG(TAG, " Auto add new peers: %s.", this->auto_add_peer_ ? "Yes" : "No");
|
||||
|
||||
|
@ -46,10 +46,10 @@ void ESPNowComponent::dump_config() {
|
|||
}
|
||||
|
||||
void ESPNowComponent::show_packet(const std::string &title, const ESPNowPacket &packet) {
|
||||
ESP_LOGV(TAG, "%s packet. Peer: 0x%12llx, Header: %c%c%c, Protocol:%c%c%c-%02x, Sequents: %d.%d, Size: %d, Valid: %s",
|
||||
title.c_str(), packet.peer, packet.get_byte_at(0), packet.get_byte_at(1), packet.get_byte_at(2),
|
||||
packet.get_byte_at(3), packet.get_byte_at(4), packet.get_byte_at(5), packet.get_byte_at(6),
|
||||
packet.get_byte_at(7), packet.attempts, packet.content_size(), packet.is_valid() ? "Yes" : "No");
|
||||
ESP_LOGV(TAG, "%s packet. Peer: %s, Header: %c%c%c, Protocol:%c%c%c-%02x, Sequents: %d.%d, Size: %d, Valid: %s",
|
||||
title.c_str(), packet.peer.c_str(), packet.at(0), packet.at(1), packet.at(2), packet.at(3), packet.at(4),
|
||||
packet.at(5), packet.at(6), packet.at(7), packet.attempts, packet.content_size(),
|
||||
packet.is_valid() ? "Yes" : "No");
|
||||
}
|
||||
|
||||
bool ESPNowComponent::validate_channel_(uint8_t channel) {
|
||||
|
@ -114,9 +114,9 @@ void ESPNowComponent::setup() {
|
|||
|
||||
esp_wifi_get_mac(WIFI_IF_STA, (uint8_t *) &this->own_peer_address_);
|
||||
|
||||
for (auto &address : this->peers_) {
|
||||
ESP_LOGV(TAG, "Add peer '%012llx'.", address);
|
||||
add_peer(address);
|
||||
for (auto &peer : this->peers_) {
|
||||
ESP_LOGV(TAG, "Add peer '%s'.", peer.c_str());
|
||||
add_peer(peer);
|
||||
}
|
||||
|
||||
this->send_queue_ = xQueueCreate(SEND_BUFFER_SIZE, sizeof(ESPNowPacket));
|
||||
|
@ -146,7 +146,7 @@ void ESPNowComponent::espnow_task(void *param) {
|
|||
ESPNowPacket packet; // NOLINT
|
||||
for (;;) {
|
||||
if (xQueueReceive(this_espnow->receive_queue_, (void *) &packet, (TickType_t) 1) == pdTRUE) {
|
||||
uint8_t *mac = packet.get_peer();
|
||||
uint8_t *mac = packet.peer.mac();
|
||||
if (esp_now_is_peer_exist(mac)) {
|
||||
this_espnow->call_on_receive_(packet);
|
||||
} else {
|
||||
|
@ -158,13 +158,13 @@ void ESPNowComponent::espnow_task(void *param) {
|
|||
}
|
||||
if (xQueueReceive(this_espnow->send_queue_, (void *) &packet, (TickType_t) 1) == pdTRUE) {
|
||||
if (packet.attempts > this_espnow->retries_) {
|
||||
ESP_LOGE(TAG, "Dropped '%012llx' (%d.%d). To many retries.", packet.peer, packet.get_sequents(),
|
||||
ESP_LOGE(TAG, "Dropped '%s' (%d.%d). To many retries.", packet.peer.c_str(), packet.get_sequents(),
|
||||
packet.attempts);
|
||||
this_espnow->unlock();
|
||||
continue;
|
||||
} else if (this_espnow->is_locked()) {
|
||||
if (packet.timestamp + this_espnow->conformation_timeout_ < millis()) {
|
||||
ESP_LOGW(TAG, "TimeOut '%012llx' (%d.%d).", packet.peer, packet.get_sequents(), packet.attempts);
|
||||
ESP_LOGW(TAG, "TimeOut '%s' (%d.%d).", packet.peer.c_str(), packet.get_sequents(), packet.attempts);
|
||||
this_espnow->unlock();
|
||||
}
|
||||
} else {
|
||||
|
@ -172,14 +172,14 @@ void ESPNowComponent::espnow_task(void *param) {
|
|||
packet.retry();
|
||||
packet.timestamp = millis();
|
||||
|
||||
esp_err_t err = esp_now_send(packet.get_peer(), packet.get_content(), packet.content_size());
|
||||
esp_err_t err = esp_now_send(packet.peer.mac(), packet.get_content(), packet.content_size());
|
||||
|
||||
if (err == ESP_OK) {
|
||||
ESP_LOGD(TAG, "Sended '%012llx' (%d.%d) from buffer. Wait for conformation.", packet.peer,
|
||||
ESP_LOGD(TAG, "Sended '%s' (%d.%d) from buffer. Wait for conformation.", packet.peer.c_str(),
|
||||
packet.get_sequents(), packet.attempts);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Sending '%012llx' (%d.%d) FAILED. B: %d.", packet.peer, packet.get_sequents(), packet.attempts,
|
||||
this_espnow->send_queue_used());
|
||||
ESP_LOGE(TAG, "Sending '%s' (%d.%d) FAILED. B: %d.", packet.peer.c_str(), packet.get_sequents(),
|
||||
packet.attempts, this_espnow->send_queue_used());
|
||||
this_espnow->unlock();
|
||||
}
|
||||
}
|
||||
|
@ -188,26 +188,26 @@ void ESPNowComponent::espnow_task(void *param) {
|
|||
}
|
||||
}
|
||||
|
||||
esp_err_t ESPNowComponent::add_peer(uint64_t addr) {
|
||||
esp_err_t ESPNowComponent::add_peer(Peer peer) {
|
||||
if (!this->is_ready()) {
|
||||
this->peers_.push_back(addr);
|
||||
this->peers_.push_back(peer);
|
||||
return ESP_OK;
|
||||
} else {
|
||||
this->del_peer(addr);
|
||||
this->del_peer(peer);
|
||||
|
||||
esp_now_peer_info_t peer_info = {};
|
||||
memset(&peer_info, 0, sizeof(esp_now_peer_info_t));
|
||||
peer_info.channel = this->wifi_channel_;
|
||||
peer_info.encrypt = false;
|
||||
memcpy((void *) peer_info.peer_addr, (void *) &addr, 6);
|
||||
memcpy((void *) peer_info.peer_addr, (void *) peer.mac(), 6);
|
||||
|
||||
return esp_now_add_peer(&peer_info);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t ESPNowComponent::del_peer(uint64_t addr) {
|
||||
if (esp_now_is_peer_exist((uint8_t *) &addr))
|
||||
return esp_now_del_peer((uint8_t *) &addr);
|
||||
esp_err_t ESPNowComponent::del_peer(Peer peer) {
|
||||
if (esp_now_is_peer_exist((uint8_t *) peer.mac()))
|
||||
return esp_now_del_peer((uint8_t *) &peer.mac());
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@ -292,18 +292,18 @@ bool ESPNowComponent::send(ESPNowPacket packet) {
|
|||
ESP_LOGE(TAG, "Cannot send espnow packet, espnow failed to setup");
|
||||
} else if (this->send_queue_full()) {
|
||||
ESP_LOGE(TAG, "Send Buffer Out of Memory.");
|
||||
} else if (!esp_now_is_peer_exist(packet.get_peer())) {
|
||||
ESP_LOGE(TAG, "Peer not registered: 0x%12llx.", packet.peer);
|
||||
} else if (!esp_now_is_peer_exist(packet.peer.mac())) {
|
||||
ESP_LOGE(TAG, "Peer not registered: %s.", packet.peer.c_str());
|
||||
} else if (!packet.is_valid()) {
|
||||
ESP_LOGE(TAG, "This Packet is invalid: '%012llx' (%d.%d)", packet.peer, packet.get_sequents(), packet.attempts);
|
||||
} else if (this->use_sent_check_) {
|
||||
ESP_LOGV(TAG, "Placing '%012llx' (%d.%d) into send buffer. Used: %d of %d", packet.peer, packet.get_sequents(),
|
||||
ESP_LOGE(TAG, "This Packet is invalid: %s (%d.%d)", packet.c_str(), packet.get_sequents(), packet.attempts);
|
||||
} else if (this->use_sent_check_ && packet.peer != ESPNOW_BROADCAST_ADDR) {
|
||||
ESP_LOGV(TAG, "Placing %s (%d.%d) into send buffer. Used: %d of %d", packet.peer.c_str(), packet.get_sequents(),
|
||||
packet.attempts, this->send_queue_used(), SEND_BUFFER_SIZE);
|
||||
xQueueSendToBack(this->send_queue_, (void *) &packet, 10);
|
||||
return true;
|
||||
} else {
|
||||
esp_err_t err = esp_now_send(packet.get_peer(), packet.get_content(), packet.content_size());
|
||||
ESP_LOGV(TAG, "Sended '%012llx' (%d.%d) directly%s.", packet.peer, packet.get_sequents(), packet.attempts,
|
||||
esp_err_t err = esp_now_send(packet.peer.mac(), packet.get_content(), packet.content_size());
|
||||
ESP_LOGV(TAG, "Sending to %s (%d.%d) directly%s.", packet.peer.c_str(), packet.get_sequents(), packet.attempts,
|
||||
(err == ESP_OK) ? "" : " FAILED");
|
||||
|
||||
this->call_on_sent_(packet, err == ESP_OK);
|
||||
|
@ -315,17 +315,16 @@ bool ESPNowComponent::send(ESPNowPacket packet) {
|
|||
|
||||
void ESPNowComponent::on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status) {
|
||||
ESPNowPacket packet; // NOLINT
|
||||
uint64_t mac64;
|
||||
memcpy((void *) &mac64, mac_addr, 6);
|
||||
Peer peer(mac_addr);
|
||||
if (xQueuePeek(ESPNowComponent::static_->send_queue_, (void *) &packet, 10 / portTICK_PERIOD_MS) == pdTRUE) {
|
||||
if (!packet.is_peer(mac_addr)) {
|
||||
ESP_LOGE(TAG, " Invalid mac address. Expected: '%012llx' (%d.%d) got: '%012llx'", packet.peer,
|
||||
packet.get_sequents(), packet.attempts, mac64);
|
||||
if (packet.peer != peer) {
|
||||
ESP_LOGE(TAG, " Invalid mac address. Expected: %s (%d.%d); got: %s", packet.peer.c_str(), packet.get_sequents(),
|
||||
packet.attempts, peer.c_str());
|
||||
return;
|
||||
} else if (status != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Sent packet failed for '%012llx' (%d.%d)", packet.peer, packet.get_sequents(), packet.attempts);
|
||||
ESP_LOGE(TAG, "Sent packet failed for %s (%d.%d)", packet.peer.c_str(), packet.get_sequents(), packet.attempts);
|
||||
} else {
|
||||
ESP_LOGV(TAG, "Confirm packet sent '%012llx' (%d.%d)", packet.peer, packet.get_sequents(), packet.attempts);
|
||||
ESP_LOGV(TAG, "Confirm packet sent %s (%d.%d)", packet.peer.c_str(), packet.get_sequents(), packet.attempts);
|
||||
xQueueReceive(ESPNowComponent::static_->send_queue_, (void *) &packet, 10 / portTICK_PERIOD_MS);
|
||||
}
|
||||
ESPNowComponent::static_->call_on_sent_(packet, status == ESP_OK);
|
||||
|
@ -335,7 +334,7 @@ void ESPNowComponent::on_data_sent(const uint8_t *mac_addr, esp_now_send_status_
|
|||
|
||||
/* ESPNowProtocol ********************************************************************** */
|
||||
|
||||
bool ESPNowProtocol::send(uint64_t peer, const uint8_t *data, uint8_t len, uint8_t command) {
|
||||
bool ESPNowProtocol::send(Peer peer, const uint8_t *data, uint8_t len, uint8_t command) {
|
||||
ESPNowPacket packet(peer, data, len, this->get_protocol_id()); // NOLINT
|
||||
packet.set_sequents(this->get_next_sequents(packet.peer));
|
||||
packet.set_command(command);
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "esphome/core/automation.h"
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include <esp_now.h>
|
||||
|
||||
#include <array>
|
||||
|
@ -29,8 +28,96 @@ static const uint8_t ESPNOW_COMMAND_ACK = 0x06;
|
|||
static const uint8_t ESPNOW_COMMAND_NAK = 0x15;
|
||||
static const uint8_t ESPNOW_COMMAND_RESEND = 0x05;
|
||||
|
||||
static const char chars[] = "0123456789-AbCdEfGhIjKlMnOpQrStUvWxYz+aBcDeFgHiJkLmNoPqRsTuVwXyZ";
|
||||
static const uint64_t FAILED = 0;
|
||||
|
||||
std::string encode_peer(uint64_t peer) {
|
||||
std::string str1 = "";
|
||||
if (peer == FAILED) {
|
||||
return "[Not Set]"
|
||||
} else if (peer == ESPNOW_BROADCAST_ADDR)
|
||||
return "[BroadCast]";
|
||||
do {
|
||||
str1.push_back(chars[peer & 63]); // Add on the left
|
||||
peer = peer >> 6;
|
||||
} while (peer != 0);
|
||||
return str1;
|
||||
}
|
||||
|
||||
uint64_t decode_peer(std::string peer) {
|
||||
uint64_t mac = 0;
|
||||
if (peer.size() != 8)
|
||||
return FAILED;
|
||||
|
||||
for (int pos = peer.size(); pos > 0; pos--) {
|
||||
char *p = strchr(chars, peer[pos - 1]);
|
||||
if (p == nullptr)
|
||||
return FAILED;
|
||||
mac = (mac << 6) + (p - chars);
|
||||
}
|
||||
return mac;
|
||||
}
|
||||
|
||||
struct Peer {
|
||||
uint64_t id{0};
|
||||
|
||||
inline Peer() ESPHOME_ALWAYS_INLINE{};
|
||||
|
||||
inline Peer(const Peer &peer) ESPHOME_ALWAYS_INLINE { this.is = peer.id; }
|
||||
inline Peer(std::String peer) ESPHOME_ALWAYS_INLINE { this->id = decode_peer(peercode); }
|
||||
inline Peer(uint64_t peer) ESPHOME_ALWAYS_INLINE { this->id = peerid; }
|
||||
inline Peer(const uint8_t *peer) ESPHOME_ALWAYS_INLINE { this = peer; }
|
||||
|
||||
inline uint8_t *mac() const { return (uint8_t *) &(this->id); }
|
||||
inline std::string code() const { return encode_peer(this->id); }
|
||||
|
||||
inline char *c_str() const { return encode_peer(this->id).c_str(); }
|
||||
|
||||
inline bool operator=(const Peer &peer) { // NOLINT
|
||||
return this->id = peer.id;
|
||||
}
|
||||
inline Color &operator=(uint8_t *peer) ESPHOME_ALWAYS_INLINE {
|
||||
memcpy((void *) this->mac(), (const void *) peer, 6);
|
||||
return *this;
|
||||
}
|
||||
inline Color &operator=(std::String peer) ESPHOME_ALWAYS_INLINE {
|
||||
this->id = decode_peer(peercode);
|
||||
return *this;
|
||||
}
|
||||
inline Color &operator=(uint64_t peer) ESPHOME_ALWAYS_INLINE {
|
||||
this->id = peer;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator==(const Peer &peer) { // NOLINT
|
||||
return this->id == peer.id;
|
||||
}
|
||||
inline bool operator==(uint64_t peer) { // NOLINT
|
||||
return this->id == peer;
|
||||
}
|
||||
inline bool operator==(std::String peer) { // NOLINT
|
||||
return this->id == decode_peer(peer);
|
||||
}
|
||||
inline bool operator==(const uint8_t *peer) { // NOLINT
|
||||
return memcmp(peer, this->mac(), 6) == 0;
|
||||
}
|
||||
|
||||
inline bool operator!=(const Peer &peer) { // NOLINT
|
||||
return this->id != peer.id;
|
||||
}
|
||||
inline bool operator!=(uint64_t peer) { // NOLINT
|
||||
return this->id != rhs.raw_32;
|
||||
}
|
||||
inline bool operator!=(std::String peer) { // NOLINT
|
||||
return this->id != decode_peer(peer);
|
||||
}
|
||||
inline bool operator!=(const uint8_t *peer) { // NOLINT
|
||||
return memcmp(peer, this->mac(), 6) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct ESPNowPacket {
|
||||
uint64_t peer{0};
|
||||
Peer &peerid{0};
|
||||
uint8_t rssi{0};
|
||||
int8_t attempts{0};
|
||||
bool is_broadcast{false};
|
||||
|
@ -47,12 +134,11 @@ struct ESPNowPacket {
|
|||
|
||||
inline ESPNowPacket() ESPHOME_ALWAYS_INLINE {}
|
||||
// Create packet to be send.
|
||||
inline ESPNowPacket(uint64_t peer, const uint8_t *data, uint8_t size, uint32_t protocol,
|
||||
|
||||
inline ESPNowPacket(Peer peer, const uint8_t *data, uint8_t size, uint32_t protocol,
|
||||
uint8_t command = 0) ESPHOME_ALWAYS_INLINE {
|
||||
assert(size <= MAX_ESPNOW_DATA_SIZE);
|
||||
if (peer == 0) {
|
||||
peer = ESPNOW_BROADCAST_ADDR;
|
||||
}
|
||||
assert(peer == 0);
|
||||
|
||||
this->peer = peer;
|
||||
|
||||
|
@ -63,21 +149,6 @@ struct ESPNowPacket {
|
|||
this->size = size;
|
||||
std::memcpy(this->get_payload(), data, size);
|
||||
}
|
||||
// Load received packet's.
|
||||
ESPNowPacket(const uint8_t *peer, const uint8_t *data, uint8_t size) ESPHOME_ALWAYS_INLINE {
|
||||
this->set_peer(peer);
|
||||
std::memcpy(this->get_content(), data, size);
|
||||
this->size = size - this->prefix_size();
|
||||
}
|
||||
|
||||
inline uint8_t *get_peer() const { return (uint8_t *) &(this->peer); }
|
||||
inline void set_peer(const uint8_t *peer) ESPHOME_ALWAYS_INLINE {
|
||||
if (*peer == 0) {
|
||||
peer = (uint8_t *) &ESPNOW_BROADCAST_ADDR;
|
||||
}
|
||||
memcpy((void *) this->get_peer(), (const void *) peer, 6);
|
||||
};
|
||||
inline bool is_peer(const uint8_t *peer) const { return memcmp(peer, this->get_peer(), 6) == 0; }
|
||||
|
||||
uint8_t prefix_size() const { return sizeof(this->content.prefix); }
|
||||
|
||||
|
@ -98,7 +169,7 @@ struct ESPNowPacket {
|
|||
|
||||
inline uint8_t *get_content() const { return (uint8_t *) &(this->content); }
|
||||
inline uint8_t *get_payload() const { return (uint8_t *) &(this->content.payload); }
|
||||
inline uint8_t get_byte_at(uint8_t pos) const {
|
||||
inline uint8_t at(uint8_t pos) const {
|
||||
assert(pos < this->size);
|
||||
return *(((uint8_t *) &this->content) + pos);
|
||||
}
|
||||
|
@ -143,7 +214,7 @@ class ESPNowProtocol : public Parented<ESPNowComponent> {
|
|||
return valid;
|
||||
}
|
||||
|
||||
bool send(uint64_t peer, const uint8_t *data, uint8_t len, uint8_t command = 0);
|
||||
bool send(peer peer, const uint8_t *data, uint8_t len, uint8_t command = 0);
|
||||
|
||||
protected:
|
||||
uint8_t next_sequents_{255};
|
||||
|
@ -207,8 +278,8 @@ class ESPNowComponent : public Component {
|
|||
this->protocols_[protocol->get_protocol_id()] = protocol;
|
||||
}
|
||||
|
||||
esp_err_t add_peer(uint64_t addr);
|
||||
esp_err_t del_peer(uint64_t addr);
|
||||
esp_err_t add_peer(Peer peer);
|
||||
esp_err_t del_peer(Peer peer);
|
||||
|
||||
bool send_queue_empty() { return uxQueueMessagesWaiting(this->send_queue_) == 0; }
|
||||
bool send_queue_full() { return uxQueueSpacesAvailable(this->send_queue_) == 0; }
|
||||
|
@ -255,7 +326,7 @@ class ESPNowComponent : public Component {
|
|||
|
||||
template<typename... Ts> class SendAction : public Action<Ts...>, public Parented<ESPNowComponent> {
|
||||
public:
|
||||
template<typename V> void set_mac(V mac) { this->mac_ = mac; }
|
||||
template<typename V> void set_peer(V peer) { this->peer_ = peer; }
|
||||
template<typename V> void set_command(V command) { this->command_ = command; }
|
||||
|
||||
void set_data_template(std::function<std::vector<uint8_t>(Ts...)> func) {
|
||||
|
@ -265,7 +336,7 @@ template<typename... Ts> class SendAction : public Action<Ts...>, public Parente
|
|||
void set_data_static(const std::vector<uint8_t> &data) { this->data_static_ = data; }
|
||||
|
||||
void play(Ts... x) override {
|
||||
uint64_t mac = this->mac_.value(x...);
|
||||
Peer peer = this->peer_.value(x...);
|
||||
uint8_t command = 0;
|
||||
if (this->command_.has_value()) {
|
||||
command = this->mac_.value(x...);
|
||||
|
@ -274,12 +345,12 @@ template<typename... Ts> class SendAction : public Action<Ts...>, public Parente
|
|||
if (this->dynamic_) {
|
||||
this->data_static_ = this->data_func_(x...);
|
||||
}
|
||||
this->parent_->get_default_protocol()->send(mac, this->data_static_.data(), this->data_static_.size(), command);
|
||||
this->parent_->get_default_protocol()->send(peer, this->data_static_.data(), this->data_static_.size(), command);
|
||||
}
|
||||
|
||||
protected:
|
||||
TemplatableValue<uint8_t, Ts...> command_{};
|
||||
TemplatableValue<uint64_t, Ts...> mac_{};
|
||||
TemplatableValue<Peer, Ts...> peer_{};
|
||||
bool dynamic_{false};
|
||||
std::function<std::vector<uint8_t>(Ts...)> data_func_{};
|
||||
std::vector<uint8_t> data_static_{};
|
||||
|
@ -287,26 +358,26 @@ template<typename... Ts> class SendAction : public Action<Ts...>, public Parente
|
|||
|
||||
template<typename... Ts> class NewPeerAction : public Action<Ts...>, public Parented<ESPNowComponent> {
|
||||
public:
|
||||
template<typename V> void set_mac(V mac) { this->mac_ = mac; }
|
||||
template<typename V> void set_peer(V peer) { this->peer_ = peer; }
|
||||
void play(Ts... x) override {
|
||||
auto mac = this->mac_.value(x...);
|
||||
parent_->add_peer(mac);
|
||||
auto peer = this->peer_.value(x...);
|
||||
parent_->add_peer(peer);
|
||||
}
|
||||
|
||||
protected:
|
||||
TemplatableValue<uint64_t, Ts...> mac_{};
|
||||
TemplatableValue<Peer, Ts...> mac_{};
|
||||
};
|
||||
|
||||
template<typename... Ts> class DelPeerAction : public Action<Ts...>, public Parented<ESPNowComponent> {
|
||||
public:
|
||||
template<typename V> void set_mac(V mac) { this->mac_ = mac; }
|
||||
template<typename V> void set_peer(V mac) { this->peer_ = peer; }
|
||||
void play(Ts... x) override {
|
||||
auto mac = this->mac_.value(x...);
|
||||
auto peer = this->peer_.value(x...);
|
||||
parent_->del_peer(mac);
|
||||
}
|
||||
|
||||
protected:
|
||||
TemplatableValue<uint64_t, Ts...> mac_{};
|
||||
TemplatableValue<Peer, Ts...> peer_{};
|
||||
};
|
||||
|
||||
class ESPNowSentTrigger : public Trigger<const ESPNowPacket, bool> {
|
||||
|
|
|
@ -42,4 +42,4 @@ espnow:
|
|||
interval:
|
||||
- interval: 10sec
|
||||
then:
|
||||
- espnow.send: "hallo everyone"
|
||||
- espnow.broatcast: "hallo everyone"
|
||||
|
|
Loading…
Reference in a new issue