refactor(driver): harden preset parsing and refresh tooling
This commit is contained in:
16
src/p2p.py
16
src/p2p.py
@@ -1,16 +0,0 @@
|
||||
import asyncio
|
||||
import aioespnow
|
||||
import json
|
||||
|
||||
async def p2p(settings, patterns):
|
||||
e = aioespnow.AIOESPNow() # Returns AIOESPNow enhanced with async support
|
||||
e.active(True)
|
||||
async for mac, msg in e:
|
||||
try:
|
||||
data = json.loads(msg)
|
||||
except:
|
||||
print(f"Failed to load espnow data {msg}")
|
||||
continue
|
||||
|
||||
if "names" not in data or settings.get("name") in data.get("names", []):
|
||||
await settings.set_settings(data.get("settings", {}), patterns, data.get("save", False))
|
||||
@@ -19,8 +19,45 @@ class Preset:
|
||||
def edit(self, data=None):
|
||||
if not data:
|
||||
return False
|
||||
aliases = {
|
||||
"pattern": "p",
|
||||
"colors": "c",
|
||||
"delay": "d",
|
||||
"brightness": "b",
|
||||
"auto": "a",
|
||||
}
|
||||
int_fields = {"d", "b", "n1", "n2", "n3", "n4", "n5", "n6"}
|
||||
allowed_fields = {"p", "c", "d", "b", "a", "n1", "n2", "n3", "n4", "n5", "n6"}
|
||||
for key, value in data.items():
|
||||
setattr(self, key, value)
|
||||
key = aliases.get(key, key)
|
||||
if key not in allowed_fields:
|
||||
continue
|
||||
if key in int_fields:
|
||||
try:
|
||||
parsed = int(value)
|
||||
if key == "b":
|
||||
parsed = max(0, min(255, parsed))
|
||||
elif key in ("d", "n1", "n2", "n3", "n4", "n5", "n6"):
|
||||
parsed = max(0, parsed)
|
||||
setattr(self, key, parsed)
|
||||
except (TypeError, ValueError):
|
||||
continue
|
||||
elif key == "a":
|
||||
if isinstance(value, bool):
|
||||
self.a = value
|
||||
elif isinstance(value, int):
|
||||
self.a = bool(value)
|
||||
elif isinstance(value, str):
|
||||
lowered = value.lower()
|
||||
if lowered in ("true", "1", "yes", "on"):
|
||||
self.a = True
|
||||
elif lowered in ("false", "0", "no", "off"):
|
||||
self.a = False
|
||||
elif key == "c":
|
||||
if isinstance(value, (list, tuple)):
|
||||
self.c = value
|
||||
else:
|
||||
setattr(self, key, value)
|
||||
return True
|
||||
|
||||
@property
|
||||
|
||||
33
src/utils.py
33
src/utils.py
@@ -33,21 +33,26 @@ def convert_and_reorder_colors(colors, settings_or_color_order):
|
||||
|
||||
converted_colors = []
|
||||
for color in colors:
|
||||
# Convert "#RRGGBB" to (R, G, B)
|
||||
if isinstance(color, str) and color.startswith("#"):
|
||||
r = int(color[1:3], 16)
|
||||
g = int(color[3:5], 16)
|
||||
b = int(color[5:7], 16)
|
||||
rgb = (r, g, b)
|
||||
try:
|
||||
# Convert "#RRGGBB" to (R, G, B)
|
||||
if isinstance(color, str) and color.startswith("#") and len(color) == 7:
|
||||
r = int(color[1:3], 16)
|
||||
g = int(color[3:5], 16)
|
||||
b = int(color[5:7], 16)
|
||||
rgb = (r, g, b)
|
||||
elif isinstance(color, (list, tuple)) and len(color) == 3:
|
||||
# Already a tuple/list, just coerce and clamp.
|
||||
rgb = tuple(max(0, min(255, int(x))) for x in color)
|
||||
else:
|
||||
# Unknown format: ignore safely.
|
||||
continue
|
||||
|
||||
# Reorder based on device color order
|
||||
reordered = (rgb[channel_order[0]], rgb[channel_order[1]], rgb[channel_order[2]])
|
||||
converted_colors.append(reordered)
|
||||
elif isinstance(color, (list, tuple)) and len(color) == 3:
|
||||
# Already a tuple/list, just reorder (JSON may use string numbers)
|
||||
rgb = tuple(int(x) for x in color)
|
||||
reordered = (rgb[channel_order[0]], rgb[channel_order[1]], rgb[channel_order[2]])
|
||||
converted_colors.append(reordered)
|
||||
else:
|
||||
# Keep as-is if not recognized format
|
||||
converted_colors.append(color)
|
||||
except (TypeError, ValueError, IndexError):
|
||||
# Skip malformed color entries to avoid crashing pattern loops.
|
||||
continue
|
||||
if not converted_colors:
|
||||
converted_colors.append((255, 255, 255))
|
||||
return converted_colors
|
||||
|
||||
Reference in New Issue
Block a user