extend and update the yaml options

This commit is contained in:
NP v/d Spek 2024-10-04 14:20:05 +02:00
parent a1e12bbd23
commit 6396595989
4 changed files with 139 additions and 122 deletions

View file

@ -1,7 +1,7 @@
from esphome import automation
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.const import CONF_DATA, CONF_ID, CONF_MAC_ADDRESS, CONF_TRIGGER_ID
from esphome.const import CONF_DATA, CONF_ID, CONF_TRIGGER_ID
from esphome.core import CORE
CODEOWNERS = ["@nielsnl68", "@jesserockz"]
@ -30,14 +30,17 @@ SendAction = espnow_ns.class_("SendAction", automation.Action)
NewPeerAction = espnow_ns.class_("NewPeerAction", automation.Action)
DelPeerAction = espnow_ns.class_("DelPeerAction", automation.Action)
CONF_AUTO_ADD_PEER = "auto_add_peer"
CONF_CONVORMATION_TIMEOUT = "conformation_timeout"
CONF_ESPNOW = "espnow"
CONF_RETRIES = "retries"
CONF_ON_RECEIVE = "on_receive"
CONF_ON_SENT = "on_sent"
CONF_ON_NEW_PEER = "on_new_peer"
CONF_WIFI_CHANNEL = "wifi_channel"
CONF_PEER = "peer"
CONF_PEERS = "peers"
CONF_AUTO_ADD_PEER = "auto_add_peer"
CONF_USE_SENT_CHECK = "use_sent_check"
CONF_WIFI_CHANNEL = "wifi_channel"
def validate_raw_data(value):
@ -56,6 +59,10 @@ CONFIG_SCHEMA = cv.Schema(
cv.Optional(CONF_WIFI_CHANNEL, default=0): cv.int_range(0, 14),
cv.Optional(CONF_AUTO_ADD_PEER, default=False): cv.boolean,
cv.Optional(CONF_USE_SENT_CHECK, default=True): cv.boolean,
cv.Optional(
CONF_CONVORMATION_TIMEOUT, default="5000ms"
): cv.positive_time_period_milliseconds,
cv.Optional(CONF_RETRIES, default=5): cv.int_range(min=1, max=10),
cv.Optional(CONF_ON_RECEIVE): automation.validate_automation(
{
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ESPNowReceiveTrigger),
@ -89,6 +96,8 @@ async def to_code(config):
cg.add(var.set_wifi_channel(config[CONF_WIFI_CHANNEL]))
cg.add(var.set_auto_add_peer(config[CONF_AUTO_ADD_PEER]))
cg.add(var.set_use_sent_check(config[CONF_USE_SENT_CHECK]))
cg.add(var.set_convermation_timeout(config[CONF_CONVORMATION_TIMEOUT]))
cg.add(var.set_retries(config[CONF_RETRIES]))
for conf in config.get(CONF_ON_SENT, []):
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
@ -133,7 +142,7 @@ async def register_protocol(var, config):
cv.maybe_simple_value(
{
cv.GenerateID(): cv.use_id(ESPNowComponent),
cv.Optional(CONF_MAC_ADDRESS): cv.templatable(cv.mac_address),
cv.Optional(CONF_PEER): cv.templatable(cv.mac_address),
cv.Required(CONF_DATA): cv.templatable(validate_raw_data),
},
key=CONF_DATA,
@ -142,10 +151,8 @@ async def register_protocol(var, config):
async def send_action(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
await cg.register_parented(var, config[CONF_ID])
if CONF_MAC_ADDRESS in config:
template_ = await cg.templatable(
config[CONF_MAC_ADDRESS].as_hex, args, cg.uint64
)
if CONF_PEER in config:
template_ = await cg.templatable(config[CONF_PEER].as_hex, args, cg.uint64)
cg.add(var.set_mac(template_))
data = config.get(CONF_DATA, [])
@ -166,14 +173,14 @@ async def send_action(config, action_id, template_arg, args):
cv.maybe_simple_value(
{
cv.GenerateID(): cv.use_id(ESPNowComponent),
cv.Required(CONF_MAC_ADDRESS): cv.templatable(cv.mac_address),
cv.Required(CONF_PEER): cv.templatable(cv.mac_address),
},
key=CONF_MAC_ADDRESS,
key=CONF_PEER,
),
)
async def new_peer_action(config, action_id, template_arg, args):
var = cg.new_Pvariable(action_id, template_arg)
template_ = await cg.templatable(config[CONF_MAC_ADDRESS].as_hex, args, cg.uint64)
template_ = await cg.templatable(config[CONF_PEER].as_hex, args, cg.uint64)
cg.add(var.set_mac(template_))
return var
@ -184,13 +191,13 @@ async def new_peer_action(config, action_id, template_arg, args):
cv.maybe_simple_value(
{
cv.GenerateID(): cv.use_id(ESPNowComponent),
cv.Required(CONF_MAC_ADDRESS): cv.templatable(cv.mac_address),
cv.Required(CONF_PEER): cv.templatable(cv.mac_address),
},
key=CONF_MAC_ADDRESS,
key=CONF_PEER,
),
)
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_MAC_ADDRESS].as_hex, args, cg.uint64)
template_ = await cg.templatable(config[CONF_PEER].as_hex, args, cg.uint64)
cg.add(var.set_mac(template_))
return var

View file

@ -41,15 +41,21 @@ ESPNowComponent::ESPNowComponent() { ESPNowComponent::static_ = this; } // NOLI
void ESPNowComponent::dump_config() {
ESP_LOGCONFIG(TAG, "esp_now:");
ESP_LOGCONFIG(TAG, " MAC Address: 0x%12llx.", this->own_peer_address_);
ESP_LOGCONFIG(TAG, " Own Peer Address: 0x%12llx.", 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");
ESP_LOGCONFIG(TAG, " Use sent status: %s.", this->use_sent_check_ ? "Yes" : "No");
ESP_LOGCONFIG(TAG, " Conversation timeout: %dms.", this->conformation_timeout_);
ESP_LOGCONFIG(TAG, " Send retries: %d.", this->retries_);
}
void ESPNowComponent::show_packet(const std::string &title, const ESPNowPacket &packet) {
ESP_LOGV(TAG,
"%s packet. Peer: 0x%12llx Header: %c%c%c Protocol: 0x%02x%02x%02x%02x Sequents: %02x Size: %2d Valid: %s",
title.c_str(), packet.peer, packet.content_at(0), packet.content_at(1), packet.content_at(2),
packet.content_at(3), packet.content_at(4), packet.content_at(5), packet.content_at(6), packet.content_at(7),
packet.content_size(), packet.is_valid() ? "Yes" : "No");
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");
}
bool ESPNowComponent::validate_channel_(uint8_t channel) {
@ -64,8 +70,6 @@ bool ESPNowComponent::validate_channel_(uint8_t channel) {
}
void ESPNowComponent::setup() {
ESP_LOGI(TAG, "Setting up ESP-NOW...");
#ifndef USE_WIFI
esp_event_loop_create_default();
@ -103,6 +107,8 @@ void ESPNowComponent::setup() {
return;
}
if (this->use_sent_check_) {
ESP_LOGI(TAG, "send check enabled");
err = esp_now_register_send_cb(ESPNowComponent::on_data_sent);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_now_register_send_cb failed: %s", esp_err_to_name(err));
@ -114,7 +120,7 @@ void ESPNowComponent::setup() {
esp_wifi_get_mac(WIFI_IF_STA, (uint8_t *) &this->own_peer_address_);
for (auto &address : this->peers_) {
ESP_LOGI(TAG, "Add peer 0x%12llx.", address);
ESP_LOGV(TAG, "Add peer '%012llx'.", address);
add_peer(address);
}
@ -135,7 +141,7 @@ void ESPNowComponent::setup() {
void ESPNowComponent::loop() {
if (!this->task_running_) {
xTaskCreate(application_task, "espnow_task", 8192, this, 2, &this->espnow_task_handle_);
xTaskCreate(application_task, "espnow_task", 4096, this, tskIDLE_PRIORITY + 1, nullptr);
this->task_running_ = true;
}
}
@ -167,36 +173,35 @@ esp_err_t ESPNowComponent::del_peer(uint64_t addr) {
ESPNowDefaultProtocol *ESPNowComponent::get_default_protocol() {
if (this->protocols_[ESPNOW_MAIN_PROTOCOL_ID] == nullptr) {
this->default_protocol_ = new ESPNowDefaultProtocol(); // NOLINT
this->register_protocol(this->default_protocol_);
this->register_protocol(new ESPNowDefaultProtocol());
}
return (ESPNowDefaultProtocol *) this->protocols_[ESPNOW_MAIN_PROTOCOL_ID];
}
ESPNowProtocol *ESPNowComponent::get_protocol_component_(uint32_t protocol) {
if (this->protocols_[protocol] == nullptr) {
ESP_LOGE(TAG, "Protocol for '0x%06" PRIx32 "' is not registered", protocol);
ESP_LOGE(TAG, "Protocol for '%06x' is not registered", protocol);
return nullptr;
}
return this->protocols_[protocol];
}
void ESPNowComponent::call_on_receive_(ESPNowPacket packet) {
ESPNowProtocol *protocol = this->get_protocol_component_(packet.protocol());
void ESPNowComponent::call_on_receive_(ESPNowPacket &packet) {
ESPNowProtocol *protocol = this->get_protocol_component_(packet.get_protocol());
if (protocol != nullptr) {
this->defer([protocol, packet]() { protocol->on_receive(packet); });
}
}
void ESPNowComponent::call_on_sent_(ESPNowPacket packet, bool status) {
ESPNowProtocol *protocol = this->get_protocol_component_(packet.protocol());
void ESPNowComponent::call_on_sent_(ESPNowPacket &packet, bool status) {
ESPNowProtocol *protocol = this->get_protocol_component_(packet.get_protocol());
if (protocol != nullptr) {
this->defer([protocol, packet, status]() { protocol->on_sent(packet, status); });
}
}
void ESPNowComponent::call_on_new_peer_(ESPNowPacket packet) {
ESPNowProtocol *protocol = this->get_protocol_component_(packet.protocol());
void ESPNowComponent::call_on_new_peer_(ESPNowPacket &packet) {
ESPNowProtocol *protocol = this->get_protocol_component_(packet.get_protocol());
if (protocol != nullptr) {
this->defer([protocol, packet]() { protocol->on_new_peer(packet); });
}
@ -225,7 +230,7 @@ void ESPNowComponent::on_data_received(const uint8_t *addr, const uint8_t *data,
(wifi_promiscuous_pkt_t *) (data - sizeof(wifi_pkt_rx_ctrl_t) - 39); // = sizeof (espnow_frame_format_t)
rx_ctrl = &promiscuous_pkt->rx_ctrl;
#endif
ESPNowPacket packet((uint64_t) *addr, data, (uint8_t) size); // NOLINT
ESPNowPacket packet(addr, data, (uint8_t) size); // NOLINT
packet.is_broadcast = broadcast;
if (rx_ctrl != nullptr) {
packet.rssi = rx_ctrl->rssi;
@ -243,9 +248,8 @@ void ESPNowComponent::on_data_received(const uint8_t *addr, const uint8_t *data,
}
bool ESPNowComponent::send(ESPNowPacket packet) {
uint8_t *mac = packet.peer_as_bytes();
uint8_t *mac = packet.get_peer();
this->show_packet("Prepare to send", packet);
if (this->is_failed()) {
ESP_LOGE(TAG, "Cannot send espnow packet, espnow failed to setup");
} else if (this->send_queue_full()) {
@ -253,15 +257,15 @@ bool ESPNowComponent::send(ESPNowPacket packet) {
} else if (!esp_now_is_peer_exist(mac)) {
ESP_LOGE(TAG, "Peer not registered: 0x%12llx.", packet.peer);
} else if (!packet.is_valid()) {
ESP_LOGE(TAG, "This Packet is invalid: 0x%012llx (%d.%d)", packet.peer, packet.sequents(), packet.attempts);
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 0x%012llx (%d.%d) into send buffer. Used: %d of %d", packet.peer, packet.sequents(),
ESP_LOGV(TAG, "Placing '%012llx' (%d.%d) into send buffer. Used: %d of %d", packet.peer, 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((uint8_t *) &mac, packet.content_as_bytes(), packet.content_size());
ESP_LOGD(TAG, "Sended 0x%012llx (%d.%d) directly%s.", packet.peer, packet.sequents(), packet.attempts,
esp_err_t err = esp_now_send((uint8_t *) &mac, packet.get_content(), packet.content_size());
ESP_LOGV(TAG, "Sended '%012llx' (%d.%d) directly%s.", packet.peer, packet.get_sequents(), packet.attempts,
(err == ESP_OK) ? "" : " FAILED");
this->call_on_sent_(packet, err == ESP_OK);
@ -275,43 +279,40 @@ void ESPNowComponent::runner() {
ESPNowPacket packet; // NOLINT
for (;;) {
if (xQueueReceive(this->receive_queue_, (void *) &packet, (TickType_t) 1) == pdTRUE) {
uint8_t *mac = packet.peer_as_bytes();
ESP_LOGD(TAG, "Handling received packet from 0x%012llx (%d.%d).", packet.peer, packet.sequents(),
packet.attempts);
uint8_t *mac = packet.get_peer();
if (esp_now_is_peer_exist(mac)) {
this->call_on_receive_(packet);
} else if (this->auto_add_peer_) {
this->add_peer(packet.peer);
this->call_on_receive_(packet);
} else {
if (this->auto_add_peer_) {
this->add_peer(packet.peer);
}
this->call_on_new_peer_(packet);
}
}
if (xQueueReceive(this->send_queue_, (void *) &packet, (TickType_t) 1) == pdTRUE) {
if (packet.attempts > MAX_NUMBER_OF_RETRYS) {
ESP_LOGE(TAG, "Dropped 0x%012llx (%d.%d). To many send retries.", packet.peer, packet.sequents(),
if (packet.attempts > this->retries_) {
ESP_LOGE(TAG, "Dropped '%012llx' (%d.%d). To many retries.", packet.peer, packet.get_sequents(),
packet.attempts);
this->unlock();
continue;
} else if (this->is_locked()) {
if (millis() - packet.timestamp > this->conformation_timeout_) {
ESP_LOGW(TAG, "TimeOut 0x%012llx (%d.%d).", packet.peer, packet.sequents(), packet.attempts);
if (packet.timestamp + this->conformation_timeout_ < millis()) {
ESP_LOGW(TAG, "TimeOut '%012llx' (%d.%d).", packet.peer, packet.get_sequents(), packet.attempts);
this->unlock();
}
} else {
this->lock();
packet.retry();
packet.timestamp = millis();
uint8_t *mac = packet.peer_as_bytes();
uint8_t *mac = packet.get_peer();
esp_err_t err = esp_now_send(mac, packet.content_as_bytes(), packet.content_size());
esp_err_t err = esp_now_send(mac, packet.get_content(), packet.content_size());
if (err == ESP_OK) {
ESP_LOGD(TAG, "Sended 0x%012llx (%d.%d) from buffer. Wait for conformation.", packet.peer, packet.sequents(),
packet.attempts);
ESP_LOGD(TAG, "Sended '%012llx' (%d.%d) from buffer. Wait for conformation.", packet.peer,
packet.get_sequents(), packet.attempts);
} else {
ESP_LOGE(TAG, "Sending 0x%012llx (%d.%d) FAILED. B: %d.", packet.peer, packet.sequents(), packet.attempts,
ESP_LOGE(TAG, "Sending '%012llx' (%d.%d) FAILED. B: %d.", packet.peer, packet.get_sequents(), packet.attempts,
this->send_queue_used());
this->unlock();
}
@ -322,23 +323,19 @@ void ESPNowComponent::runner() {
}
void ESPNowComponent::on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status) {
if ((ESPNowComponent::static_ == nullptr) || !ESPNowComponent::static_->use_sent_check_) {
return;
}
ESPNowPacket packet; // NOLINT
uint64_t mac64 = 0;
memcpy((void *) &mac64, (void *) mac_addr, 6);
uint64_t mac64;
memcpy((void *) &mac64, mac_addr, 6);
if (xQueuePeek(ESPNowComponent::static_->send_queue_, (void *) &packet, 10 / portTICK_PERIOD_MS) == pdTRUE) {
if (packet.peer != mac64) {
ESP_LOGE(TAG, " Invalid mac address. Expected: 0x%012llx (%d.%d) got: 0x%012llx", packet.peer, packet.sequents(),
packet.attempts, mac64);
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);
return;
} else if (status == ESP_OK) {
ESP_LOGV(TAG, "Confirm packet sent 0x%012llx (%d.%d)", packet.peer, packet.sequents(), packet.attempts);
xQueueReceive(ESPNowComponent::static_->send_queue_, (void *) &packet, 10 / portTICK_PERIOD_MS);
} else if (status != ESP_OK) {
ESP_LOGE(TAG, "Sent packet failed for '%012llx' (%d.%d)", packet.peer, packet.get_sequents(), packet.attempts);
} else {
ESP_LOGE(TAG, "Sent packet failed for 0x%012llx (%d.%d)", packet.peer, packet.sequents(), packet.attempts);
ESP_LOGV(TAG, "Confirm packet sent '%012llx' (%d.%d)", packet.peer, 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);
ESPNowComponent::static_->unlock();
@ -349,10 +346,7 @@ void ESPNowComponent::on_data_sent(const uint8_t *mac_addr, esp_now_send_status_
bool ESPNowProtocol::send(uint64_t peer, const uint8_t *data, uint8_t len) {
ESPNowPacket packet(peer, data, len, this->get_protocol_component_id()); // NOLINT
packet.sequents(this->get_next_sequents());
ESP_LOGV(TAG, "Created packet to Send for 0x%12llx (%d.%d) directly.", packet.peer, packet.sequents(),
packet.attempts);
packet.set_sequents(this->get_next_sequents());
return this->parent_->send(packet);
}

View file

@ -6,7 +6,7 @@
#include "esphome/core/component.h"
#include "esphome/core/helpers.h"
#include "esphome/core/bytebuffer.h"
#include "esphome/core/log.h"
#include <esp_now.h>
#include <array>
@ -21,22 +21,19 @@ namespace espnow {
static const uint64_t ESPNOW_BROADCAST_ADDR = 0xFFFFFFFFFFFF;
static const uint8_t ESPNOW_DATA_HEADER = 0x00;
static const uint8_t ESPNOW_DATA_PROTOCOL = 0x03;
static const uint8_t ESPNOW_DATA_PACKET = 0x07;
static const uint8_t ESPNOW_DATA_CONTENT = 0x08;
static const uint8_t MAX_ESPNOW_DATA_SIZE = 241;
static const uint8_t MAX_NUMBER_OF_RETRYS = 5;
static const uint8_t TRANSPORT_HEADER[] = {'N', '0', 'w'};
static const uint32_t ESPNOW_MAIN_PROTOCOL_ID = 0x447453; // = StD
static const uint32_t TRANSPORT_HEADER = 0xC19983;
static const uint32_t ESPNOW_MAIN_PROTOCOL_ID = 0x11CFAF;
static const uint8_t ESPNOW_COMMAND_ACK = 0x06;
static const uint8_t ESPNOW_COMMAND_NAK = 0x15;
static const uint8_t ESPNOW_COMMAND_RESEND = 0x05;
struct ESPNowPacket {
uint64_t peer{0};
uint8_t rssi{0};
uint8_t attempts{0};
int8_t attempts{0};
bool is_broadcast{false};
uint32_t timestamp{0};
uint8_t size{0};
@ -51,46 +48,58 @@ 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) ESPHOME_ALWAYS_INLINE {
inline ESPNowPacket(uint64_t 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;
}
this->set_peer(peer);
this->peer = peer;
this->is_broadcast =
(std::memcmp((const void *) this->peer_as_bytes(), (const void *) &ESPNOW_BROADCAST_ADDR, 6) == 0);
this->protocol(protocol);
this->set_protocol(protocol);
if (command != 0) {
this->set_command(command);
}
this->size = size;
std::memcpy(this->payload_as_bytes(), data, size);
std::memcpy(this->get_payload(), data, size);
}
// Load received packet's.
ESPNowPacket(uint64_t peer, const uint8_t *data, uint8_t size) ESPHOME_ALWAYS_INLINE {
ESPNowPacket(const uint8_t *peer, const uint8_t *data, uint8_t size) ESPHOME_ALWAYS_INLINE {
this->set_peer(peer);
std::memcpy(this->content_as_bytes(), data, size);
std::memcpy(this->get_content(), data, size);
this->size = size - this->prefix_size();
}
inline uint8_t *peer_as_bytes() const { return (uint8_t *) &(this->peer); }
inline void set_peer(uint64_t peer) ESPHOME_ALWAYS_INLINE {
if (peer == 0) {
this->peer = ESPNOW_BROADCAST_ADDR;
} else {
this->peer = peer;
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); }
uint8_t prefix_size() const { return sizeof(this->content.prefix); }
uint8_t content_size() const { return ((*this).prefix_size() + (*this).size); }
uint8_t content_size() const { return (this->prefix_size() + this->size); }
inline uint32_t protocol() const { return this->content.prefix.protocol; }
inline void protocol(uint32_t protocol) ESPHOME_ALWAYS_INLINE { this->content.prefix.protocol = protocol; }
inline uint32_t get_protocol() const { return this->content.prefix.protocol & 0x00FFFFFF; }
inline void set_protocol(uint32_t protocol) {
this->content.prefix.protocol = (this->content.prefix.protocol & 0xFF000000) + (protocol & 0x00FFFFFF);
}
uint8_t sequents() const { return (*this).content.prefix.sequents; }
inline void sequents(uint8_t sequents) ESPHOME_ALWAYS_INLINE { this->content.prefix.sequents = sequents; }
inline uint8_t get_command() const { return this->content.prefix.protocol >> 24; }
inline void set_command(uint32_t command) ESPHOME_ALWAYS_INLINE {
this->content.prefix.protocol = (this->content.prefix.protocol & 0x00FFFFFF) + (command << 24);
}
inline uint8_t *content_as_bytes() const { return (uint8_t *) &(this->content); }
inline uint8_t *payload_as_bytes() const { return (uint8_t *) &(this->content.payload); }
inline uint8_t content_at(uint8_t pos) const {
uint8_t get_sequents() const { return this->content.prefix.sequents; }
inline void set_sequents(uint8_t sequents) ESPHOME_ALWAYS_INLINE { this->content.prefix.sequents = sequents; }
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 {
assert(pos < this->size);
return *(((uint8_t *) &this->content) + pos);
}
@ -98,9 +107,14 @@ struct ESPNowPacket {
inline void retry() ESPHOME_ALWAYS_INLINE { attempts++; }
inline bool is_valid() const {
// bool valid = (memcmp((const void *) this->content_as_bytes(), (const void *) &TRANSPORT_HEADER, 3) == 0);
// valid &= (this->protocol() != 0);
return true; // valid;
bool valid = (memcmp((const void *) this->get_content(), (const void *) &TRANSPORT_HEADER, 3) == 0);
valid &= (this->get_protocol() != 0);
return valid;
}
protected:
static uint32_t protocol_(uint8_t *protocol) {
return (*(protocol + 2) << 0) + (*(protocol + 1) << 8) + (*(protocol + 0) << 16);
}
};
@ -181,6 +195,11 @@ class ESPNowComponent : public Component {
void set_wifi_channel(uint8_t channel) { this->wifi_channel_ = channel; }
void set_auto_add_peer(bool value) { this->auto_add_peer_ = value; }
void set_use_sent_check(bool value) { this->use_sent_check_ = value; }
void set_convermation_timeout(uint32_t timeout) {
this->conformation_timeout_ = timeout;
ESP_LOGD("ESPNOW", "%d", timeout);
}
void set_retries(uint8_t value) { this->retries_ = value; }
void setup() override;
void loop() override;
@ -214,29 +233,27 @@ class ESPNowComponent : public Component {
bool validate_channel_(uint8_t channel);
ESPNowProtocol *get_protocol_component_(uint32_t protocol);
uint64_t own_peer_address_{0};
uint8_t wifi_channel_{0};
uint32_t conformation_timeout_{5000};
uint8_t retries_{5};
bool auto_add_peer_{false};
bool use_sent_check_{true};
bool lock_{false};
void call_on_receive_(ESPNowPacket packet);
void call_on_sent_(ESPNowPacket packet, bool status);
void call_on_new_peer_(ESPNowPacket packet);
void call_on_receive_(ESPNowPacket &packet);
void call_on_sent_(ESPNowPacket &packet, bool status);
void call_on_new_peer_(ESPNowPacket &packet);
QueueHandle_t receive_queue_{};
QueueHandle_t send_queue_{};
std::map<uint32_t, ESPNowProtocol *> protocols_{};
std::vector<uint64_t> peers_{};
uint64_t own_peer_address_{0};
ESPNowDefaultProtocol *default_protocol_{nullptr};
TaskHandle_t espnow_task_handle_{nullptr};
bool task_running_{false};
uint32_t conformation_timeout_{5000};
static ESPNowComponent *static_; // NOLINT
};

View file

@ -38,9 +38,8 @@ espnow:
on_receive:
- logger.log:
format: "Received: %s RSSI: %d"
args: [packet.payload_as_bytes(), packet.rssi]
args: [packet.get_payload(), packet.rssi]
interval:
- interval: 1min
- interval: 10sec
then:
- espnow.send: "hallo everyone"