fix(protocol): correct continuous-mode record header classification for accurate timestamp extraction

This commit is contained in:
2026-05-01 20:28:55 -04:00
parent 0fbb39c21a
commit d758825c67
3 changed files with 58 additions and 20 deletions
+36 -19
View File
@@ -1638,31 +1638,48 @@ def _decode_a5_waveform(
def _extract_record_type(data: bytes) -> Optional[str]:
"""
Decode the recording mode from byte[1] of the 210-byte waveform record.
Detect the waveform record format by inspecting the first 3 bytes of the
210-byte record returned by SUB 0C.
Byte[1] is the sub-record code that immediately follows the day byte in the
9-byte timestamp header at the start of each waveform record:
[day:1] [sub_code:1] [month:1] [year:2 BE] ...
Two formats exist (confirmed from BE11529 captures and CLAUDE.md docs):
Confirmed codes (✅ 2026-04-01):
0x10 → "Waveform" (continuous / single-shot mode)
Single-shot mode — 9-byte header:
data[0] = day
data[1] = 0x10 ← sub_code marker
data[2] = month
data[3:5] = year (BE)
...
Histogram mode code is not yet confirmed — a histogram event must be
captured with debug=true to identify it. Returns None for unknown codes.
Continuous mode — 10-byte header:
data[0] = 0x10 ← marker A
data[1] = day ← variable (NOT 0x10)
data[2] = 0x10 ← marker B
data[3] = month
data[4:6] = year (BE)
...
Disambiguate by checking BOTH data[0] and data[2]:
- data[0]==0x10 AND data[2]==0x10 → Continuous (10-byte header)
- data[1]==0x10 → Single-shot (9-byte header)
- otherwise → Unknown
Previous logic only checked data[1] and so mis-classified continuous-mode
records as "Unknown(0xXX)" wherever day != 0x10 — see filename
M5290000.000 regression report (2026-05-01 SFM log).
"""
if len(data) < 2:
if len(data) < 3:
return None
code = data[1]
if code == 0x10:
return "Waveform"
if code == 0x03:
# Continuous mode waveform record (confirmed by user — NOT a monitor log).
# The byte layout differs from 0x10 single-shot records: the timestamp
# fields decode as garbage under the 0x10 waveform layout.
# TODO: confirm correct timestamp layout for 0x03 records from a known-time event.
# 10-byte continuous format: 0x10 markers at byte 0 AND byte 2
if data[0] == 0x10 and data[2] == 0x10:
return "Waveform (Continuous)"
log.warning("_extract_record_type: unknown sub_code=0x%02X", code)
return f"Unknown(0x{code:02X})"
# 9-byte single-shot format: 0x10 sub_code marker at byte 1
if data[1] == 0x10:
return "Waveform"
log.warning(
"_extract_record_type: unrecognized header: data[0:3]=%02X %02X %02X",
data[0], data[1], data[2],
)
return f"Unknown({data[0]:02X}.{data[1]:02X}.{data[2]:02X})"
def _extract_peak_floats(data: bytes) -> Optional[PeakValues]: