Linux/Python ESP-NOW library.
- Send and receive ESP-NOW messages to and from a Linux machine and ESP8266/ESP32 devices
- Monitor all ESP-NOW messages
- Supports ESP-NOW v1.0 and v2.0
- v2.0 supports over 1,400 bytes per message!
sudo bash prep.sh wlan1 8
python3 ESPythoNOW.py wlan1
from ESPythoNOW import *
import time
def callback(from_mac, to_mac, msg):
print("ESP-NOW message from %s to %s: %s" % (from_mac, to_mac, msg))
espnow = ESPythoNow(interface="wlan1", callback=callback)
espnow.start()
while True:
msg=b'\x01'
espnow.send("FF:FF:FF:FF:FF:FF", msg)
time.sleep(3)from ESPythoNOW import *
def callback(from_mac, to_mac, msg):
print("ESP-NOW message from %s to %s: %s" % (from_mac, to_mac, msg))
espnow = ESPythoNow(interface="wlan1", accept_all=True, callback=callback)
espnow.start()
input() # Run until enter is pressedespnow = ESPythoNow(interface="wlan1", callback=callback, pmk="0u4hgz7pgct3gnv8", lmk="a3o4csuv2bpvr0wu")Note: Sending encrypted ESP-NOW messages is not currently supported.
-
espnow = ESPythoNow() - Initialize ESPythoNOW
- Arguments
- interface - The only required argument, the wireless interface to use. Must support monitor mode.
- mac - The MAC address to use. Defaults to interface's MAC.
- callback - Function will execute in thread on ESP-NOW message receive.
- accept_broadcast - Accept/Reject ESP-NOW BROADCAST messages. Defaults to True.
- accept_all - Accept/Reject ESP-NOW messages no matter the destination MAC. Defaults to False.
- accept_ack - If enabled, will execute the callback function when remote peer confirms delivery of sent message. Defaults to False.
- block_on_send - If enabled, will block on send() until remote peer confirms delivery or timeout. Defaults to False
- Returns
- ESPythoNow object.
- Arguments
-
espnow.start() - Begin listening for ESP-NOW messages
- Returns
- True/False on listener starting
- Returns
-
espnow.send() - Send ESP-NOW messages to remote peer
- Arguments
- mac - The MAC address of remote ESP-NOW peer.
- msg - The message contents.
- Also supports list of messages
- block - If enabled, will block until remote peer confirms delivery or timeout. Overrides global block_on_send. Defaults to block_on_send.
- Returns
- If not blocking, will always return True.
- If blocking, will return True if message(s) have delivery confirmed by remote peer.
- Arguments
# Get Wizmote data as a dict
def wizmote_callback(from_mac, to_mac, data):
print(from_mac, to_mac, "Wizmote callback handler", data)
espnow = ESPythoNow(interface="wlan1", accept_all=True)
espnow.add_signature(known_profiles["wizmote"], wizmote_callback, data="dict", dedupe=True)
#espnow.add_signature(known_profiles["wizmote"], wizmote_callback, data="json", dedupe=True) # or as json
#espnow.add_signature(known_profiles["wizmote"], wizmote_callback, data="raw", dedupe=False) # or raw bytes
#espnow.add_signature(known_profiles["wizmote"], wizmote_callback, data="hex", dedupe=False) # or hex
espnow.start()# Get Wiz PIR motion sensor data
# Provide a custom profile that can detect/fingerprint ESP-NOW messsages as well as decode them
custom_profile = {
"wiz_motion":{
"name": "wiz motion sensor",
"struct": "<BIBBBBBBBB4s",
"vars": ["type", "sequence", "dt1", "_0", "_1", "_2", "motion", "_3", "_4", "_5", "ccm"],
"dict": {"motion": {0x0b: True, 0x19: True, 0x0a: False, 0x18: False}}, # 0x0b RT Motion | 0x19 LT Motion | 0x0a RT Clear | 0x18 LT Clear
"signature": {"length": 17, "bytes": {0: 0x81, 5: 0x42}}}}
def wiz_motion_callback(from_mac, to_mac, data):
print(from_mac, to_mac, "Wiz Motion callback handler", data)
espnow = ESPythoNow(interface="wlan1", accept_all=True)
espnow.add_signature(custom_profile["wiz_motion"], wiz_motion_callback, data="dict", dedupe=True)
espnow.start()-
Interface must support monitor mode
-
Any "local" MAC address is supported
- Only actual local MAC will provide delivery confirmation
-
Supports receiving encrypted messages, does not support sending yet
-
This is a work in progress