diff --git a/minimateplus/client.py b/minimateplus/client.py index 3f5c9d2..d35c541 100644 --- a/minimateplus/client.py +++ b/minimateplus/client.py @@ -228,7 +228,7 @@ class MiniMateClient: log.info("count_events: %d event(s) found via 1E/1F chain", count) return count - def get_events(self, full_waveform: bool = False, debug: bool = False) -> list[Event]: + def get_events(self, full_waveform: bool = False, debug: bool = False, stop_after_index: Optional[int] = None) -> list[Event]: """ Download all stored events from the device using the confirmed 1E → 0A → 0C → 5A → 1F event-iterator protocol. @@ -439,6 +439,15 @@ class MiniMateClient: events.append(ev) idx += 1 + # Early exit: if the caller only wants events up to a specific + # index, stop iterating once we've collected it. + if stop_after_index is not None and idx > stop_after_index: + log.info( + "get_events: reached stop_after_index=%d — stopping early", + stop_after_index, + ) + break + else: # Partial/failed record — skip 5A, just advance with 1F. log.info( diff --git a/minimateplus/protocol.py b/minimateplus/protocol.py index 9a2041f..5e65924 100644 --- a/minimateplus/protocol.py +++ b/minimateplus/protocol.py @@ -520,7 +520,7 @@ class MiniMateProtocol: self._send(build_5a_frame(_BULK_CHUNK_OFFSET, params)) self._parser.reset() # reset bytes_fed for accurate per-chunk count try: - rsp = self._recv_one(expected_sub=rsp_sub, reset_parser=False) + rsp = self._recv_one(expected_sub=rsp_sub, reset_parser=False, timeout=10.0) except TimeoutError: raw = self._parser.bytes_fed log.warning( diff --git a/sfm/server.py b/sfm/server.py index 10c2a1d..5e9dd77 100644 --- a/sfm/server.py +++ b/sfm/server.py @@ -380,7 +380,7 @@ def device_event( def _do(): with _build_client(port, baud, host, tcp_port) as client: client.connect() - return client.get_events() + return client.get_events(stop_after_index=index) events = _run_with_retry(_do, is_tcp=_is_tcp(host)) except HTTPException: raise @@ -433,9 +433,8 @@ def device_event_waveform( def _do(): with _build_client(port, baud, host, tcp_port, timeout=120.0) as client: info = client.connect() - # full_waveform=True fetches the complete 5A stream inside the - # 1E→0A→0C→5A→1F loop. Issuing a second 5A after 1F times out. - events = client.get_events(full_waveform=True) + # stop_after_index avoids downloading events beyond the one requested. + events = client.get_events(full_waveform=True, stop_after_index=index) matching = [ev for ev in events if ev.index == index] return matching[0] if matching else None, info ev, info = _run_with_retry(_do, is_tcp=_is_tcp(host))