feat(api): tcp driver registry, identify, preset push delivery

- Track Wi-Fi TCP clients, liveness pings, disconnect broadcast, bind errors via gather\n- Device list/get include connected; POST identify with __identify preset\n- Presets push/send delivery helpers; bump led-driver hello type

Made-with: Cursor
This commit is contained in:
pi
2026-04-06 00:21:57 +12:00
parent e6b5bf2cf1
commit f8eba0ee7e
15 changed files with 1052 additions and 108 deletions

View File

@@ -233,10 +233,10 @@ class Device(Model):
def list(self):
return list(self.keys())
def upsert_wifi_tcp_client(self, device_name, peer_ip, mac):
def upsert_wifi_tcp_client(self, device_name, peer_ip, mac, device_type=None):
"""
Register or update a Wi-Fi client by **MAC** (storage id). Updates **name**
and **address** (peer IP) on each connect.
Register or update a Wi-Fi client by **MAC** (storage id). Updates **name**,
**address** (peer IP), and optionally **type** from the client hello when valid.
"""
mac_hex = normalize_mac(mac)
if not mac_hex:
@@ -247,10 +247,19 @@ class Device(Model):
ip = normalize_address_for_transport(peer_ip, "wifi")
if not ip:
return None
resolved_type = None
if device_type is not None:
try:
resolved_type = validate_device_type(device_type)
except ValueError:
resolved_type = None
if mac_hex in self:
merged = dict(self[mac_hex])
merged["name"] = name
merged["type"] = validate_device_type(merged.get("type"))
if resolved_type is not None:
merged["type"] = resolved_type
else:
merged["type"] = validate_device_type(merged.get("type"))
merged["transport"] = "wifi"
merged["address"] = ip
merged["id"] = mac_hex
@@ -260,7 +269,7 @@ class Device(Model):
self[mac_hex] = {
"id": mac_hex,
"name": name,
"type": "led",
"type": resolved_type or "led",
"transport": "wifi",
"address": ip,
"default_pattern": None,