big refactor of waveform protocol.
This commit is contained in:
+19
-21
@@ -37,6 +37,7 @@ from __future__ import annotations
|
||||
import datetime
|
||||
import logging
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
import time
|
||||
from pathlib import Path
|
||||
@@ -863,8 +864,8 @@ def device_event_blastware_file(
|
||||
|
||||
Supply either *port* (serial) or *host* (TCP/modem).
|
||||
|
||||
The file is written to /tmp and streamed back as a binary download.
|
||||
Blastware can open it directly — filename encodes serial + timestamp.
|
||||
The file is written to the OS temp directory and streamed back as a binary
|
||||
download. Blastware can open it directly — filename encodes serial + timestamp.
|
||||
|
||||
Filename format: <prefix><serial3><stem><AB>0<W|H>
|
||||
- prefix letter = chr(ord('B') + floor(serial_numeric / 1000))
|
||||
@@ -885,26 +886,13 @@ def device_event_blastware_file(
|
||||
def _do():
|
||||
with _build_client(port, baud, host, tcp_port, timeout=120.0) as client:
|
||||
info = client.connect()
|
||||
# Use stop_after_metadata=True (full_waveform=False) with 1 extra
|
||||
# chunk after "Project:". The extra chunk is required to prime the
|
||||
# device over TCP: termination at term_counter=metadata_counter+0x0400
|
||||
# returns only ~90 bytes (no useful footer) over TCP/cellular, but
|
||||
# termination at metadata_counter+0x0800 (one chunk later) returns
|
||||
# the full 737-byte frame containing the footer.
|
||||
#
|
||||
# Confirmed from 4-26-26 BW RS-232 capture: BW terminates at 0x1800
|
||||
# without an extra chunk (works on RS-232 but not TCP).
|
||||
# write_blastware_file() automatically skips the extra chunk's
|
||||
# contribution — only the probe+ADC+metadata+terminator bytes appear
|
||||
# in the output file.
|
||||
#
|
||||
# full_waveform=True (natural end-of-stream) downloads ALL chunks
|
||||
# including post-event silence (35+ chunks for a 9-sec event at
|
||||
# 1024 sps) — this produces 24KB+ files that Blastware rejects.
|
||||
# Under v0.14.0 BW-exact 5A walk, the chunk loop is bounded by
|
||||
# the event end_offset extracted from STRT. No more
|
||||
# stop_after_metadata / extra_chunks gymnastics — these
|
||||
# kwargs are now no-ops.
|
||||
events = client.get_events(
|
||||
full_waveform=False,
|
||||
stop_after_index=index,
|
||||
extra_chunks_after_metadata=1,
|
||||
)
|
||||
matching = [ev for ev in events if ev.index == index]
|
||||
return matching[0] if matching else None, info
|
||||
@@ -940,8 +928,18 @@ def device_event_blastware_file(
|
||||
# Build filename using the same algorithm Blastware uses
|
||||
filename = blastware_filename(ev, serial)
|
||||
|
||||
# Write to /tmp so FastAPI can stream it back
|
||||
out_path = Path("/tmp") / filename
|
||||
# Write to OS temp dir (cross-platform: /tmp on Linux/macOS,
|
||||
# %TEMP% on Windows) so FastAPI can stream it back via FileResponse.
|
||||
out_path = Path(tempfile.gettempdir()) / filename
|
||||
# Delete any stale file at this path before writing. On Windows we have
|
||||
# observed the new (smaller) file getting trailing zero-bytes from the
|
||||
# previous (larger) file when filesystem semantics around open(...,"wb")
|
||||
# don't truncate cleanly (e.g. through a synced folder). Explicit unlink
|
||||
# eliminates that ambiguity.
|
||||
try:
|
||||
out_path.unlink()
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
write_blastware_file(ev, a5_frames, out_path)
|
||||
log.info(
|
||||
"blastware_file: wrote %s (%d A5 frames, serial=%s)",
|
||||
|
||||
Reference in New Issue
Block a user