ESPNow 通信组件
ESPNow 组件让 ESPHome 能够以一种简单且不受限制的方式与 ESP32 设备进行通信。 它使你能够通过乐鑫(Espressif)的 ESP-NOW 协议与其他 ESP32 设备交互,参见 文档。 它可以与数据包传输组件一起使用来共享 传感器数据;参见ESP-NOW 数据包传输平台。
# Example configuration entryespnow:- channel (Optional, int): ESP-NOW 通信用于发送/接收数据包所使用的 Wi-Fi 信道。 当使用 Wi-Fi 时不能设置,因为 ESP-NOW 会使用与 Wi-Fi 网络相同的信道。
- auto_add_peer (Optional, boolean): 设置为
true时,ESP-NOW 组件会自动将任何新接入的 设备添加为对等设备(peer)。参见下面的对等设备。默认为false。 - enable_on_boot (Optional, boolean): 在启动时启用 ESP-NOW 组件。默认为
true。 - max_payload_size (Optional, int): 此设备在一帧中可以发送和接收的最大载荷(以字节为单位)。
大于
250的值使用 ESP-NOW v2 帧(最大1470字节),仅适用于同样支持它们的对等设备,并且 会为数据包缓冲区保留成比例地更多的 RAM。这仅设置此设备缓冲区的大小;协议版本 本身会与每个对等设备自动协商。默认为250。 - peers (Optional, list of MAC Address): 此设备允许与其通信的设备 MAC 地址列表。参见下面的对等设备。
自动化:
- on_receive (Optional, Automation): 从已注册的对等设备收到定向(非广播)数据包时执行的自动化。可以指定多次。参见
on_receive。 - on_unknown_peer (Optional, Automation): 从未注册为对等设备的设备收到数据包时执行的自动化。参见
on_unknown_peer。 - on_broadcast (Optional, Automation): 收到广播数据包时执行的自动化。
可以指定多次。参见
on_broadcast。
所有三个触发器(on_receive、on_unknown_peer 和 on_broadcast)都会暴露描述所收到数据包的相同的三个 lambda 变量:
- info (API 参考:espnow::ESPNowRecvInfo): 关于所收到
数据包的信息。最有用的成员是:
info.src_addr—uint8_t[6]数据包的源 MAC 地址。info.des_addr—uint8_t[6]目标 MAC 地址(对于广播为FF:FF:FF:FF:FF:FF)。info.rx_ctrl— 指向 Wi-Fiwifi_pkt_rx_ctrl_t结构的指针,包含底层接收细节,例如info.rx_ctrl->rssi(信号强度,单位为 dBm)。
- data: 指向所接收载荷的
const uint8_t *指针。 - size: 给出载荷长度(以字节为单位)的
uint16_t。
这些变量仅在自动化的同步部分执行期间有效。如果自动化
包含任何异步操作(例如 delay),到自动化恢复执行时,底层内存可能已被回收;
如果之后还需要这些值,请先将其复制到你自己的缓冲区中。
espnow: on_receive: - lambda: |- char des_mac[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; char src_mac[MAC_ADDRESS_PRETTY_BUFFER_SIZE]; char hex[256]; ESP_LOGD("espnow", "Received from %s to %s: %s RSSI: %ddBm", format_mac_addr_upper(info.src_addr, src_mac), format_mac_addr_upper(info.des_addr, des_mac), format_hex_pretty_to(hex, data, size), info.rx_ctrl->rssi);on_receive
Section titled “on_receive”当从内部对等设备列表中注册的对等设备收到定向(非广播)数据包时,将触发此自动化。广播数据包会分发到 on_broadcast,而未注册对等设备的数据包会分发到 on_unknown_peer。
可以配置多个 on_receive 自动化;每个都可以选择性地按源地址进行过滤。它们会按照声明的顺序进行评估。
- address (Optional, MAC Address): 仅当数据包的源地址匹配时才触发此触发器。如果未设置, 则任何源地址都会触发。
espnow: peers: - 11:22:33:44:55:66 on_receive: # Fires for any registered peer - lambda: |- ESP_LOGD("espnow", "Got %u bytes", size); # Fires only for packets from this specific peer - address: 11:22:33:44:55:66 then: - logger.log: "Message from the kitchen sensor"on_unknown_peer
Section titled “on_unknown_peer”当从 MAC 地址不在已注册对等设备列表中的设备收到数据包时,将触发此自动化。它让配置有机会检查数据包并决定是否将发送者注册为对等设备(通常通过调用 espnow.peer.add 操作)。如果在触发器执行期间添加了对等设备,则在处理下一个数据包之前,同一个数据包会被传递给 on_receive(或 on_broadcast)。
如果未配置 on_unknown_peer 自动化,则除非 auto_add_peer 设置为 true,否则该数据包会被静默丢弃;当 auto_add_peer 为 true 时,发送者会被添加到对等设备列表,并且该数据包会按情况传递给 on_receive 或 on_broadcast。只允许配置一个 on_unknown_peer 自动化,并且它不接受 address 过滤器。
espnow: on_unknown_peer: then: # Accept the new peer only if the payload starts with a known magic byte. - if: condition: lambda: "return size >= 1 && data[0] == 0x42;" then: - espnow.peer.add: address: !lambda |- return {info.src_addr[0], info.src_addr[1], info.src_addr[2], info.src_addr[3], info.src_addr[4], info.src_addr[5]};on_broadcast
Section titled “on_broadcast”当从已注册的对等设备收到发送到广播地址(FF:FF:FF:FF:FF:FF)的数据包时,将触发此自动化。来自未注册为对等设备的设备的广播会首先被分发到 on_unknown_peer;一旦该对等设备被添加,来自它的广播就会到达此触发器。
可以配置多个 on_broadcast 自动化;每个都可以选择性地按源地址进行过滤。
- address (Optional, MAC Address): 仅当数据包的源地址匹配时才触发此触发器。如果未设置, 则任何源地址都会触发。
espnow: auto_add_peer: true on_broadcast: - lambda: |- ESP_LOGD("espnow", "Broadcast of %u bytes received, RSSI %ddBm", size, info.rx_ctrl->rssi);espnow.send 操作
Section titled “espnow.send 操作”这是一个通过 ESP-NOW 协议向特定对等设备发送数据包的操作。
on_...: - espnow.send: address: 11:22:33:44:55:66 data: "The big angry wolf awakens" - espnow.send: address: 11:22:33:44:55:66 data: !lambda "return {0x00, 0x00, 0x34, 0x5d};" - espnow.send: address: !lambda "return {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};" data: [0x00, 0x00, 0x34, 0x5d] - espnow.send: address: !lambda "return {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};" data: !lambda "return {0x00, 0x00, 0x34, 0x5d};"- address (Required, MAC Address, templatable): 要发送到的接收设备的 MAC 地址。必须已经注册为对等设备,或者必须将
auto_add_peer设置为true。 - data (Required, string or list of bytes, templatable): 要发送的数据。最大载荷大小为配置的
max_payload_size(默认为 250 字节)。 - wait_for_sent (Optional, boolean): 如果为
true,自动化将等待底层发送操作完成(以及任何on_sent或on_error操作结束),然后再继续执行下一个操作。默认为true。 - continue_on_error (Optional, boolean): 如果设置为
false,当发送失败时,周围的自动化将被中止。当wait_for_sent为false时,不能为false。默认为true。
自动化:
- on_sent (Optional, Automation): 当数据成功发送时执行的自动化(接收方已确认数据包)。
- on_error (Optional, Automation): 当数据无法发送时执行的自动化。
espnow.broadcast 操作
Section titled “espnow.broadcast 操作”这是一个通过 ESP-NOW 协议向同一 Wi-Fi 信道上所有正在侦听 ESP-NOW 广播的设备发送数据包的操作。它等同于使用地址 FF:FF:FF:FF:FF:FF 的 espnow.send。有关何时适合使用广播,请参阅下面的广播。
on_...: - espnow.broadcast: data: "The big angry wolf awakens" - espnow.broadcast: data: !lambda "return {0x00, 0x00, 0x34, 0x5d};" - espnow.broadcast: data: [0x00, 0x00, 0x34, 0x5d]- data (Required, string or list of bytes, templatable): 要发送的数据。最大载荷大小为配置的
max_payload_size(默认为 250 字节)。 - 来自
espnow.send的所有其他选项(wait_for_sent、continue_on_error、on_sent、on_error)也都被接受。
espnow.peer.add 操作
Section titled “espnow.peer.add 操作”这是一个向内部允许的对等设备列表中添加新对等设备的操作。
on_...: - espnow.peer.add: address: 11:22:33:44:55:66 - espnow.peer.add: address: !lambda "return {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};"- address (Required, MAC Address, templatable): 要添加到允许对等设备列表中的对等设备地址。
espnow.peer.delete 操作
Section titled “espnow.peer.delete 操作”这是一个从内部允许的对等设备列表中移除已知对等设备的操作。
on_...: - espnow.peer.delete: address: 11:22:33:44:55:66 - espnow.peer.delete: address: !lambda "return {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};"- address (Required, MAC Address, templatable): 要从允许对等设备列表中移除的对等设备地址。
espnow.set_channel 操作
Section titled “espnow.set_channel 操作”这是一个更改 ESP-NOW 发送和接收所使用 Wi-Fi 信道的操作。当 Wi-Fi 组件启用时它没有效果,因为此时信道由关联的 Wi-Fi 网络决定。
on_...: - espnow.set_channel: channel: 1 - espnow.set_channel: 1- channel (Required, int, templatable): 要切换到的 Wi-Fi 信道。有效值为
1到14;实际允许的最高信道取决于设备所在的国家或地区(例如,美国和大部分欧洲地区允许信道 1-11,许多其他国家允许 1-13,日本允许 1-14)。有关详细信息,请参阅各国 Wi-Fi 信道法规或查阅 Espressif ESP-NOW 文档。两个对等设备必须处于同一信道,ESP-NOW 数据包才能被交换。
对等设备是此设备允许向其发送数据的设备。可以从任何设备接收广播和未加密的单播数据,而无需显式将其添加为对等设备;但是,只有源地址在已注册对等设备列表中的数据包才会被传递给 on_receive 和 on_broadcast 触发器。来自任何其他设备的数据包会首先提供给 on_unknown_peer。
如果 auto_add_peer 设置为 false 且你尚未添加任何对等设备,那么只能发送广播,尝试向非广播地址发送数据时会出错。
将 auto_add_peer 设置为 true 将允许组件自动将任何接入的设备添加为对等设备,并会自动添加任何向其发送过数据的对等设备。
ESP-NOW 协议既支持定向(单播)帧(寻址到特定对等设备),也支持发送到特殊地址 FF:FF:FF:FF:FF:FF 的广播帧。每种方式各有权衡:
广播的优点:
- 单个广播帧可以向任意数量的侦听设备传递相同的数据,而不是每个对等设备重复发送一次。
- 广播帧不会被接收方确认,这意味着与相同长度的定向消息相比,它们使用更少的无线电空中时间,并且永远不会触发重传。
- 发送方和接收方之间无需预先配对,这简化了传感器信标等一对多设计。
- 无需事先知道接收设备的 MAC 地址,这在设备频繁添加或移除时可能是一个优势。
广播的缺点:
- 同一 Wi-Fi 信道上的每个支持 ESP-NOW 的设备都会接收并部分处理每个广播帧,即使它最终会丢弃载荷。这会唤醒这些设备上的无线电和 CPU,并且可以明显增加共享该信道的电池供电节点的功耗。
- 由于没有确认机制,因此没有内置的投递确认;应用程序必须接受偶尔的数据包丢失,或在其之上实现自己的重传/心跳方案。
使用广播没有额外的安全影响:以明文发送的定向 ESP-NOW 数据包可以被范围内任何设备捕获,与广播数据包一样容易,而且 ESPHome 的 espnow 组件没有实现 ESP-NOW 的可选链路层加密。如果你需要加密,请使用 ESP-NOW 数据包传输平台,它会在 espnow 之上叠加 数据包传输 组件的加密,并且在单播和广播上都能同样出色的工作。