diff --git a/CLAUDE.md b/CLAUDE.md index f8b545f..bafcf4e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -147,13 +147,11 @@ then sends the termination frame. 4-3-26 BW TX captures confirm it belongs at **`params[7]`** (raw: `00 00 00 00 00 00 00 fe 00 00`). With the wrong position the device ignores the token and 1F returns null immediately. -**all-zero params required (empirically confirmed):** Even with the correct token position, -sending `token=0xFE` causes the device to return null from 1F in multi-event sessions. -All callers (`count_events`, `get_events`) must use `advance_event(browse=True)` which -sends all-zero params. The 3-31-26 capture that "confirmed" token=0xFE had only one event -stored — 1F always returns null at end-of-events, so we never actually observed 1F -successfully returning a second key with token=0xFE. Empirical evidence from live device -testing with 2+ events is definitive: **always use all-zero params for 1F.** +**1F token depends on context:** In browse mode (no 5A), use all-zero params (`browse=True`). +In download mode (get_events with 5A), use token=0xFE (`browse=False`) — this is required to +arm the device's 5A bulk stream state machine. The earlier "empirical" test showing token=0xFE +returns null was done WITHOUT the 1E(arm) step; that test is invalid. BW always uses 1F(0xFE) +in download mode. `count_events` uses `browse=True` (no 5A needed). **0A context requirement:** `advance_event()` (1F) only returns a valid next-event key when a preceding `read_waveform_header()` (0A) call has established device waveform @@ -194,16 +192,16 @@ there is only one event. 0A(key0) ← REQUIRED: establishes device context 1E(token=0xFE) ← REQUIRED: arms device for 5A; CONFIRMED 4-2-26 + 4-3-26 0C(key0) ← read waveform record -1F(all zeros / browse=True) → key1 ← MUST come BEFORE 5A (BW sequence, confirmed 4-2-26) +1F(all zeros / browse=False) → key1 ← MUST come BEFORE 5A (BW sequence, confirmed 4-2-26) POLL × 3 ← REQUIRED: 3 full POLL cycles before 5A (BW frames 68-73) 5A(key0) ← bulk stream; key0 used even though 1F already advanced 0A(key1) 1E(token=0xFE) ← re-arm for next event's 5A 0C(key1) -1F(all zeros) → key2 +1F(browse=False) → key2 POLL × 3 5A(key1) -1F(all zeros) → null ← done +1F(browse=False) → null ← done ``` **The 1E(token=0xFE) arm step is required (FIXED 2026-04-06):** diff --git a/minimateplus/client.py b/minimateplus/client.py index a75f8d3..40050a5 100644 --- a/minimateplus/client.py +++ b/minimateplus/client.py @@ -326,11 +326,16 @@ class MiniMateClient: ) # SUB 1F — advance BEFORE 5A (matches BW sequence from 4-2-26 capture). + # MUST use browse=False (token=0xFE) — BW always sends 1F(token=0xFE) in + # download mode. The device's 5A state machine requires the download-mode + # token here to arm the bulk stream; browse-mode (all-zero) token causes + # the device to ignore the subsequent 5A probe. + # Confirmed from 4-2-26 capture frames 66-67 vs frame 74. # Save next key now; 5A will still use cur_key. try: - key4, data8 = proto.advance_event(browse=True) + key4, data8 = proto.advance_event(browse=False) log.info( - "get_events: 1F → key=%s trailing=%s", + "get_events: 1F(download) → key=%s trailing=%s", key4.hex(), data8[4:8].hex(), ) except ProtocolError as exc: