mirror of
https://github.com/esphome/esphome.git
synced 2025-02-01 10:40:56 +00:00
add option to modify the wifi_channel per peer
This commit is contained in:
parent
f9e86cf93b
commit
4ed30edf3a
@ -88,6 +88,7 @@ DEFINE_PEER_CONFIG = cv.maybe_simple_value(
|
|||||||
{
|
{
|
||||||
cv.Optional(CONF_PEER_ID): cv.declare_id(ESPNowPeer),
|
cv.Optional(CONF_PEER_ID): cv.declare_id(ESPNowPeer),
|
||||||
cv.Required(CONF_MAC_ADDRESS): cv.mac_address,
|
cv.Required(CONF_MAC_ADDRESS): cv.mac_address,
|
||||||
|
cv.Optional(CONF_WIFI_CHANNEL): cv.int_range(0, 14),
|
||||||
},
|
},
|
||||||
key=CONF_MAC_ADDRESS,
|
key=CONF_MAC_ADDRESS,
|
||||||
)
|
)
|
||||||
@ -96,7 +97,7 @@ DEFINE_PEER_CONFIG = cv.maybe_simple_value(
|
|||||||
CONFIG_SCHEMA = cv.Schema(
|
CONFIG_SCHEMA = cv.Schema(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(ESPNowComponent),
|
cv.GenerateID(): cv.declare_id(ESPNowComponent),
|
||||||
cv.Optional(CONF_WIFI_CHANNEL, default=0): cv.int_range(0, 14),
|
cv.Optional(CONF_WIFI_CHANNEL): cv.int_range(0, 14),
|
||||||
cv.Optional(CONF_AUTO_ADD_PEER, default=False): cv.boolean,
|
cv.Optional(CONF_AUTO_ADD_PEER, default=False): cv.boolean,
|
||||||
cv.Optional(CONF_USE_SENT_CHECK, default=True): cv.boolean,
|
cv.Optional(CONF_USE_SENT_CHECK, default=True): cv.boolean,
|
||||||
cv.Optional(
|
cv.Optional(
|
||||||
@ -141,8 +142,9 @@ async def to_code(config):
|
|||||||
cg.add_library("WiFi", None)
|
cg.add_library("WiFi", None)
|
||||||
|
|
||||||
cg.add_define("USE_ESPNOW")
|
cg.add_define("USE_ESPNOW")
|
||||||
|
if CONF_WIFI_CHANNEL in config:
|
||||||
|
cg.add(var.set_wifi_channel(config[CONF_WIFI_CHANNEL]))
|
||||||
|
|
||||||
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_auto_add_peer(config[CONF_AUTO_ADD_PEER]))
|
||||||
cg.add(var.set_use_sent_check(config[CONF_USE_SENT_CHECK]))
|
cg.add(var.set_use_sent_check(config[CONF_USE_SENT_CHECK]))
|
||||||
cg.add(var.set_conformation_timeout(config[CONF_CONFORMATION_TIMEOUT]))
|
cg.add(var.set_conformation_timeout(config[CONF_CONFORMATION_TIMEOUT]))
|
||||||
@ -152,7 +154,11 @@ async def to_code(config):
|
|||||||
mac = espnow_hex(conf.get(CONF_MAC_ADDRESS))
|
mac = espnow_hex(conf.get(CONF_MAC_ADDRESS))
|
||||||
if CONF_PEER_ID in conf:
|
if CONF_PEER_ID in conf:
|
||||||
cg.new_variable(conf[CONF_PEER_ID], mac)
|
cg.new_variable(conf[CONF_PEER_ID], mac)
|
||||||
cg.add(var.add_peer(mac))
|
|
||||||
|
if CONF_WIFI_CHANNEL in conf:
|
||||||
|
cg.add(var.add_peer(mac, conf[CONF_WIFI_CHANNEL]))
|
||||||
|
else:
|
||||||
|
cg.add(var.add_peer(mac))
|
||||||
|
|
||||||
for conf in config.get(CONF_ON_SENT, []):
|
for conf in config.get(CONF_ON_SENT, []):
|
||||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||||
@ -276,6 +282,7 @@ async def send_action(config, action_id, template_arg, args):
|
|||||||
{
|
{
|
||||||
cv.GenerateID(): cv.use_id(ESPNowComponent),
|
cv.GenerateID(): cv.use_id(ESPNowComponent),
|
||||||
cv.Required(CONF_MAC_ADDRESS): validate_peer,
|
cv.Required(CONF_MAC_ADDRESS): validate_peer,
|
||||||
|
cv.Optional(CONF_WIFI_CHANNEL): cv.int_range(0, 14),
|
||||||
},
|
},
|
||||||
key=CONF_MAC_ADDRESS,
|
key=CONF_MAC_ADDRESS,
|
||||||
),
|
),
|
||||||
@ -308,6 +315,8 @@ async def peer_action(config, action_id, template_arg, args):
|
|||||||
if peer_id := config.get(CONF_PEER_ID):
|
if peer_id := config.get(CONF_PEER_ID):
|
||||||
peer = await cg.get_variable(peer_id)
|
peer = await cg.get_variable(peer_id)
|
||||||
cg.add(var.set_peer_id(peer))
|
cg.add(var.set_peer_id(peer))
|
||||||
|
if CONF_WIFI_CHANNEL in config:
|
||||||
|
cg.add(var.set_wifi_channel(config[CONF_WIFI_CHANNEL]))
|
||||||
|
|
||||||
await register_peer(var, config, args)
|
await register_peer(var, config, args)
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ void ESPNowComponent::setup() {
|
|||||||
esp_wifi_get_mac(WIFI_IF_STA, (uint8_t *) &this->own_peer_address_);
|
esp_wifi_get_mac(WIFI_IF_STA, (uint8_t *) &this->own_peer_address_);
|
||||||
|
|
||||||
for (auto id : this->peers_) {
|
for (auto id : this->peers_) {
|
||||||
this->add_peer(id);
|
this->add_peer(id & 0x00FFFFFFFFFFFF, (int8_t) id >> (64 - 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
this->send_queue_ = xQueueCreate(SEND_BUFFER_SIZE, sizeof(ESPNowPacket));
|
this->send_queue_ = xQueueCreate(SEND_BUFFER_SIZE, sizeof(ESPNowPacket));
|
||||||
@ -184,7 +184,12 @@ void ESPNowComponent::espnow_task(void *param) {
|
|||||||
packet.retry();
|
packet.retry();
|
||||||
packet.timestamp = millis();
|
packet.timestamp = millis();
|
||||||
|
|
||||||
esp_err_t err = esp_now_send(packet.get_peer(), packet.get_content(), packet.content_size());
|
esp_err_t err;
|
||||||
|
if (packet.get_peer() == 0) {
|
||||||
|
err = esp_now_send(nullptr, packet.get_content(), packet.content_size());
|
||||||
|
} else {
|
||||||
|
err = esp_now_send(packet.get_peer(), packet.get_content(), packet.content_size());
|
||||||
|
}
|
||||||
|
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
ESP_LOGD(TAG, "Sended '%s' (%d.%d) from buffer. Wait for conformation.", packet.get_peer_code().c_str(),
|
ESP_LOGD(TAG, "Sended '%s' (%d.%d) from buffer. Wait for conformation.", packet.get_peer_code().c_str(),
|
||||||
@ -200,21 +205,32 @@ void ESPNowComponent::espnow_task(void *param) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t ESPNowComponent::add_peer(uint64_t peer) {
|
void ESPNowComponent::set_wifi_channel(uint8_t channel) {
|
||||||
|
if (this->is_ready() && (this->wifi_channel_ == channel)) {
|
||||||
|
ESPNowPacket packet(ESPNOW_MASS_SEND_ADDR, &channel, 1, ESPNOW_MAIN_PROTOCOL_ID, 251);
|
||||||
|
}
|
||||||
|
this->wifi_channel_ = channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t ESPNowComponent::add_peer(uint64_t peer, int8_t channel) {
|
||||||
esp_err_t result = ESP_OK;
|
esp_err_t result = ESP_OK;
|
||||||
|
int8_t old_channel = this->wifi_channel_;
|
||||||
|
esp_now_peer_info_t peer_info = {};
|
||||||
|
|
||||||
if (!this->is_ready()) {
|
if (!this->is_ready()) {
|
||||||
this->peers_.push_back(peer);
|
this->peers_.push_back((peer & 0x00FFFFFFFFFFFF) + (channel << (64 - 8)));
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
if (esp_now_is_peer_exist((uint8_t *) &peer)) {
|
if (esp_now_is_peer_exist((uint8_t *) &peer)) {
|
||||||
|
esp_now_get_peer((const uint8_t *) &peer, &peer_info);
|
||||||
|
old_channel = peer_info.channel;
|
||||||
result = esp_now_del_peer((uint8_t *) &peer);
|
result = esp_now_del_peer((uint8_t *) &peer);
|
||||||
if (result != ESP_OK)
|
if (result != ESP_OK)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_now_peer_info_t peer_info = {};
|
|
||||||
memset(&peer_info, 0, sizeof(esp_now_peer_info_t));
|
memset(&peer_info, 0, sizeof(esp_now_peer_info_t));
|
||||||
peer_info.channel = this->wifi_channel_;
|
peer_info.channel = (channel = -1) ? old_channel : channel;
|
||||||
peer_info.encrypt = false;
|
peer_info.encrypt = false;
|
||||||
memcpy((void *) peer_info.peer_addr, (void *) &peer, 6);
|
memcpy((void *) peer_info.peer_addr, (void *) &peer, 6);
|
||||||
esp_err_t result = esp_now_add_peer(&peer_info);
|
esp_err_t result = esp_now_add_peer(&peer_info);
|
||||||
@ -297,7 +313,12 @@ void ESPNowComponent::call_on_del_peer_(uint64_t peer) {
|
|||||||
|
|
||||||
bool ESPNowComponent::is_paired(uint64_t peer) {
|
bool ESPNowComponent::is_paired(uint64_t peer) {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if (this->pairing_protocol_ != nullptr) {
|
if (peer == ESPNOW_MASS_SEND_ADDR) {
|
||||||
|
return true;
|
||||||
|
} else if (peer == ESPNOW_BROADCAST_ADDR) {
|
||||||
|
this->add_peer(ESPNOW_BROADCAST_ADDR);
|
||||||
|
return true;
|
||||||
|
} else if (this->pairing_protocol_ != nullptr) {
|
||||||
result = this->pairing_protocol_->is_paired(peer);
|
result = this->pairing_protocol_->is_paired(peer);
|
||||||
} else {
|
} else {
|
||||||
result = (esp_now_is_peer_exist((uint8_t *) &peer));
|
result = (esp_now_is_peer_exist((uint8_t *) &peer));
|
||||||
@ -368,7 +389,12 @@ bool ESPNowComponent::send(ESPNowPacket packet) {
|
|||||||
xQueueSendToBack(this->send_queue_, (void *) &packet, 10);
|
xQueueSendToBack(this->send_queue_, (void *) &packet, 10);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
esp_err_t err = esp_now_send(packet.get_peer(), packet.get_content(), packet.content_size());
|
esp_err_t err;
|
||||||
|
if (packet.get_peer() == 0) {
|
||||||
|
err = esp_now_send(nullptr, packet.get_content(), packet.content_size());
|
||||||
|
} else {
|
||||||
|
err = esp_now_send(packet.get_peer(), packet.get_content(), packet.content_size());
|
||||||
|
}
|
||||||
ESP_LOGV(TAG, "Sending to %s (%d.%d) directly%s.", packet.get_peer_code().c_str(), packet.get_sequents(),
|
ESP_LOGV(TAG, "Sending to %s (%d.%d) directly%s.", packet.get_peer_code().c_str(), packet.get_sequents(),
|
||||||
packet.attempts, (err == ESP_OK) ? "" : " FAILED");
|
packet.attempts, (err == ESP_OK) ? "" : " FAILED");
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ namespace esphome {
|
|||||||
namespace espnow {
|
namespace espnow {
|
||||||
|
|
||||||
static const uint64_t ESPNOW_BROADCAST_ADDR = 0xFFFFFFFFFFFF;
|
static const uint64_t ESPNOW_BROADCAST_ADDR = 0xFFFFFFFFFFFF;
|
||||||
|
static const uint64_t ESPNOW_MASS_SEND_ADDR = 0xFFFFFFFFFFFE;
|
||||||
|
|
||||||
static const uint8_t MAX_ESPNOW_DATA_SIZE = 240;
|
static const uint8_t MAX_ESPNOW_DATA_SIZE = 240;
|
||||||
|
|
||||||
@ -68,7 +69,7 @@ struct ESPNowPacket {
|
|||||||
uint8_t command = 0) ESPHOME_ALWAYS_INLINE {
|
uint8_t command = 0) ESPHOME_ALWAYS_INLINE {
|
||||||
if (size > MAX_ESPNOW_DATA_SIZE) {
|
if (size > MAX_ESPNOW_DATA_SIZE) {
|
||||||
ESP_LOGE("ESPNowPacket", "Payload size is to large. It should be less then %d instead it is %d",
|
ESP_LOGE("ESPNowPacket", "Payload size is to large. It should be less then %d instead it is %d",
|
||||||
MAX_ESPNOW_DATA_SIZE, size);
|
MAX_ESPNOW_DATA_SIZE, size); // nolint
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (peer == 0ull) {
|
if (peer == 0ull) {
|
||||||
@ -90,7 +91,7 @@ struct ESPNowPacket {
|
|||||||
inline ESPNowPacket(const uint8_t *peer, const uint8_t *data, uint8_t size) ESPHOME_ALWAYS_INLINE {
|
inline ESPNowPacket(const uint8_t *peer, const uint8_t *data, uint8_t size) ESPHOME_ALWAYS_INLINE {
|
||||||
if (size > MAX_ESPNOW_DATA_SIZE + this->prefix_size()) {
|
if (size > MAX_ESPNOW_DATA_SIZE + this->prefix_size()) {
|
||||||
ESP_LOGE("ESPNowPacket", "Received Payload size is to large. It should be less then %d instead it is %d",
|
ESP_LOGE("ESPNowPacket", "Received Payload size is to large. It should be less then %d instead it is %d",
|
||||||
MAX_ESPNOW_DATA_SIZE + this->prefix_size(), size);
|
MAX_ESPNOW_DATA_SIZE + this->prefix_size(), size); // nolint
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +257,7 @@ class ESPNowComponent : public Component {
|
|||||||
|
|
||||||
float get_setup_priority() const override { return -100; }
|
float get_setup_priority() const override { return -100; }
|
||||||
|
|
||||||
void set_wifi_channel(uint8_t channel) { this->wifi_channel_ = channel; }
|
void set_wifi_channel(uint8_t channel);
|
||||||
void set_auto_add_peer(bool value) { this->auto_add_peer_ = value; }
|
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_use_sent_check(bool value) { this->use_sent_check_ = value; }
|
||||||
void set_conformation_timeout(uint32_t timeout) { this->conformation_timeout_ = timeout; }
|
void set_conformation_timeout(uint32_t timeout) { this->conformation_timeout_ = timeout; }
|
||||||
@ -278,7 +279,7 @@ class ESPNowComponent : public Component {
|
|||||||
protocol->init_protocol();
|
protocol->init_protocol();
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t add_peer(uint64_t peer);
|
esp_err_t add_peer(uint64_t peer, int8_t channel = -1);
|
||||||
esp_err_t del_peer(uint64_t peer);
|
esp_err_t del_peer(uint64_t peer);
|
||||||
|
|
||||||
bool send_queue_empty() { return uxQueueMessagesWaiting(this->send_queue_) == 0; }
|
bool send_queue_empty() { return uxQueueMessagesWaiting(this->send_queue_) == 0; }
|
||||||
@ -343,9 +344,14 @@ template<typename... Ts> class SendAction : public Action<Ts...>, public Parente
|
|||||||
template<typename... Ts> class NewPeerAction : public Action<Ts...>, public Parented<ESPNowComponent> {
|
template<typename... Ts> class NewPeerAction : public Action<Ts...>, public Parented<ESPNowComponent> {
|
||||||
public:
|
public:
|
||||||
TEMPLATABLE_VALUE(uint64_t, mac_address);
|
TEMPLATABLE_VALUE(uint64_t, mac_address);
|
||||||
|
TEMPLATABLE_VALUE(int8_t, wifi_channel);
|
||||||
void play(Ts... x) override {
|
void play(Ts... x) override {
|
||||||
uint64_t mac_address = this->mac_address_.value(x...);
|
uint64_t mac_address = this->mac_address_.value(x...);
|
||||||
parent_->add_peer(mac_address);
|
if (this->wifi_channel_.has_value()) {
|
||||||
|
parent_->add_peer(mac_address);
|
||||||
|
} else {
|
||||||
|
parent_->add_peer(mac_address, this->wifi_channel_.value(x...));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,6 +30,8 @@ logger:
|
|||||||
|
|
||||||
espnow:
|
espnow:
|
||||||
auto_add_peer: true
|
auto_add_peer: true
|
||||||
|
predefined_peers:
|
||||||
|
- mac_address: 11:22:33:44:55:66
|
||||||
on_receive:
|
on_receive:
|
||||||
- logger.log:
|
- logger.log:
|
||||||
format: "Received: '%s' from '%s' command: %d RSSI: %d"
|
format: "Received: '%s' from '%s' command: %d RSSI: %d"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user