fix(blastware_file, server): enhance logging and correct chunk handling for accurate data processing

This commit is contained in:
2026-04-26 16:03:07 -04:00
parent 2f084ed105
commit ae30a02898
2 changed files with 37 additions and 10 deletions
+28 -2
View File
@@ -639,6 +639,15 @@ def write_blastware_file(
strt = b"STRT" + b"\xff\xfe" + key4 + bytes(14) + bytes([rectime & 0xFF]) strt = b"STRT" + b"\xff\xfe" + key4 + bytes(14) + bytes([rectime & 0xFF])
probe_skip = 7 + 21 probe_skip = 7 + 21
log.warning(
"write_blastware_file: strt_pos_stripped=%d probe_skip=%d "
"probe_data_len=%d strt_hex=%s",
strt_pos_stripped if strt_pos_stripped >= 0 else -1,
probe_skip,
len(a5_frames[0].data),
strt.hex() if len(strt) >= 4 else "(short)",
)
if len(strt) != 21: if len(strt) != 21:
raise ValueError(f"STRT record must be 21 bytes, got {len(strt)}") raise ValueError(f"STRT record must be 21 bytes, got {len(strt)}")
@@ -701,13 +710,30 @@ def write_blastware_file(
# truncated file that Blastware rejects. # truncated file that Blastware rejects.
skip = 13 if fi == 1 else 12 skip = 13 if fi == 1 else 12
all_bytes.extend(_frame_body_bytes(frame, skip)) contribution = _frame_body_bytes(frame, skip)
log.warning("write_blastware_file: fi=%d skip=%d raw_data=%d contribution=%d",
fi, skip, len(frame.data), len(contribution))
all_bytes.extend(contribution)
# Terminator contributes its content, which ends with the 26-byte footer. # Terminator contributes its content, which ends with the 26-byte footer.
# skip=11 (not 12) because the terminator's inner frame header is 4 bytes, # skip=11 (not 12) because the terminator's inner frame header is 4 bytes,
# one shorter than chunk frames' 5-byte inner header. Confirmed 2026-04-21. # one shorter than chunk frames' 5-byte inner header. Confirmed 2026-04-21.
if term_frame is not None: if term_frame is not None:
all_bytes.extend(_frame_body_bytes(term_frame, 11)) term_contribution = _frame_body_bytes(term_frame, 11)
log.warning(
"write_blastware_file: term_frame data_len=%d skip=11 "
"contribution_len=%d first8=%s",
len(term_frame.data),
len(term_contribution),
term_contribution[:8].hex() if len(term_contribution) >= 8 else term_contribution.hex(),
)
all_bytes.extend(term_contribution)
log.warning(
"write_blastware_file: all_bytes total=%d last28=%s",
len(all_bytes),
bytes(all_bytes[-28:]).hex() if len(all_bytes) >= 28 else bytes(all_bytes).hex(),
)
if len(all_bytes) >= 26: if len(all_bytes) >= 26:
body = bytes(all_bytes[:-26]) body = bytes(all_bytes[:-26])
+9 -8
View File
@@ -885,21 +885,22 @@ def device_event_blastware_file(
def _do(): def _do():
with _build_client(port, baud, host, tcp_port, timeout=120.0) as client: with _build_client(port, baud, host, tcp_port, timeout=120.0) as client:
info = client.connect() info = client.connect()
# Use stop_after_metadata=True (full_waveform=False) with 1 extra # Use stop_after_metadata=True (full_waveform=False) with 0 extra
# chunk after "Project:". For any record time, the pre-metadata # chunks after "Project:". Confirmed from 4-26-26 BW RS-232 capture
# section of the 5A stream naturally carries proportionally more # of "copy event to file" on a 2-sec Continuous event (key=01110000):
# ADC data for longer events — so "1 extra chunk" produces the # BW sends the termination frame IMMEDIATELY after the chunk that
# correct body length regardless of record time. # contains "Project:" — no extra chunk is downloaded first.
# extra_chunks_after_metadata=1 was WRONG: it downloaded one additional
# chunk (counter = last_data_counter + 0x0400) adding ~1053 spurious
# bytes to the body, causing Blastware to reject the file.
# #
# full_waveform=True (natural end-of-stream) downloads ALL chunks # full_waveform=True (natural end-of-stream) downloads ALL chunks
# including post-event silence (35+ chunks for a 9-sec event at # including post-event silence (35+ chunks for a 9-sec event at
# 1024 sps) — this produces 24KB+ files that Blastware rejects. # 1024 sps) — this produces 24KB+ files that Blastware rejects.
# Confirmed from file size comparison: BW 1-sec=4400B, BW 3-sec=8114B,
# per-second delta 1857 bytes — matches pre-metadata frame scaling.
events = client.get_events( events = client.get_events(
full_waveform=False, full_waveform=False,
stop_after_index=index, stop_after_index=index,
extra_chunks_after_metadata=1, extra_chunks_after_metadata=0,
) )
matching = [ev for ev in events if ev.index == index] matching = [ev for ev in events if ev.index == index]
return matching[0] if matching else None, info return matching[0] if matching else None, info