Update SPI JSON sender to led-bar format: {"settings":{...}, "save":false} and tooling scripts
This commit is contained in:
@@ -3,9 +3,9 @@
|
|||||||
CLI to send JSON over SPI to the ESP32-C3 SPI slave.
|
CLI to send JSON over SPI to the ESP32-C3 SPI slave.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
./send_json.py --data '{"d":{"t":"b","br":128},"bar":{"pt":"off"}}'
|
./send_json.py --data '{"settings":{"pattern":"on","brightness":128}}'
|
||||||
./send_json.py --file payload.json
|
./send_json.py --file payload.json
|
||||||
./send_json.py --beat --brightness 180 --delay 30 --pattern wave
|
./send_json.py --brightness 180 --delay 30 --pattern wave
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -22,7 +22,12 @@ from spi_master_test import SPIMasterTest # noqa: E402
|
|||||||
|
|
||||||
|
|
||||||
def build_payload_from_args(args: argparse.Namespace) -> dict:
|
def build_payload_from_args(args: argparse.Namespace) -> dict:
|
||||||
"""Build a control payload matching the receiver format from args."""
|
"""Build a control payload matching led-bar's receiver format from args.
|
||||||
|
|
||||||
|
Format:
|
||||||
|
{"settings": { ... }, "save": false}
|
||||||
|
Or raw passthrough if --data/--file is provided.
|
||||||
|
"""
|
||||||
if args.data:
|
if args.data:
|
||||||
try:
|
try:
|
||||||
return json.loads(args.data)
|
return json.loads(args.data)
|
||||||
@@ -38,56 +43,67 @@ def build_payload_from_args(args: argparse.Namespace) -> dict:
|
|||||||
print(f"Failed to read JSON file {args.file}: {exc}")
|
print(f"Failed to read JSON file {args.file}: {exc}")
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
# Build from individual params (beat or update)
|
# Build led-bar settings object
|
||||||
msg_type = "b" if args.beat else "u"
|
settings: dict = {}
|
||||||
defaults = {"t": msg_type}
|
|
||||||
if args.brightness is not None:
|
|
||||||
defaults["br"] = int(args.brightness)
|
|
||||||
if args.delay is not None:
|
|
||||||
defaults["dl"] = int(args.delay)
|
|
||||||
if args.n1 is not None:
|
|
||||||
defaults["n1"] = int(args.n1)
|
|
||||||
if args.n2 is not None:
|
|
||||||
defaults["n2"] = int(args.n2)
|
|
||||||
if args.n3 is not None:
|
|
||||||
defaults["n3"] = int(args.n3)
|
|
||||||
if args.step is not None:
|
|
||||||
defaults["s"] = int(args.step)
|
|
||||||
|
|
||||||
bar = {}
|
|
||||||
if args.pattern:
|
if args.pattern:
|
||||||
bar["pt"] = args.pattern
|
settings["pattern"] = args.pattern
|
||||||
|
if args.brightness is not None:
|
||||||
|
settings["brightness"] = int(args.brightness)
|
||||||
|
if args.delay is not None:
|
||||||
|
settings["delay"] = int(args.delay)
|
||||||
|
|
||||||
|
# Optional numeric params if supported on led-bar side
|
||||||
|
if args.n1 is not None:
|
||||||
|
settings["n1"] = int(args.n1)
|
||||||
|
if args.n2 is not None:
|
||||||
|
settings["n2"] = int(args.n2)
|
||||||
|
if args.n3 is not None:
|
||||||
|
settings["n3"] = int(args.n3)
|
||||||
|
|
||||||
|
payload: dict = {"settings": settings}
|
||||||
|
|
||||||
|
# Optional: step tick control
|
||||||
|
if args.step is not None:
|
||||||
|
payload["step"] = int(args.step)
|
||||||
|
|
||||||
|
# Allow override raw NAME JSON into settings directly if provided
|
||||||
if args.name_value:
|
if args.name_value:
|
||||||
# Allow sending a specific bar (device) override by name
|
|
||||||
# Usage: --name-value mybar '{"br":200,"pt":"off"}'
|
|
||||||
try:
|
try:
|
||||||
name, value = args.name_value
|
name, value = args.name_value
|
||||||
bar = json.loads(value)
|
override = json.loads(value)
|
||||||
return {"d": defaults, name: bar}
|
# Merge override fields into settings
|
||||||
|
if not isinstance(override, dict):
|
||||||
|
raise ValueError("--name-value JSON must be an object")
|
||||||
|
settings.update(override)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
print(f"Invalid --name-value: {exc}")
|
print(f"Invalid --name-value: {exc}")
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
# Default field name could be populated on receiver side via settings.get("name")
|
# Default save=false; caller can include save in --data if desired
|
||||||
# We only send defaults and a generic "bar" override here for convenience.
|
payload.setdefault("save", False)
|
||||||
return {"d": defaults, "bar": bar}
|
|
||||||
|
if not settings and "step" not in payload:
|
||||||
|
print("No settings specified to send.", file=sys.stderr)
|
||||||
|
return {"settings": {}, "save": False}
|
||||||
|
|
||||||
|
return payload
|
||||||
|
|
||||||
|
|
||||||
def parse_args() -> argparse.Namespace:
|
def parse_args() -> argparse.Namespace:
|
||||||
p = argparse.ArgumentParser(description="Send JSON over SPI to ESP32-C3")
|
p = argparse.ArgumentParser(description="Send JSON over SPI to ESP32-C3 (led-bar format)")
|
||||||
src = p.add_mutually_exclusive_group()
|
src = p.add_mutually_exclusive_group()
|
||||||
src.add_argument("--data", help="Raw JSON string to send")
|
src.add_argument("--data", help="Raw JSON string to send (passthrough)")
|
||||||
src.add_argument("--file", help="Path to JSON file to send")
|
src.add_argument("--file", help="Path to JSON file to send (passthrough)")
|
||||||
|
|
||||||
p.add_argument("--beat", action="store_true", help="Send as beat message (t=b)")
|
p.add_argument("--brightness", type=int, help="Brightness")
|
||||||
p.add_argument("--brightness", type=int, help="Brightness (br)")
|
p.add_argument("--delay", type=int, help="Delay (ms)")
|
||||||
p.add_argument("--delay", type=int, help="Delay (dl)")
|
p.add_argument("--pattern", help="Pattern name")
|
||||||
p.add_argument("--pattern", help="Pattern name (pt)")
|
|
||||||
p.add_argument("--n1", type=int, help="n1 parameter")
|
p.add_argument("--n1", type=int, help="n1 parameter")
|
||||||
p.add_argument("--n2", type=int, help="n2 parameter")
|
p.add_argument("--n2", type=int, help="n2 parameter")
|
||||||
p.add_argument("--n3", type=int, help="n3 parameter")
|
p.add_argument("--n3", type=int, help="n3 parameter")
|
||||||
p.add_argument("--step", type=int, help="step (s)")
|
p.add_argument("--step", type=int, help="Pattern step override")
|
||||||
p.add_argument("--name-value", nargs=2, metavar=("NAME", "JSON"), help="Send override under NAME key with JSON object value")
|
p.add_argument("--name-value", nargs=2, metavar=("NAME", "JSON"), help="Merge JSON into settings (shortcut)")
|
||||||
|
|
||||||
# SPI params
|
# SPI params
|
||||||
p.add_argument("--bus", type=int, default=0, help="SPI bus (default 0)")
|
p.add_argument("--bus", type=int, default=0, help="SPI bus (default 0)")
|
||||||
|
Reference in New Issue
Block a user