fix(espnow): bridge async rx, uplink framing, driver RX handling
Bridge uses async for on AIOESPNow, pack_ws_uplink to Pi, AP channel from settings. Driver applies binary wire and JSON commands on receive. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import asyncio
|
||||
import time
|
||||
|
||||
from microdot import Microdot
|
||||
from microdot.websocket import WebSocketError, with_websocket
|
||||
@@ -8,7 +7,7 @@ import aioespnow
|
||||
import machine
|
||||
import network
|
||||
from settings import Settings
|
||||
|
||||
from espnow_wire import BROADCAST_MAC, pack_ws_uplink
|
||||
|
||||
wdt = machine.WDT(timeout=10000)
|
||||
wdt.feed()
|
||||
@@ -17,9 +16,19 @@ print(settings)
|
||||
|
||||
app = Microdot()
|
||||
|
||||
ch = settings.get("wifi_channel", 6)
|
||||
try:
|
||||
ch = max(1, min(11, int(ch)))
|
||||
except (TypeError, ValueError):
|
||||
ch = 6
|
||||
|
||||
ap_if = network.WLAN(network.AP_IF)
|
||||
ap_if.active(True)
|
||||
ap_if.config(ssid=settings.get("name"), password=settings.get("ap_password"))
|
||||
ap_if.config(
|
||||
ssid=settings.get("name"),
|
||||
password=settings.get("ap_password"),
|
||||
channel=ch,
|
||||
)
|
||||
print(ap_if.ifconfig())
|
||||
|
||||
sta_if = network.WLAN(network.STA_IF)
|
||||
@@ -28,37 +37,47 @@ print(sta_if.config("channel"))
|
||||
|
||||
esp = aioespnow.AIOESPNow()
|
||||
esp.active(True)
|
||||
esp.add_peer(b"\xff\xff\xff\xff\xff\xff")
|
||||
esp.add_peer(BROADCAST_MAC)
|
||||
|
||||
clients = set()
|
||||
|
||||
|
||||
@app.route("/ws")
|
||||
@with_websocket
|
||||
async def ws(request, ws):
|
||||
clients.add(ws)
|
||||
while True:
|
||||
|
||||
try:
|
||||
raw = await ws.receive()
|
||||
except WebSocketError as err:
|
||||
print(err)
|
||||
break
|
||||
if not raw:
|
||||
break
|
||||
try:
|
||||
await esp.asend(b"\xff\xff\xff\xff\xff\xff", raw)
|
||||
print(raw)
|
||||
except Exception as err:
|
||||
print(err)
|
||||
break
|
||||
ws.close()
|
||||
clients.discard(ws)
|
||||
try:
|
||||
while True:
|
||||
try:
|
||||
raw = await ws.receive()
|
||||
except WebSocketError as err:
|
||||
print(err)
|
||||
break
|
||||
if not raw:
|
||||
break
|
||||
try:
|
||||
await esp.asend(BROADCAST_MAC, raw)
|
||||
except Exception as err:
|
||||
print(err)
|
||||
break
|
||||
finally:
|
||||
clients.discard(ws)
|
||||
|
||||
|
||||
async def _espnow_receive_loop():
|
||||
async for host, msg in esp.airecv():
|
||||
print(host, msg)
|
||||
for client in clients:
|
||||
await client.send(msg)
|
||||
async for host, msg in esp:
|
||||
if not host or not msg:
|
||||
continue
|
||||
print("espnow rx", len(msg), "B")
|
||||
frame = pack_ws_uplink(host, msg)
|
||||
dead = []
|
||||
for client in list(clients):
|
||||
try:
|
||||
await client.send(frame)
|
||||
except Exception:
|
||||
dead.append(client)
|
||||
for client in dead:
|
||||
clients.discard(client)
|
||||
|
||||
|
||||
async def _wdt_feed_loop():
|
||||
@@ -66,11 +85,12 @@ async def _wdt_feed_loop():
|
||||
await asyncio.sleep(1)
|
||||
wdt.feed()
|
||||
|
||||
|
||||
async def main():
|
||||
asyncio.create_task(_wdt_feed_loop())
|
||||
asyncio.create_task(_wdt_feed_loop())
|
||||
asyncio.create_task(_espnow_receive_loop())
|
||||
await app.start_server(host="0.0.0.0", port=80)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
asyncio.run(main())
|
||||
|
||||
Submodule led-driver updated: 3e718f7432...1fdb2c9441
Reference in New Issue
Block a user