fix: redefines rectime_seconds from strt[18] byte to new computed time.

The server now re-computes rectime_seconds using the actual sample rate from the compliance config (overriding the default 1024 in the client), so if the device runs at 2048 or 4096 sps it's still correct.

Viewer — The rectime display now shows Xs (stored) / Ys (cfg) so you can compare the STRT-derived duration against the compliance config's record_time setting side-by-side. I also clamped the y-axis to ±(0C peak × 1.4) so near-saturation decode artifacts don't squash the real blast signal into a flat line.
This commit is contained in:
2026-04-14 14:19:17 -04:00
parent edb4698bfb
commit 0da88ec6aa
4 changed files with 98 additions and 10 deletions
+23 -6
View File
@@ -603,7 +603,7 @@ class MiniMateClient:
"get_events: 5A full waveform download for key=%s", cur_key.hex()
)
a5_frames = proto.read_bulk_waveform_stream(
cur_key, stop_after_metadata=False, max_chunks=128
cur_key, stop_after_metadata=False, max_chunks=2048
)
if a5_frames:
a5_ok = True
@@ -1378,25 +1378,42 @@ def _decode_a5_waveform(
# STRT record layout (21 bytes, offsets relative to b'STRT'):
# +0..3 magic b'STRT'
# +8..9 uint16 BE total_samples (full-record expected sample-set count)
# +4..5 0xFF 0xFE (flags)
# +6..9 key4 (4-byte event key)
# +10..13 prev_key4
# +14..15 uint16 BE total_samples (full-record expected sample-set count)
# +16..17 uint16 BE pretrig_samples
# +18 uint8 rectime_seconds
#
# NOTE: strt[8:10] is the LOWER 2 bytes of key4, NOT total_samples.
# Confirmed from raw_rx capture (4-9-26): strt[14:16] = total_samples. ✅
strt = w0[strt_pos : strt_pos + 21]
if len(strt) < 21:
log.warning("_decode_a5_waveform: STRT record truncated (%dB)", len(strt))
return
total_samples = struct.unpack_from(">H", strt, 8)[0]
total_samples = struct.unpack_from(">H", strt, 14)[0]
pretrig_samples = struct.unpack_from(">H", strt, 16)[0]
rectime_seconds = strt[18]
# strt[18] is a record-mode/type byte, NOT rectime in seconds.
# Confirmed from analysis of 4-9-26 ACH capture (15 distinct events):
# flags=0xFFFE (single-shot) → strt[18]=0x46 ('F') for all events regardless of duration
# flags=0xFFFD (continuous) → strt[18]=0x0E for all events regardless of duration
# The actual post-trigger record time must be derived from total_samples and pretrig_samples.
# Default sample rate of 1024 is used here; the server overrides with compliance config sr.
_sample_rate_default = 1024
rectime_seconds = int(round(
max(0, total_samples - pretrig_samples) / _sample_rate_default
))
event.total_samples = total_samples
event.pretrig_samples = pretrig_samples
event.rectime_seconds = rectime_seconds
log.debug(
"_decode_a5_waveform: STRT total_samples=%d pretrig=%d rectime=%ds",
total_samples, pretrig_samples, rectime_seconds,
"_decode_a5_waveform: STRT total_samples=%d pretrig=%d "
"strt[18]=0x%02X (mode byte, not seconds) computed_rectime=%ds",
total_samples, pretrig_samples, strt[18], rectime_seconds,
)
# ── Collect per-frame waveform bytes with global offset tracking ─────────