fix: correct event count field offset and eliminate count_events() walk

_decode_event_count: read uint16 BE at offset 10 (confirmed 2026-04-10 from
live BE11529 event index — data[10:12]=0x0006=6, matches device LCD).
Previous uint32 at offset 3 always returned 1 regardless of event count.

ach_server.py: use device_info.event_count (already fetched during connect())
instead of calling count_events() separately. This saves 2*N round-trips and
avoids the 1F linked-list walk which was overcounting on some devices.
count_events() kept as fallback when connect() is skipped (--events-only).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-10 01:10:49 -04:00
parent 9d9c14af79
commit 3d2ebfc057
2 changed files with 24 additions and 28 deletions
+14 -7
View File
@@ -216,13 +216,20 @@ class AchSession:
unit_key = serial or self.peer # fall back to IP if no serial
last_count = state.get(unit_key, {}).get("event_count", 0)
try:
current_count = client.count_events()
log.info(" Unit has %d stored event(s); last downloaded count: %d",
current_count, last_count)
except Exception as exc:
log.error(" [FAIL] count_events failed: %s", exc)
return
# Use the event count already read from the event index during connect().
# This is fast (no extra round-trips) and confirmed accurate (matches LCD).
# Falls back to count_events() only if connect() wasn't called.
if device_info is not None:
current_count = device_info.event_count
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); last downloaded count: %d",
current_count, last_count)
if current_count <= last_count:
log.info(" [OK] No new events since last call-home -- nothing to download")