Files
Sony-rcp/scripts/analyze_capture.py
2026-05-13 12:30:37 +10:00

56 lines
1.6 KiB
Python

#!/usr/bin/env python3
"""Summarize fixed-size hex frames from serial_sniff.py logs."""
from __future__ import annotations
import argparse
import collections
import re
from pathlib import Path
FRAME_RE = re.compile(r"\b(?:(RX|TX)\s+)?frame\s+\d+\s+((?:[0-9A-Fa-f]{2}\s*)+)$")
def frames_from_log(path: Path) -> list[tuple[str, str]]:
frames: list[tuple[str, str]] = []
for line in path.read_text(encoding="utf-8").splitlines():
match = FRAME_RE.search(line.strip())
if match:
direction = match.group(1) or "RX"
frame = " ".join(match.group(2).upper().split())
frames.append((direction, frame))
return frames
def checksum_note(frame: str) -> str:
values = [int(part, 16) for part in frame.split()]
if len(values) != 6:
return ""
checksum = 0x5A
for value in values[:5]:
checksum ^= value
if checksum == values[5]:
return " checksum ok"
return f" checksum expected {checksum:02X}"
def main() -> int:
parser = argparse.ArgumentParser(description="Count frames in capture logs.")
parser.add_argument("logs", nargs="+", type=Path)
args = parser.parse_args()
for log in args.logs:
frames = frames_from_log(log)
counts = collections.Counter(frames)
print(f"{log}: {len(frames)} frames, {len(counts)} unique direction/frame pairs")
for (direction, frame), count in counts.most_common():
print(f" {count:5d} {direction:<2} {frame}{checksum_note(frame)}")
return 0
if __name__ == "__main__":
raise SystemExit(main())