feat(bridge): add wifi/serial bridge runtime and UI
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -7,10 +7,12 @@ from typing import Any, Dict, Optional
|
||||
|
||||
from models.device import Device, normalize_mac # noqa: F401 — re-export for callers
|
||||
from models.group import Group
|
||||
from models.transport import get_current_sender
|
||||
from models.transport import get_current_bridge
|
||||
from util.bridge_envelope import build_groups_envelope
|
||||
from util.espnow_ping import record_ping_rsp
|
||||
from util.espnow_wire import (
|
||||
MSG_ANNOUNCE,
|
||||
MSG_PING_RSP,
|
||||
WIRE_MAGIC,
|
||||
mac_bytes_to_hex,
|
||||
parse_announce,
|
||||
@@ -24,8 +26,11 @@ async def handle_bridge_uplink(peer_mac: bytes, payload: bytes) -> None:
|
||||
if not payload:
|
||||
return
|
||||
if payload[0] == WIRE_MAGIC:
|
||||
if wire_msg_type(payload) == MSG_ANNOUNCE:
|
||||
mt = wire_msg_type(payload)
|
||||
if mt == MSG_ANNOUNCE:
|
||||
await handle_espnow_announce(peer_mac, payload)
|
||||
elif mt == MSG_PING_RSP:
|
||||
record_ping_rsp(peer_mac, payload)
|
||||
return
|
||||
if payload[:1] == b"{":
|
||||
try:
|
||||
@@ -128,17 +133,47 @@ async def push_groups_broadcast() -> bool:
|
||||
return False
|
||||
|
||||
|
||||
async def push_groups_all_espnow_devices() -> Dict[str, Any]:
|
||||
"""Push ``set_groups`` envelopes to every ESP-NOW device in the registry."""
|
||||
devices_model = Device()
|
||||
macs: list[str] = []
|
||||
skipped = 0
|
||||
for did, doc in devices_model.items():
|
||||
if str(doc.get("transport") or "espnow").strip().lower() != "espnow":
|
||||
continue
|
||||
mac = normalize_mac(str(did)) or normalize_mac(str(doc.get("address") or ""))
|
||||
if not mac:
|
||||
skipped += 1
|
||||
continue
|
||||
macs.append(mac)
|
||||
sent = 0
|
||||
failed = 0
|
||||
for mac in macs:
|
||||
if await push_groups_to_mac(mac):
|
||||
sent += 1
|
||||
else:
|
||||
failed += 1
|
||||
ok = bool(macs) and failed == 0
|
||||
return {
|
||||
"ok": ok,
|
||||
"sent": sent,
|
||||
"failed": failed,
|
||||
"skipped": skipped,
|
||||
"total": len(macs),
|
||||
}
|
||||
|
||||
|
||||
async def push_groups_to_mac(mac_hex: str) -> bool:
|
||||
"""Unicast groups envelope to one driver (set_groups true)."""
|
||||
mac = normalize_mac(mac_hex)
|
||||
if not mac:
|
||||
return False
|
||||
gids = groups_for_mac(mac, Group())
|
||||
sender = get_current_sender()
|
||||
if sender is None:
|
||||
bridge = get_current_bridge()
|
||||
if bridge is None:
|
||||
return False
|
||||
envelope = build_groups_envelope(mac, gids)
|
||||
ok = await sender.send(envelope)
|
||||
ok = await bridge.send(envelope)
|
||||
if ok:
|
||||
print(f"[espnow] groups sent mac={mac} groups={gids!r}")
|
||||
return bool(ok)
|
||||
|
||||
Reference in New Issue
Block a user