From 6adf8b60788cb26e18f4c0f99e741cda3d08214c Mon Sep 17 00:00:00 2001 From: Brian Harrison Date: Fri, 3 Apr 2026 18:15:42 -0400 Subject: [PATCH] =?UTF-8?q?Fix:=20advance=5Fevent(browse=3DTrue)=20now=20s?= =?UTF-8?q?ends=20token=5Fparams(0)=20=E2=80=94=20all=20zeros=20=E2=80=94?= =?UTF-8?q?=20matching=20the=20confirmed=20BW=20browse=20sequence.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- minimateplus/client.py | 2 +- minimateplus/protocol.py | 31 +++++++++++++++++-------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/minimateplus/client.py b/minimateplus/client.py index 03fd9d2..65e696a 100644 --- a/minimateplus/client.py +++ b/minimateplus/client.py @@ -216,7 +216,7 @@ class MiniMateClient: log.warning("count_events: 0A failed for key=%s: %s", key4.hex(), exc) break try: - key4, data8 = proto.advance_event() + key4, data8 = proto.advance_event(browse=True) log.warning( "count_events: 1F [iter %d] → key=%s data8=%s trailing=%s", count, key4.hex(), data8.hex(), data8[4:8].hex(), diff --git a/minimateplus/protocol.py b/minimateplus/protocol.py index 8694845..afc38d1 100644 --- a/minimateplus/protocol.py +++ b/minimateplus/protocol.py @@ -518,15 +518,22 @@ class MiniMateProtocol: return frames_data - def advance_event(self) -> tuple[bytes, bytes]: + def advance_event(self, browse: bool = False) -> tuple[bytes, bytes]: """ - Send the SUB 1F (EVENT_ADVANCE) two-step read with download-mode token - (0xFE) and return the next waveform key and the full 8-byte event data - block. + Send the SUB 1F (EVENT_ADVANCE) two-step read and return the next + waveform key and the full 8-byte event data block. - In download mode (token=0xFE), the device skips partial histogram bins - and returns the key of the next FULL record directly. This is the - Blastware-observed behaviour for iterating through all stored events. + browse=False (default, download mode): sends token=0xFE at params[7]. + Used by get_events() — the token causes the device to skip partial + histogram bins and return the key of the next FULL record. + + browse=True: sends all-zero params (no token). Matches Blastware's + confirmed browse-mode sequence: 0A → 1F(zeros) → 0A → 1F(zeros). + Used by count_events() where no 0C/5A download occurs. + + IMPORTANT: A preceding 0A (read_waveform_header) call is REQUIRED in + both modes to establish device waveform context. Without it, 1F + returns the null sentinel regardless of how many events are stored. Returns: (key4, event_data8) where: @@ -538,19 +545,15 @@ class MiniMateProtocol: all-zeros for event 0 (the very first stored event) and will cause the loop to terminate prematurely. - Confirmed from 4-3-26 two-event capture: - - event 0 1E response: key4=00000000 data8=0000000000011100 (valid) - - event 1 1F response: key4=0000fe00 data8=0000fe0000011100 (valid) - - null 1F response: key4=0000fe00 data8=0000fe0000000000 ← trailing zeros - Raises: ProtocolError: on timeout, bad checksum, or wrong response SUB. """ rsp_sub = _expected_rsp_sub(SUB_EVENT_ADVANCE) length = DATA_LENGTHS[SUB_EVENT_ADVANCE] # 0x08 - params = token_params(0xFE) + params = token_params(0) if browse else token_params(0xFE) - log.debug("advance_event: 1F probe") + mode = "browse" if browse else "download" + log.debug("advance_event: 1F probe mode=%s params=%s", mode, params.hex()) self._send(build_bw_frame(SUB_EVENT_ADVANCE, 0, params)) self._recv_one(expected_sub=rsp_sub)