Refactor patterns to use preset-based API and fix initialization order

- Fix initialization order: initialize self.presets before calling self.select()
- Separate add() and edit() methods: add() creates new presets, edit() updates existing ones
- Update all test files to use add() instead of edit() for creating presets
- Add comprehensive auto/manual mode test
- Remove tool.py (moved to led-tool project)
This commit is contained in:
2026-01-25 23:23:14 +13:00
parent f4ef415b5a
commit b7d2f52fc3
16 changed files with 1593 additions and 1105 deletions

165
dev.py
View File

@@ -3,130 +3,51 @@
import subprocess
import serial
import sys
import glob
def upload_src(port):
subprocess.call(["mpremote", "connect", port, "fs", "cp", "-r", ".", ":"], cwd="src")
print(sys.argv)
def upload_lib(port):
subprocess.call(["mpremote", "connect", port, "fs", "cp", "-r", "lib", ":"])
# Extract port (first arg if it's not a command)
commands = ["src", "lib", "ls", "reset", "follow", "db"]
port = None
if len(sys.argv) > 1 and sys.argv[1] not in commands:
port = sys.argv[1]
def list_files(port):
subprocess.call(["mpremote", "connect", port, "fs", "ls", ":"])
def reset_device(port):
with serial.Serial(port, baudrate=115200) as ser:
ser.write(b'\x03\x03\x04')
def follow_serial(port):
with serial.Serial(port, baudrate=115200) as ser:
while True:
if ser.in_waiting > 0:
data = ser.readline().decode('utf-8').strip()
print(data)
def clean_settings(port):
subprocess.call(["mpremote", "connect", port, "fs", "rm", ":/settings.json"])
def flash_firmware(port):
# Find MicroPython firmware binary
firmware_files = glob.glob("*.bin")
if not firmware_files:
print("Error: No .bin firmware file found in current directory")
print("Please download MicroPython firmware and place it in the project directory")
sys.exit(1)
firmware = firmware_files[0]
if len(firmware_files) > 1:
print(f"Warning: Multiple .bin files found, using: {firmware}")
print(f"Flashing MicroPython firmware: {firmware}")
print("Erasing flash...")
subprocess.call(["esptool.py", "--port", port, "erase_flash"])
print(f"Writing firmware to flash...")
subprocess.call([
"esptool.py",
"--port", port,
"--baud", "460800",
"write_flash", "0",
firmware
])
print("Flash complete!")
def main():
port = "/dev/ttyACM0"
commands = []
i = 1
# Parse arguments manually to preserve order
while i < len(sys.argv):
arg = sys.argv[i]
if arg in ["-p", "--port"]:
if i + 1 < len(sys.argv):
port = sys.argv[i + 1]
i += 2
for cmd in sys.argv[1:]:
print(cmd)
match cmd:
case "src":
if port:
subprocess.call(["mpremote", "connect", port, "fs", "cp", "-r", ".", ":" ], cwd="src")
else:
print(f"Error: {arg} requires a port argument")
sys.exit(1)
elif arg in ["-s", "--src"]:
commands.append(("src", upload_src))
i += 1
elif arg in ["-r", "--reset"]:
commands.append(("reset", reset_device))
i += 1
elif arg in ["-f", "--follow"]:
commands.append(("follow", follow_serial))
i += 1
elif arg == "--lib":
commands.append(("lib", upload_lib))
i += 1
elif arg == "--ls":
commands.append(("ls", list_files))
i += 1
elif arg == "--clean":
commands.append(("clean", clean_settings))
i += 1
elif arg == "--flash":
commands.append(("flash", flash_firmware))
i += 1
elif arg in ["-h", "--help"]:
print("LED Driver development tools")
print("\nUsage:")
print(" ./dev.py [-p PORT] [FLAGS...]")
print("\nFlags:")
print(" -p, --port PORT Serial port (default: /dev/ttyACM0)")
print(" -s, --src Upload src directory")
print(" -r, --reset Reset device")
print(" -f, --follow Follow serial output")
print(" --lib Upload lib directory")
print(" --ls List files on device")
print(" --clean Remove settings.json from device")
print(" --flash Flash MicroPython firmware")
print("\nExamples:")
print(" ./dev.py -p /dev/ttyACM0 -s -r -f")
print(" ./dev.py --flash -s -r")
sys.exit(0)
else:
print(f"Error: Unknown argument: {arg}")
print("Use -h or --help for usage information")
sys.exit(1)
# Execute commands in the order they were given
if not commands:
print("No commands specified. Use -h or --help for usage information.")
sys.exit(1)
for cmd_name, cmd_func in commands:
if cmd_name == "reset":
print("Resetting device...")
elif cmd_name == "follow":
print("Following serial output (Ctrl+C to exit)...")
elif cmd_name == "flash":
pass # flash_firmware prints its own messages
else:
print(f"{cmd_name.capitalize()}...")
cmd_func(port)
if __name__ == "__main__":
main()
print("Error: Port required for 'src' command")
case "lib":
if port:
subprocess.call(["mpremote", "connect", port, "fs", "cp", "-r", "lib", ":" ])
else:
print("Error: Port required for 'lib' command")
case "ls":
if port:
subprocess.call(["mpremote", "connect", port, "fs", "ls", ":" ])
else:
print("Error: Port required for 'ls' command")
case "reset":
if port:
with serial.Serial(port, baudrate=115200) as ser:
ser.write(b'\x03\x03\x04')
else:
print("Error: Port required for 'reset' command")
case "follow":
if port:
with serial.Serial(port, baudrate=115200) as ser:
while True:
if ser.in_waiting > 0: # Check if there is data in the buffer
data = ser.readline().decode('utf-8').strip() # Read and decode the data
print(data)
else:
print("Error: Port required for 'follow' command")
case "db":
if port:
subprocess.call(["mpremote", "connect", port, "fs", "cp", "-r", "db", ":" ])
else:
print("Error: Port required for 'db' command")