"""Pull the device's in-memory BLE debug ring buffer over USB-CDC. Usage: python pull_ble_log.py # auto-detect port, write to config/.ble_device_log.json python pull_ble_log.py COM7 # specify port python pull_ble_log.py --clear # also clear device-side buffer after pulling Run this AFTER reproducing the BLE issue so the buffer captures the failure. The Python desktop app must NOT be running (it holds the serial port). """ import json import os import sys from pathlib import Path from serial_manager import SerialManager from utils.constants import APPDATA_DIR def main(argv: list[str]) -> int: clear = "--clear" in argv args = [a for a in argv[1:] if not a.startswith("--")] port = args[0] if args else None sm = SerialManager() if port: sm.connect(port) else: sm.scan_and_connect() if not sm.connected: print("ERROR: device not found on USB. Is the desktop app running and holding the port?") return 1 print(f"Connected to {sm.port}") entries = sm.get_ble_log() if entries is None: print("ERROR: get_ble_log returned no response (firmware too old? reflash needed.)") sm.disconnect() return 2 out_path = Path(APPDATA_DIR) / ".ble_device_log.json" out_path.parent.mkdir(parents=True, exist_ok=True) out_path.write_text(json.dumps(entries, indent=2), encoding="utf-8") print(f"Wrote {len(entries)} entries to {out_path}") # Pretty-print to stdout so you can pipe to a file or grep. for e in entries: print(f"[{e.get('t', 0)}ms] {e.get('m', '')}") if clear: if sm.clear_ble_log(): print("Device buffer cleared.") else: print("WARNING: clear_ble_log failed.") sm.disconnect() return 0 if __name__ == "__main__": sys.exit(main(sys.argv))