fix: update event count retrieval logic in AchSession and MiniMateClient
This commit is contained in:
+23
-26
@@ -257,29 +257,11 @@ class AchSession:
|
|||||||
# Used to detect post-erase key reuse — see comment block above.
|
# Used to detect post-erase key reuse — see comment block above.
|
||||||
max_seen_key: str = unit_state.get("max_downloaded_key", "00000000")
|
max_seen_key: str = unit_state.get("max_downloaded_key", "00000000")
|
||||||
|
|
||||||
# Use the event count already read from the event index during connect().
|
# Walk the event index (browse-mode, no 5A) to get the actual current
|
||||||
# This is fast (no extra round-trips) and confirmed accurate (matches LCD).
|
# key list. The SUB 08 event_count field is a lifetime "total events
|
||||||
# Falls back to count_events() only if connect() wasn't called.
|
# ever recorded" counter that does NOT decrement on erase — confirmed
|
||||||
if device_info is not None:
|
# 2026-04-13. list_event_keys() via the 1E/1F chain is the only
|
||||||
current_count = device_info.event_count or 0
|
# reliable way to know what is actually stored on the device right now.
|
||||||
else:
|
|
||||||
try:
|
|
||||||
current_count = client.count_events()
|
|
||||||
except Exception as exc:
|
|
||||||
log.error(" [FAIL] count_events failed: %s", exc)
|
|
||||||
return
|
|
||||||
|
|
||||||
log.info(" Unit has %d stored event(s); %d key(s) previously downloaded",
|
|
||||||
current_count, len(seen_keys))
|
|
||||||
|
|
||||||
if current_count == 0:
|
|
||||||
log.info(" [OK] No events on device -- nothing to download")
|
|
||||||
log.info("Session complete (no events) -> %s", session_dir)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Fast pre-check: walk the event index (browse-mode, no 5A) to get
|
|
||||||
# the current key list, then bail early if everything is already seen.
|
|
||||||
# This avoids calling get_events() at all when there's nothing new.
|
|
||||||
log.info(" Checking device key list (browse walk, no waveform download)...")
|
log.info(" Checking device key list (browse walk, no waveform download)...")
|
||||||
try:
|
try:
|
||||||
device_keys = client.list_event_keys()
|
device_keys = client.list_event_keys()
|
||||||
@@ -287,6 +269,17 @@ class AchSession:
|
|||||||
log.warning(" list_event_keys failed: %s -- falling back to full download", exc)
|
log.warning(" list_event_keys failed: %s -- falling back to full download", exc)
|
||||||
device_keys = None
|
device_keys = None
|
||||||
|
|
||||||
|
# Use the walk result as our authoritative current count.
|
||||||
|
current_count = len(device_keys) if device_keys is not None else 0
|
||||||
|
|
||||||
|
log.info(" Unit has %d stored event(s); %d key(s) previously downloaded",
|
||||||
|
current_count, len(seen_keys))
|
||||||
|
|
||||||
|
if device_keys is not None and current_count == 0:
|
||||||
|
log.info(" [OK] No events on device -- nothing to download")
|
||||||
|
log.info("Session complete (no events) -> %s", session_dir)
|
||||||
|
return
|
||||||
|
|
||||||
if device_keys is not None:
|
if device_keys is not None:
|
||||||
# ── Post-erase detection ──────────────────────────────────────
|
# ── Post-erase detection ──────────────────────────────────────
|
||||||
# After the device memory is erased, new events start from key
|
# After the device memory is erased, new events start from key
|
||||||
@@ -359,10 +352,14 @@ class AchSession:
|
|||||||
new_key_set = None # unknown; proceed with full download
|
new_key_set = None # unknown; proceed with full download
|
||||||
|
|
||||||
# Apply max_events cap
|
# Apply max_events cap
|
||||||
stop_idx = current_count - 1
|
# stop_idx: when we know the count from list_event_keys, use it as
|
||||||
|
# an upper bound. When list_event_keys failed (device_keys is None),
|
||||||
|
# pass None — get_events will run until the null sentinel naturally.
|
||||||
|
stop_idx: Optional[int] = (current_count - 1) if device_keys is not None else None
|
||||||
if self.max_events is not None:
|
if self.max_events is not None:
|
||||||
stop_idx = min(stop_idx, self.max_events - 1)
|
cap = self.max_events - 1
|
||||||
if self.max_events < current_count:
|
stop_idx = cap if stop_idx is None else min(stop_idx, cap)
|
||||||
|
if device_keys is not None and self.max_events < current_count:
|
||||||
log.warning(
|
log.warning(
|
||||||
" max_events=%d cap: will download events 0-%d only "
|
" max_events=%d cap: will download events 0-%d only "
|
||||||
"(unit has %d total)",
|
"(unit has %d total)",
|
||||||
|
|||||||
+15
-2
@@ -181,8 +181,21 @@ class MiniMateClient:
|
|||||||
log.info("connect: reading event index (SUB 08)")
|
log.info("connect: reading event index (SUB 08)")
|
||||||
try:
|
try:
|
||||||
idx_raw = proto.read_event_index()
|
idx_raw = proto.read_event_index()
|
||||||
device_info.event_count = _decode_event_count(idx_raw)
|
# NOTE: _decode_event_count reads data[10:12] from the SUB 08 payload,
|
||||||
log.info("connect: device has %d stored event(s)", device_info.event_count)
|
# which was believed to be the stored event count. Empirically it turns
|
||||||
|
# out to be a monotonically-increasing "total events ever recorded" counter
|
||||||
|
# that does NOT decrement when events are erased — confirmed 2026-04-13:
|
||||||
|
# device reported 6 via SUB 08 while list_event_keys() returned 0 (empty).
|
||||||
|
# We preserve the raw read here for the index data but do NOT use this
|
||||||
|
# count for logic; ach_server uses list_event_keys() as the authoritative
|
||||||
|
# source instead.
|
||||||
|
_raw_idx_count = _decode_event_count(idx_raw)
|
||||||
|
log.info(
|
||||||
|
"connect: SUB 08 index count=%d (lifetime counter, not current storage)",
|
||||||
|
_raw_idx_count,
|
||||||
|
)
|
||||||
|
# Leave device_info.event_count as None — callers should use
|
||||||
|
# list_event_keys() to get the actual current event count.
|
||||||
except ProtocolError as exc:
|
except ProtocolError as exc:
|
||||||
log.warning("connect: event index read failed: %s — continuing", exc)
|
log.warning("connect: event index read failed: %s — continuing", exc)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user