fix: improve metadata frame detection and update version to v0.12.1
This commit is contained in:
+36
-5
@@ -76,6 +76,22 @@ _COMPLIANCE_SLOT_SIZE = 64
|
||||
_COMPLIANCE_VALUE_OFFSET = 22
|
||||
_COMPLIANCE_VALUE_MAX = _COMPLIANCE_SLOT_SIZE - _COMPLIANCE_VALUE_OFFSET # 42
|
||||
|
||||
# Needles used to identify the 5A metadata frame in _decode_a5_waveform.
|
||||
# The frame carries compliance-setup ASCII strings embedded in the bulk stream.
|
||||
# Checking multiple needles is required because devices with unconfigured
|
||||
# Project/Client/etc. fields omit those label strings entirely — the sole
|
||||
# reliable anchor then becomes b"Geo: " (always present, geo threshold is
|
||||
# required for monitoring). We also check db (full rsp.data) rather than
|
||||
# db[7:] to avoid any off-by-7 miss if a label landed in the prefix bytes.
|
||||
_METADATA_FRAME_NEEDLES: tuple[bytes, ...] = (
|
||||
b"Project:",
|
||||
b"Client:",
|
||||
b"User Name:",
|
||||
b"Seis Loc:",
|
||||
b"Extended Notes",
|
||||
b"Geo: ",
|
||||
)
|
||||
|
||||
|
||||
# ── MiniMateClient ────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -1456,14 +1472,29 @@ def _decode_a5_waveform(
|
||||
wave[:24].hex(' '),
|
||||
)
|
||||
|
||||
# Metadata frame: contains "Project:", "Client:", etc. strings.
|
||||
# Metadata frame: contains compliance-setup ASCII strings.
|
||||
# Originally assumed to be always fi==7 (A5[7] in 4-2-26 blast capture),
|
||||
# but confirmed variable position — it appears at whatever chunk index the
|
||||
# device places it (observed at fi=6 for desk-thump events 2026-04-14).
|
||||
# Skip ANY frame whose raw bytes contain b"Project:" — this is the same
|
||||
# anchor used by stop_after_metadata in read_bulk_waveform_stream.
|
||||
elif b"Project:" in w:
|
||||
log.info("_decode_a5_waveform: fi=%d skipped (metadata frame)", fi)
|
||||
#
|
||||
# Detection uses MULTIPLE needles against the full frame bytes (db, NOT w)
|
||||
# because:
|
||||
# 1. Devices with no Project/Client/etc. configured omit those label strings
|
||||
# entirely — checking only b"Project:" misses the frame for unconfigured
|
||||
# units (confirmed 2026-04-15: Brian's device had no fields set, so
|
||||
# "Project:" was absent and the frame was decoded as ADC samples, causing
|
||||
# the serial number bytes "BE11529\0" to appear as waveform data).
|
||||
# 2. Checking db (full rsp.data) rather than w (db[7:]) eliminates any
|
||||
# off-by-7 risk if a label were to land in the first 7 bytes.
|
||||
# 3. b"Geo: " is always present (geo threshold is required for monitoring)
|
||||
# and serves as the universal fallback anchor.
|
||||
elif any(needle in db for needle in _METADATA_FRAME_NEEDLES):
|
||||
log.info(
|
||||
"_decode_a5_waveform: fi=%d skipped (metadata frame, "
|
||||
"needle=%r)",
|
||||
fi,
|
||||
next(n for n in _METADATA_FRAME_NEEDLES if n in db),
|
||||
)
|
||||
continue
|
||||
|
||||
# Terminator frames have page_key=0x0000 and are excluded upstream
|
||||
|
||||
@@ -125,6 +125,20 @@ _BULK_COUNTER_STEP = 0x0400 # chunk counter increment per chunk ✅
|
||||
# protocol requirement. Confirmed 2026-04-06: 0x0400 for chunk 1 works; 0x1004
|
||||
# causes a 120-second device timeout. Formula n * 0x0400 is used for all chunks.
|
||||
|
||||
# Needles for identifying the 5A metadata frame.
|
||||
# Devices with no Project/Client/etc. configured omit those label strings,
|
||||
# so b"Geo: " (geo threshold — always present) is the universal fallback.
|
||||
# Mirror of _METADATA_FRAME_NEEDLES in client.py; kept here for the
|
||||
# stop_after_metadata check in read_bulk_waveform_stream.
|
||||
_METADATA_FRAME_NEEDLES: tuple[bytes, ...] = (
|
||||
b"Project:",
|
||||
b"Client:",
|
||||
b"User Name:",
|
||||
b"Seis Loc:",
|
||||
b"Extended Notes",
|
||||
b"Geo: ",
|
||||
)
|
||||
|
||||
# Default timeout values (seconds).
|
||||
# MiniMate Plus is a slow device — keep these generous.
|
||||
DEFAULT_RECV_TIMEOUT = 10.0
|
||||
@@ -617,9 +631,13 @@ class MiniMateProtocol:
|
||||
break
|
||||
raise
|
||||
|
||||
# Detect metadata frame using the same multi-needle set used by
|
||||
# _decode_a5_waveform. Devices with no Project/Client/etc.
|
||||
# configured omit those label strings; b"Geo: " is the fallback.
|
||||
_is_metadata = any(n in rsp.data for n in _METADATA_FRAME_NEEDLES)
|
||||
log.warning(
|
||||
"5A RX chunk=%d page_key=0x%04X data_len=%d contains_Project=%s",
|
||||
chunk_num, rsp.page_key, len(rsp.data), b"Project:" in rsp.data,
|
||||
"5A RX chunk=%d page_key=0x%04X data_len=%d is_metadata=%s",
|
||||
chunk_num, rsp.page_key, len(rsp.data), _is_metadata,
|
||||
)
|
||||
|
||||
if rsp.page_key == 0x0000:
|
||||
@@ -629,7 +647,7 @@ class MiniMateProtocol:
|
||||
|
||||
frames_data.append(rsp.data)
|
||||
|
||||
if stop_after_metadata and b"Project:" in rsp.data:
|
||||
if stop_after_metadata and _is_metadata:
|
||||
log.debug("5A A5[%d] metadata found — stopping early", chunk_num)
|
||||
break
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user