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

60 lines
1.7 KiB
Python

#!/usr/bin/env python3
"""Summarize fixed-size hex frames from serial helper logs."""
from __future__ import annotations
import argparse
import collections
import re
from pathlib import Path
FRAME_RE = re.compile(
r"\b(?P<direction>RX|TX)(?:\s+cmd\s+0x[0-9A-Fa-f]{2})?"
r"(?:\s+fields\b.*?)?\s+"
r"frame\s+\d+\s+(?P<frame>(?:[0-9A-Fa-f]{2}\s*)+)(?:\s+\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("direction")
frame = " ".join(match.group("frame").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())