mirror of
https://github.com/esphome/esphome.git
synced 2024-11-28 09:44:12 +01:00
Add command filters to the triggers
This commit is contained in:
parent
c83b68460c
commit
7931a307b4
3 changed files with 55 additions and 18 deletions
|
@ -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_TRIGGER_ID
|
||||
from esphome.const import CONF_COMMAND, CONF_DATA, CONF_ID, CONF_TRIGGER_ID
|
||||
from esphome.core import CORE
|
||||
|
||||
CODEOWNERS = ["@nielsnl68", "@jesserockz"]
|
||||
|
@ -66,16 +66,19 @@ CONFIG_SCHEMA = cv.Schema(
|
|||
cv.Optional(CONF_ON_RECEIVE): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ESPNowReceiveTrigger),
|
||||
cv.Optional(CONF_COMMAND): cv.Range(min=16, max=255),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_SENT): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ESPNowSentTrigger),
|
||||
cv.Optional(CONF_COMMAND): cv.Range(min=16, max=255),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_NEW_PEER): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ESPNowNewPeerTrigger),
|
||||
cv.Optional(CONF_COMMAND): cv.Range(min=16, max=255),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_PEERS): cv.ensure_list(cv.mac_address),
|
||||
|
@ -101,6 +104,8 @@ async def to_code(config):
|
|||
|
||||
for conf in config.get(CONF_ON_SENT, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
if CONF_COMMAND in conf:
|
||||
cg.add(trigger.set_command(conf[CONF_COMMAND]))
|
||||
await automation.build_automation(
|
||||
trigger,
|
||||
[(ESPNowPacketConst, "packet"), (bool, "status")],
|
||||
|
@ -109,12 +114,16 @@ async def to_code(config):
|
|||
|
||||
for conf in config.get(CONF_ON_RECEIVE, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
if CONF_COMMAND in conf:
|
||||
cg.add(trigger.set_command(conf[CONF_COMMAND]))
|
||||
await automation.build_automation(
|
||||
trigger, [(ESPNowPacketConst, "packet")], conf
|
||||
)
|
||||
|
||||
for conf in config.get(CONF_ON_NEW_PEER, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
if CONF_COMMAND in conf:
|
||||
cg.add(trigger.set_command(conf[CONF_COMMAND]))
|
||||
await automation.build_automation(
|
||||
trigger, [(ESPNowPacketConst, "packet")], conf
|
||||
)
|
||||
|
@ -144,6 +153,7 @@ async def register_protocol(var, config):
|
|||
cv.GenerateID(): cv.use_id(ESPNowComponent),
|
||||
cv.Optional(CONF_PEER): cv.templatable(cv.mac_address),
|
||||
cv.Required(CONF_DATA): cv.templatable(validate_raw_data),
|
||||
cv.Optional(CONF_COMMAND): cv.templatable(cv.Range(min=16, max=255)),
|
||||
},
|
||||
key=CONF_DATA,
|
||||
),
|
||||
|
@ -155,6 +165,10 @@ async def send_action(config, action_id, template_arg, args):
|
|||
template_ = await cg.templatable(config[CONF_PEER].as_hex, args, cg.uint64)
|
||||
cg.add(var.set_mac(template_))
|
||||
|
||||
if CONF_COMMAND in config:
|
||||
template_ = await cg.templatable(config[CONF_COMMAND], args, cg.uint8)
|
||||
cg.add(var.set_command(template_))
|
||||
|
||||
data = config.get(CONF_DATA, [])
|
||||
if isinstance(data, bytes):
|
||||
data = list(data)
|
||||
|
@ -178,13 +192,6 @@ async def send_action(config, action_id, template_arg, args):
|
|||
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_PEER].as_hex, args, cg.uint64)
|
||||
cg.add(var.set_mac(template_))
|
||||
return var
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
"espnow.peer.del",
|
||||
DelPeerAction,
|
||||
|
|
|
@ -344,9 +344,10 @@ 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) {
|
||||
bool ESPNowProtocol::send(uint64_t peer, const uint8_t *data, uint8_t len, uint8_t command = 0) {
|
||||
ESPNowPacket packet(peer, data, len, this->get_protocol_component_id()); // NOLINT
|
||||
packet.set_sequents(this->get_next_sequents());
|
||||
packet.set_sequents(this->get_next_sequents(packet.peer, packet.protocol()));
|
||||
packet.set_command(command);
|
||||
return this->parent_->send(packet);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ static const uint64_t ESPNOW_BROADCAST_ADDR = 0xFFFFFFFFFFFF;
|
|||
|
||||
static const uint8_t MAX_ESPNOW_DATA_SIZE = 241;
|
||||
|
||||
static const uint8_t TRANSPORT_HEADER[] = {'N', '0', 'w'};
|
||||
static const uint8_t TRANSPORT_HEADER[3] = {'N', '0', 'w'};
|
||||
static const uint32_t ESPNOW_MAIN_PROTOCOL_ID = 0x447453; // = StD
|
||||
|
||||
static const uint8_t ESPNOW_COMMAND_ACK = 0x06;
|
||||
|
@ -129,7 +129,7 @@ class ESPNowProtocol : public Parented<ESPNowComponent> {
|
|||
virtual void on_new_peer(const ESPNowPacket &packet){};
|
||||
|
||||
virtual uint32_t get_protocol_component_id() = 0;
|
||||
uint8_t get_next_sequents() {
|
||||
uint8_t get_next_sequents(uint64_t peer = 0, uint32_t protocol = 0) {
|
||||
if (this->next_sequents_ == 255) {
|
||||
this->next_sequents_ = 0;
|
||||
} else {
|
||||
|
@ -145,7 +145,7 @@ class ESPNowProtocol : public Parented<ESPNowComponent> {
|
|||
return valid;
|
||||
}
|
||||
|
||||
bool send(uint64_t peer, const uint8_t *data, uint8_t len);
|
||||
bool send(uint64_t peer, const uint8_t *data, uint8_t len, uint8_t command = 0);
|
||||
|
||||
protected:
|
||||
uint8_t next_sequents_{255};
|
||||
|
@ -260,6 +260,8 @@ 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_command(V command) { this->command_ = command; }
|
||||
|
||||
void set_data_template(std::function<ByteBuffer(Ts...)> func) {
|
||||
this->data_func_ = func;
|
||||
this->static_ = false;
|
||||
|
@ -271,6 +273,10 @@ template<typename... Ts> class SendAction : public Action<Ts...>, public Parente
|
|||
|
||||
void play(Ts... x) override {
|
||||
uint64_t mac = this->mac_.value(x...);
|
||||
uint8_t command = 0;
|
||||
if (this->command_.has_value()) {
|
||||
command = this->mac_.value(x...);
|
||||
}
|
||||
|
||||
if (this->static_) {
|
||||
this->parent_->get_default_protocol()->send(mac, this->data_static_.data(), this->data_static_.size());
|
||||
|
@ -281,6 +287,7 @@ template<typename... Ts> class SendAction : public Action<Ts...>, public Parente
|
|||
}
|
||||
|
||||
protected:
|
||||
TemplatableValue<uint8_t, Ts...> command_{};
|
||||
TemplatableValue<uint64_t, Ts...> mac_{};
|
||||
bool static_{false};
|
||||
std::function<ByteBuffer(Ts...)> data_func_{};
|
||||
|
@ -314,24 +321,46 @@ template<typename... Ts> class DelPeerAction : public Action<Ts...>, public Pare
|
|||
class ESPNowSentTrigger : public Trigger<const ESPNowPacket, bool> {
|
||||
public:
|
||||
explicit ESPNowSentTrigger(ESPNowComponent *parent) {
|
||||
parent->get_default_protocol()->add_on_sent_callback(
|
||||
[this](const ESPNowPacket packet, bool status) { this->trigger(packet, status); });
|
||||
parent->get_default_protocol()->add_on_sent_callback([this](const ESPNowPacket packet, bool status) {
|
||||
if ((this->command_ == 0) || this->command_ == packet.get_command()) {
|
||||
this->trigger(packet, status);
|
||||
}
|
||||
});
|
||||
}
|
||||
void set_command(uint8_t command) { this->command_ = command; }
|
||||
|
||||
protected:
|
||||
uint8_t command_{0};
|
||||
};
|
||||
|
||||
class ESPNowReceiveTrigger : public Trigger<const ESPNowPacket> {
|
||||
public:
|
||||
explicit ESPNowReceiveTrigger(ESPNowComponent *parent) {
|
||||
parent->get_default_protocol()->add_on_receive_callback(
|
||||
[this](const ESPNowPacket packet) { this->trigger(packet); });
|
||||
parent->get_default_protocol()->add_on_receive_callback([this](const ESPNowPacket packet) {
|
||||
if ((this->command_ == 0) || this->command_ == packet.get_command()) {
|
||||
this->trigger(packet);
|
||||
}
|
||||
});
|
||||
}
|
||||
void set_command(uint8_t command) { this->command_ = command; }
|
||||
|
||||
protected:
|
||||
uint8_t command_{0};
|
||||
};
|
||||
|
||||
class ESPNowNewPeerTrigger : public Trigger<const ESPNowPacket> {
|
||||
public:
|
||||
explicit ESPNowNewPeerTrigger(ESPNowComponent *parent) {
|
||||
parent->get_default_protocol()->add_on_peer_callback([this](const ESPNowPacket packet) { this->trigger(packet); });
|
||||
parent->get_default_protocol()->add_on_peer_callback([this](const ESPNowPacket packet) {
|
||||
if ((this->command_ == 0) || this->command_ == packet.get_command()) {
|
||||
this->trigger(packet);
|
||||
}
|
||||
});
|
||||
}
|
||||
void set_command(uint8_t command) { this->command_ = command; }
|
||||
|
||||
protected:
|
||||
uint8_t command_{0};
|
||||
};
|
||||
|
||||
} // namespace espnow
|
||||
|
|
Loading…
Reference in a new issue