mirror of
https://github.com/esphome/esphome.git
synced 2025-02-01 02:31:00 +00:00
implement set channel possiblity
remove peer_id over the use of globals.
This commit is contained in:
parent
7534e39cc4
commit
3250125e21
@ -1,5 +1,6 @@
|
||||
from esphome import automation, core
|
||||
import esphome.codegen as cg
|
||||
from esphome.components.globals import GlobalsComponent
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_COMMAND,
|
||||
@ -7,7 +8,9 @@ from esphome.const import (
|
||||
CONF_MAC_ADDRESS,
|
||||
CONF_PAYLOAD,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_WIFI,
|
||||
)
|
||||
import esphome.final_validate as fv
|
||||
|
||||
CODEOWNERS = ["@nielsnl68", "@jesserockz"]
|
||||
|
||||
@ -18,7 +21,7 @@ ESPNowProtocol = espnow_ns.class_("ESPNowProtocol")
|
||||
ESPNowListener = espnow_ns.class_("ESPNowListener")
|
||||
|
||||
ESPNowPacket = espnow_ns.class_("ESPNowPacket")
|
||||
ESPNowPeer = cg.uint64
|
||||
ESPNowPeer = GlobalsComponent
|
||||
|
||||
ESPNowPacketConst = ESPNowPacket.operator("const")
|
||||
|
||||
@ -41,7 +44,7 @@ SendAction = espnow_ns.class_("SendAction", automation.Action)
|
||||
NewPeerAction = espnow_ns.class_("NewPeerAction", automation.Action)
|
||||
DelPeerAction = espnow_ns.class_("DelPeerAction", automation.Action)
|
||||
SetKeeperAction = espnow_ns.class_("SetKeeperAction", automation.Action)
|
||||
SetStaticPeerAction = espnow_ns.class_("SetStaticPeerAction", automation.Action)
|
||||
SetChannelAction = espnow_ns.class_("SetChannelAction", automation.Action)
|
||||
|
||||
CONF_AUTO_ADD_PEER = "auto_add_peer"
|
||||
CONF_CONFORMATION_TIMEOUT = "conformation_timeout"
|
||||
@ -59,6 +62,7 @@ CONF_WIFI_CHANNEL = "wifi_channel"
|
||||
CONF_PROTOCOL_MODE = "protocol_mode"
|
||||
|
||||
validate_command = cv.Range(min=1, max=250)
|
||||
validate_channel = cv.int_range(1, 14)
|
||||
|
||||
ESPNowProtocolMode = espnow_ns.enum("ESPNowProtocolMode")
|
||||
ENUM_MODE = {
|
||||
@ -86,9 +90,8 @@ def espnow_hex(mac_address):
|
||||
|
||||
DEFINE_PEER_CONFIG = cv.maybe_simple_value(
|
||||
{
|
||||
cv.Optional(CONF_PEER_ID): cv.declare_id(ESPNowPeer),
|
||||
cv.Required(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.Optional(CONF_WIFI_CHANNEL): cv.int_range(0, 14),
|
||||
cv.Optional(CONF_WIFI_CHANNEL): validate_channel,
|
||||
},
|
||||
key=CONF_MAC_ADDRESS,
|
||||
)
|
||||
@ -97,7 +100,7 @@ DEFINE_PEER_CONFIG = cv.maybe_simple_value(
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ESPNowComponent),
|
||||
cv.Optional(CONF_WIFI_CHANNEL): cv.int_range(0, 14),
|
||||
cv.Optional(CONF_WIFI_CHANNEL): validate_channel,
|
||||
cv.Optional(CONF_AUTO_ADD_PEER, default=False): cv.boolean,
|
||||
cv.Optional(CONF_USE_SENT_CHECK, default=True): cv.boolean,
|
||||
cv.Optional(
|
||||
@ -211,6 +214,25 @@ async def register_protocol(var, config):
|
||||
cg.add(var.set_protocol_mode(config[CONF_PROTOCOL_MODE]))
|
||||
|
||||
|
||||
def _final_validate(config):
|
||||
full_config = fv.full_config.get()
|
||||
if CONF_WIFI_CHANNEL in config and CONF_WIFI in full_config:
|
||||
raise cv.Invalid(
|
||||
f"When you have {CONF_WIFI} configured, You can not set the {CONF_WIFI_CHANNEL} variable."
|
||||
)
|
||||
if CONF_WIFI_CHANNEL not in config and CONF_WIFI not in full_config:
|
||||
raise cv.Invalid(
|
||||
f"When you don't use the {CONF_WIFI} component, You need to set the {CONF_WIFI_CHANNEL} variable."
|
||||
)
|
||||
return config
|
||||
|
||||
|
||||
FINAL_VALIDATE_SCHEMA = _final_validate
|
||||
|
||||
|
||||
# ========================================== A C T I O N S ================================================
|
||||
|
||||
|
||||
def validate_peer(value):
|
||||
if isinstance(value, cv.Lambda):
|
||||
return cv.returning_lambda(value)
|
||||
@ -282,7 +304,7 @@ async def send_action(config, action_id, template_arg, args):
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(ESPNowComponent),
|
||||
cv.Required(CONF_MAC_ADDRESS): validate_peer,
|
||||
cv.Optional(CONF_WIFI_CHANNEL): cv.int_range(0, 14),
|
||||
cv.Optional(CONF_WIFI_CHANNEL): cv.templatable(validate_channel),
|
||||
},
|
||||
key=CONF_MAC_ADDRESS,
|
||||
),
|
||||
@ -298,26 +320,32 @@ async def send_action(config, action_id, template_arg, args):
|
||||
key=CONF_MAC_ADDRESS,
|
||||
),
|
||||
)
|
||||
@automation.register_action(
|
||||
"espnow.static.peer",
|
||||
SetStaticPeerAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(ESPNowComponent),
|
||||
cv.Required(CONF_PEER_ID): cv.use_id(ESPNowPeer),
|
||||
cv.Required(CONF_MAC_ADDRESS): validate_peer,
|
||||
}
|
||||
),
|
||||
)
|
||||
async def peer_action(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
await cg.register_parented(var, config[CONF_ID])
|
||||
if peer_id := config.get(CONF_PEER_ID):
|
||||
peer = await cg.get_variable(peer_id)
|
||||
cg.add(var.set_peer_id(peer))
|
||||
if CONF_WIFI_CHANNEL in config:
|
||||
cg.add(var.set_wifi_channel(config[CONF_WIFI_CHANNEL]))
|
||||
template_ = await cg.templatable(config[CONF_WIFI_CHANNEL], args, cg.uint8)
|
||||
cg.add(var.set_wifi_channel(template_))
|
||||
|
||||
await register_peer(var, config, args)
|
||||
|
||||
return var
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"espnow.channel.set",
|
||||
SetChannelAction,
|
||||
cv.maybe_simple_value(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(ESPNowComponent),
|
||||
cv.Required(CONF_WIFI_CHANNEL): cv.templatable(validate_channel),
|
||||
},
|
||||
key=CONF_WIFI_CHANNEL,
|
||||
),
|
||||
)
|
||||
async def channel_action(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
await cg.register_parented(var, config[CONF_ID])
|
||||
template_ = await cg.templatable(config[CONF_WIFI_CHANNEL], args, cg.uint8)
|
||||
cg.add(var.set_channel(template_))
|
||||
return var
|
||||
|
@ -266,8 +266,8 @@ void ESPNowComponent::set_wifi_channel(uint8_t channel) {
|
||||
ESPNowPacket packet(ESPNOW_MASS_SEND_ADDR, &channel, 1, ESPNOW_MAIN_PROTOCOL_ID, 251);
|
||||
this->send(packet);
|
||||
ESP_LOGD(TAG, "Wifi Channel is changed from %d to %d.", this->wifi_channel_, channel);
|
||||
this->wifi_channel_ = channel;
|
||||
}
|
||||
this->wifi_channel_ = channel;
|
||||
}
|
||||
|
||||
esp_err_t ESPNowComponent::add_peer(uint64_t peer, int8_t channel) {
|
||||
@ -276,6 +276,11 @@ esp_err_t ESPNowComponent::add_peer(uint64_t peer, int8_t channel) {
|
||||
esp_now_peer_info_t peer_info = {};
|
||||
|
||||
if (this->is_ready()) {
|
||||
if (peer == this->own_peer_address_) {
|
||||
ESP_LOGE(TAG, "Tried to peer your self.");
|
||||
this->mark_failed();
|
||||
return ESP_ERR_INVALID_MAC;
|
||||
}
|
||||
if (esp_now_is_peer_exist((uint8_t *) &peer)) {
|
||||
esp_now_get_peer((const uint8_t *) &peer, &peer_info);
|
||||
old_channel = peer_info.channel;
|
||||
@ -444,8 +449,7 @@ void ESPNowComponent::handle_internal_commands(ESPNowPacket packet) {
|
||||
case 251:
|
||||
channel = (int8_t) *packet.get_payload();
|
||||
this->add_peer(packet.peer, channel);
|
||||
ESP_LOGI(TAG, "The channel for peer %s. is changed toCommand not used: %d.", packet.get_peer_code().c_str(),
|
||||
channel);
|
||||
ESP_LOGI(TAG, "The channel for peer %s is changed to: %d.", packet.get_peer_code().c_str(), channel);
|
||||
break;
|
||||
default:
|
||||
ESP_LOGE(TAG, "Invalid internal ESP-NOW packet. Command not used: %d.", packet.get_command());
|
||||
@ -453,7 +457,9 @@ void ESPNowComponent::handle_internal_commands(ESPNowPacket packet) {
|
||||
}
|
||||
|
||||
bool ESPNowComponent::send(ESPNowPacket packet) {
|
||||
if (!this->is_ready()) {
|
||||
if (packet.peer == this->own_peer_address_) {
|
||||
ESP_LOGE(TAG, "Tried to peer your self.");
|
||||
} else if (!this->is_ready()) {
|
||||
ESP_LOGE(TAG, "Cannot send espnow packet, espnow is not setup yet.");
|
||||
} else if (this->is_failed()) {
|
||||
ESP_LOGE(TAG, "Cannot send espnow packet, espnow failed to setup");
|
||||
@ -482,7 +488,7 @@ bool ESPNowComponent::send(ESPNowPacket packet) {
|
||||
this->call_on_sent_(packet, err == ESP_OK);
|
||||
return true;
|
||||
}
|
||||
|
||||
this->mark_failed();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -518,7 +524,7 @@ bool ESPNowProtocol::send(uint64_t peer, const uint8_t *data, uint8_t len, uint8
|
||||
return this->parent_->send(packet);
|
||||
}
|
||||
|
||||
const char *const ChangeChannel::TAG = "espnow.changechannel";
|
||||
const char *const SetChannel::TAG = "espnow.changechannel";
|
||||
|
||||
} // namespace espnow
|
||||
} // namespace esphome
|
||||
|
@ -340,33 +340,18 @@ template<typename... Ts> class DelPeerAction : public Action<Ts...>, public Pare
|
||||
}
|
||||
};
|
||||
|
||||
template<typename... Ts> class SetStaticPeerAction : public Action<Ts...>, public Parented<ESPNowComponent> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint64_t, mac_address);
|
||||
void set_peer_id(uint64_t &peer_id) { this->peer_id_ = &peer_id; }
|
||||
void play(Ts... x) override {
|
||||
uint64_t mac_address = this->mac_address_.value(x...);
|
||||
*(this->peer_id_) = mac_address;
|
||||
if (mac_address != 0)
|
||||
parent_->add_peer(mac_address);
|
||||
}
|
||||
|
||||
protected:
|
||||
uint64_t *peer_id_;
|
||||
};
|
||||
|
||||
class ChangeChannel {
|
||||
class SetChannel {
|
||||
public:
|
||||
// could be made inline with C++17
|
||||
static const char *const TAG;
|
||||
};
|
||||
|
||||
template<typename... Ts> class ChangeChannelAction : public Action<Ts...>, public Parented<ESPNowComponent> {
|
||||
template<typename... Ts> class SetChannelAction : public Action<Ts...>, public Parented<ESPNowComponent> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(int8_t, channel);
|
||||
void play(Ts... x) override {
|
||||
#ifdef USE_WIFI
|
||||
esph_log_e(ChangeChannel::TAG, "Manual changing the channel is not possible with WIFI enabled.");
|
||||
esph_log_e(SetChannel::TAG, "Manual changing the channel is not possible with WIFI enabled.");
|
||||
#else
|
||||
int8_t value = this->channel_.value(x...);
|
||||
parent_->set_wifi_channel(value);
|
||||
@ -374,7 +359,7 @@ template<typename... Ts> class ChangeChannelAction : public Action<Ts...>, publi
|
||||
}
|
||||
};
|
||||
|
||||
/********************************* triggers **************************************/
|
||||
/********************************* triggers **************************************/
|
||||
class ESPNowSentTrigger : public Trigger<const ESPNowPacket, bool> {
|
||||
public:
|
||||
explicit ESPNowSentTrigger(ESPNowComponent *parent) {
|
||||
|
@ -12,29 +12,19 @@ esp32:
|
||||
|
||||
esphome:
|
||||
name: "${name}"
|
||||
# Friendly names are used where appropriate in Home Assistant
|
||||
friendly_name: "${friendly_name}"
|
||||
# Automatically add the mac address to the name
|
||||
# so you can use a single firmware for all devices
|
||||
name_add_mac_suffix: false
|
||||
|
||||
# This will allow for (future) project identification,
|
||||
# configuration and updates.
|
||||
project:
|
||||
name: LumenSoft.espnow-test
|
||||
version: "1.0"
|
||||
|
||||
# To be able to get logs from the device via serial and api.
|
||||
logger:
|
||||
level: verbose
|
||||
level: debug
|
||||
|
||||
espnow:
|
||||
auto_add_peer: true
|
||||
wifi_channel: 1
|
||||
predefined_peers:
|
||||
- mac_address: 11:22:33:44:55:66
|
||||
- mac_address: E8:6B:EA:23:CD:98
|
||||
on_receive:
|
||||
- logger.log:
|
||||
format: "Received: '%s' from '%s' command: %d RSSI: %d"
|
||||
format: "Received from: %s = '%s' cmd: %d RSSI: %d"
|
||||
args:
|
||||
[
|
||||
packet.get_payload(),
|
||||
@ -43,15 +33,11 @@ espnow:
|
||||
packet.rssi,
|
||||
]
|
||||
|
||||
# this works only when esp_idf v5.1.5+ is being used.
|
||||
on_broadcast:
|
||||
- command: 123
|
||||
then:
|
||||
- logger.log:
|
||||
format: "Broadcast from: '%s' RSSI: %d: %s"
|
||||
args:
|
||||
[
|
||||
packet.get_peer_code().c_str(),
|
||||
packet.rssi,
|
||||
packet.get_payload(),
|
||||
]
|
||||
interval:
|
||||
- interval: 10sec
|
||||
startup_delay: 20sec
|
||||
then:
|
||||
- espnow.send:
|
||||
mac_address: E8:6B:EA:23:CD:98
|
||||
payload: "Test 1."
|
||||
command: 222
|
||||
|
@ -26,23 +26,22 @@ esphome:
|
||||
|
||||
# To be able to get logs from the device via serial and api.
|
||||
logger:
|
||||
level: verbose
|
||||
level: debug
|
||||
|
||||
globals:
|
||||
- id: hub_address
|
||||
type: uint64_t
|
||||
initial_value: "0xE86BEA23CD98"
|
||||
initial_value: "0x0"
|
||||
restore_value: yes
|
||||
|
||||
espnow:
|
||||
auto_add_peer: true
|
||||
wifi_channel: 1
|
||||
predefined_peers:
|
||||
- peer_id: keeper
|
||||
mac_address: E8:6B:EA:23:CD:98
|
||||
|
||||
- mac_address: e8:6b:ea:24:22:04
|
||||
on_receive:
|
||||
- logger.log:
|
||||
format: "Received: '%s' from '%s' command: %d RSSI: %d"
|
||||
format: "Received from: %s = '%s' cmd: %d RSSI: %d"
|
||||
args:
|
||||
[
|
||||
packet.get_payload(),
|
||||
@ -51,52 +50,15 @@ espnow:
|
||||
packet.rssi,
|
||||
]
|
||||
|
||||
on_broadcast:
|
||||
- command: 123
|
||||
then:
|
||||
- logger.log:
|
||||
format: "Broadcast Received from: '%s' RSSI: %d: %s"
|
||||
args:
|
||||
[
|
||||
packet.get_peer_code().c_str(),
|
||||
packet.rssi,
|
||||
packet.get_payload(),
|
||||
]
|
||||
|
||||
interval:
|
||||
- interval: 30sec
|
||||
startup_delay: 20sec
|
||||
startup_delay: 10sec
|
||||
then:
|
||||
- espnow.broadcast:
|
||||
payload: "Broadcast message"
|
||||
command: 123
|
||||
- espnow.channel.set: 5
|
||||
- interval: 5sec
|
||||
startup_delay: 10sec
|
||||
then:
|
||||
- espnow.send:
|
||||
mac_address: keeper
|
||||
payload: "Used static keeper value"
|
||||
command: 222
|
||||
- espnow.send:
|
||||
mac_address: E8:6B:EA:23:CD:98
|
||||
payload: "used fixed mac address"
|
||||
mac_address: e8:6b:ea:24:22:04
|
||||
payload: "Test 2."
|
||||
command: 123
|
||||
- espnow.send:
|
||||
# dynamic peer address
|
||||
mac_address: !lambda return keeper;
|
||||
payload: "use keeper dynamicly "
|
||||
command: 62
|
||||
- espnow.send:
|
||||
mac_address: !lambda return id(hub_address);
|
||||
payload: "Using a global numberic value dynamicly"
|
||||
command: 132
|
||||
|
||||
binary_sensor:
|
||||
- platform: gpio
|
||||
pin: GPIO39
|
||||
name: Button
|
||||
on_click:
|
||||
- espnow.static.peer:
|
||||
peer_id: keeper
|
||||
mac_address: 80:6B:EA:23:CD:87
|
||||
- espnow.peer.add: 80:6B:EA:23:AA:BB
|
||||
- espnow.peer.del: 80:6B:EA:23:AA:BB
|
||||
|
@ -1,5 +1,5 @@
|
||||
globals:
|
||||
- id: hub_address
|
||||
- id: keeper
|
||||
type: uint64_t
|
||||
initial_value: "0xE86BEA23CD98"
|
||||
restore_value: yes
|
||||
@ -8,8 +8,7 @@ espnow:
|
||||
auto_add_peer: true
|
||||
predefined_peers:
|
||||
- FF:FF:FF:FF:FF:FF
|
||||
- peer_id: keeper
|
||||
mac_address: 11:22:33:44:55:66
|
||||
- mac_address: 11:22:33:44:55:66
|
||||
wifi_channel: 2
|
||||
on_receive:
|
||||
- logger.log:
|
||||
@ -40,21 +39,13 @@ interval:
|
||||
- espnow.broadcast:
|
||||
payload: "hallo everyone"
|
||||
command: 123
|
||||
- espnow.send:
|
||||
mac_address: keeper
|
||||
payload: "hallo everyone"
|
||||
command: 230
|
||||
- espnow.send:
|
||||
mac_address: 44:55:66:77:88:33
|
||||
payload: "hallo everyone"
|
||||
command: 230
|
||||
|
||||
- espnow.send:
|
||||
# dynamic peer address
|
||||
mac_address: !lambda return keeper;
|
||||
payload: "use keeper dynamicly "
|
||||
command: 62
|
||||
- espnow.send:
|
||||
mac_address: !lambda return id(hub_address);
|
||||
mac_address: !lambda return id(keeper);
|
||||
payload: "Using a global numberic value dynamicly"
|
||||
command: 132
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user