feat(espnow): broadcast delivery with group-filtered routing
Send presets and select on broadcast with groups; unicast only for per-device settings. V1 select as [preset_id, step?]. Sequence steps use beat counts; manual presets get select each beat, auto only on step change. Bridge downlink router, Pi envelope delivery, and tests. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
43
espnow-sender/src/peer_table.py
Normal file
43
espnow-sender/src/peer_table.py
Normal file
@@ -0,0 +1,43 @@
|
||||
"""LRU table of ESP-NOW peer MACs seen on uplink."""
|
||||
|
||||
from espnow_wire import BROADCAST_MAC
|
||||
|
||||
try:
|
||||
from settings import Settings
|
||||
except ImportError:
|
||||
Settings = None
|
||||
|
||||
|
||||
class PeerTable:
|
||||
def __init__(self, max_peers=20):
|
||||
self._max = max(1, int(max_peers))
|
||||
self._order = []
|
||||
self._names = {}
|
||||
|
||||
def touch(self, mac_bytes, name=None):
|
||||
if not mac_bytes or len(mac_bytes) != 6:
|
||||
return
|
||||
if mac_bytes in self._order:
|
||||
self._order.remove(mac_bytes)
|
||||
elif len(self._order) >= self._max:
|
||||
old = self._order.pop(0)
|
||||
self._names.pop(old, None)
|
||||
self._order.append(mac_bytes)
|
||||
if name:
|
||||
self._names[mac_bytes] = str(name)
|
||||
|
||||
def peers(self):
|
||||
return list(self._order)
|
||||
|
||||
def is_broadcast_mac(self, mac_bytes):
|
||||
return mac_bytes == BROADCAST_MAC
|
||||
|
||||
|
||||
def load_max_peers():
|
||||
if Settings is None:
|
||||
return 20
|
||||
try:
|
||||
s = Settings()
|
||||
return int(s.get("max_peers", 20))
|
||||
except Exception:
|
||||
return 20
|
||||
Reference in New Issue
Block a user