kopia lustrzana https://github.com/micropython/micropython-lib
aioespnow: Add library providing asyncio support for espnow module.
This module provides asyncio support for the espnow module on ESP32 and ESP8266 ports.pull/641/head
rodzic
c113611765
commit
a1b9aa934c
|
@ -0,0 +1,91 @@
|
|||
# `aioespnow`
|
||||
|
||||
A supplementary module which extends the micropython `espnow` module to provide
|
||||
`asyncio` support.
|
||||
|
||||
- Asyncio support is available on all ESP32 targets as well as those ESP8266
|
||||
boards which include the `uasyncio` module (ie. ESP8266 devices with at least
|
||||
2MB flash storage).
|
||||
|
||||
## API reference
|
||||
|
||||
- class `AIOESPNow()`: inherits all the methods of the `ESPNow` class and
|
||||
extends the interface with the following async methods:
|
||||
|
||||
- `async AIOESPNow.arecv()`
|
||||
|
||||
Asyncio support for ESPNow.recv(). Note that this method does not take a
|
||||
timeout value as argument.
|
||||
|
||||
- `async AIOESPNow.airecv()`
|
||||
|
||||
Asyncio support for ESPNow.irecv(). Use this method to reduce memory
|
||||
fragmentation, as it will reuse common storage for each new message
|
||||
received, whereas the `arecv()` method will allocate new memory for every
|
||||
message received.
|
||||
|
||||
- `async AIOESPNow.asend(mac, msg, sync=True)`
|
||||
- `async AIOESPNow.asend(msg)`
|
||||
|
||||
Asyncio support for ESPNow.send().
|
||||
|
||||
- `__aiter__()/async __anext__()`
|
||||
|
||||
AIOESPNow also supports reading incoming messages by asynchronous
|
||||
iteration using `async for`, eg:
|
||||
|
||||
```python
|
||||
e = AIOESPNow()
|
||||
e.active(True)
|
||||
async def recv_till_halt(e):
|
||||
async for mac, msg in e:
|
||||
print(mac, msg)
|
||||
if msg == b'halt':
|
||||
break
|
||||
asyncio.run(recv_till_halt(e))
|
||||
```
|
||||
|
||||
## Example Usage
|
||||
|
||||
A small async server example::
|
||||
|
||||
```python
|
||||
import network
|
||||
import aioespnow
|
||||
import uasyncio as asyncio
|
||||
|
||||
# A WLAN interface must be active to send()/recv()
|
||||
network.WLAN(network.STA_IF).active(True)
|
||||
|
||||
e = aioespnow.AIOESPNow() # Returns AIOESPNow enhanced with async support
|
||||
e.active(True)
|
||||
peer = b'\xbb\xbb\xbb\xbb\xbb\xbb'
|
||||
e.add_peer(peer)
|
||||
|
||||
# Send a periodic ping to a peer
|
||||
async def heartbeat(e, peer, period=30):
|
||||
while True:
|
||||
if not await e.asend(peer, b'ping'):
|
||||
print("Heartbeat: peer not responding:", peer)
|
||||
else:
|
||||
print("Heartbeat: ping", peer)
|
||||
await asyncio.sleep(period)
|
||||
|
||||
# Echo any received messages back to the sender
|
||||
async def echo_server(e):
|
||||
async for mac, msg in e:
|
||||
print("Echo:", msg)
|
||||
try:
|
||||
await e.asend(mac, msg)
|
||||
except OSError as err:
|
||||
if len(err.args) > 1 and err.args[1] == 'ESP_ERR_ESPNOW_NOT_FOUND':
|
||||
e.add_peer(mac)
|
||||
await e.asend(mac, msg)
|
||||
|
||||
async def main(e, peer, timeout, period):
|
||||
asyncio.create_task(heartbeat(e, peer, period))
|
||||
asyncio.create_task(echo_server(e))
|
||||
await asyncio.sleep(timeout)
|
||||
|
||||
asyncio.run(main(e, peer, 120, 10))
|
||||
```
|
|
@ -0,0 +1,31 @@
|
|||
# aioespnow module for MicroPython on ESP32 and ESP8266
|
||||
# MIT license; Copyright (c) 2022 Glenn Moloney @glenn20
|
||||
|
||||
import uasyncio as asyncio
|
||||
import espnow
|
||||
|
||||
|
||||
# Modelled on the uasyncio.Stream class (extmod/stream/stream.py)
|
||||
# NOTE: Relies on internal implementation of uasyncio.core (_io_queue)
|
||||
class AIOESPNow(espnow.ESPNow):
|
||||
# Read one ESPNow message
|
||||
async def arecv(self):
|
||||
yield asyncio.core._io_queue.queue_read(self)
|
||||
return self.recv(0) # type: ignore
|
||||
|
||||
async def airecv(self):
|
||||
yield asyncio.core._io_queue.queue_read(self)
|
||||
return self.irecv(0) # type: ignore
|
||||
|
||||
async def asend(self, mac, msg=None, sync=None):
|
||||
if msg is None:
|
||||
msg, mac = mac, None # If msg is None: swap mac and msg
|
||||
yield asyncio.core._io_queue.queue_write(self)
|
||||
return self.send(mac, msg, sync) # type: ignore
|
||||
|
||||
# "async for" support
|
||||
def __aiter__(self):
|
||||
return self
|
||||
|
||||
async def __anext__(self):
|
||||
return await self.airecv()
|
|
@ -0,0 +1,6 @@
|
|||
metadata(
|
||||
description="Extends the micropython espnow module with methods to support asyncio.",
|
||||
version="0.1",
|
||||
)
|
||||
|
||||
module("aioespnow.py")
|
Ładowanie…
Reference in New Issue