fix: add STRT invalid detction, ach server passes config for get events,
This commit is contained in:
+67
-4
@@ -448,7 +448,7 @@ class MiniMateClient:
|
||||
proto.confirm_erase_all()
|
||||
log.info("delete_all_events: erase confirmed — device memory cleared")
|
||||
|
||||
def get_events(self, full_waveform: bool = False, debug: bool = False, stop_after_index: Optional[int] = None, skip_waveform_for_keys: Optional[set] = None) -> list[Event]:
|
||||
def get_events(self, full_waveform: bool = False, debug: bool = False, stop_after_index: Optional[int] = None, skip_waveform_for_keys: Optional[set] = None, compliance_config: Optional["ComplianceConfig"] = None) -> list[Event]:
|
||||
"""
|
||||
Download all stored events from the device using the confirmed
|
||||
1E → 0A → 0C → 5A → 1F event-iterator protocol.
|
||||
@@ -479,6 +479,7 @@ class MiniMateClient:
|
||||
ProtocolError: on unrecoverable communication failure.
|
||||
"""
|
||||
proto = self._require_proto()
|
||||
_compliance_config = compliance_config # passed through to _decode_a5_waveform
|
||||
|
||||
log.info("get_events: requesting first event (SUB 1E)")
|
||||
try:
|
||||
@@ -608,7 +609,7 @@ class MiniMateClient:
|
||||
if a5_frames:
|
||||
a5_ok = True
|
||||
_decode_a5_metadata_into(a5_frames, ev)
|
||||
_decode_a5_waveform(a5_frames, ev)
|
||||
_decode_a5_waveform(a5_frames, ev, compliance_config=_compliance_config)
|
||||
log.info(
|
||||
"get_events: 5A decoded %d sample-sets",
|
||||
len((ev.raw_samples or {}).get("Tran", [])),
|
||||
@@ -1311,6 +1312,7 @@ def _decode_a5_metadata_into(frames_data: list[bytes], event: Event) -> None:
|
||||
def _decode_a5_waveform(
|
||||
frames_data: list[bytes],
|
||||
event: Event,
|
||||
compliance_config: Optional["ComplianceConfig"] = None,
|
||||
) -> None:
|
||||
"""
|
||||
Decode the raw 4-channel ADC waveform from a complete set of SUB 5A
|
||||
@@ -1397,15 +1399,19 @@ def _decode_a5_waveform(
|
||||
|
||||
# Sanity check: pretrig must be less than total_samples.
|
||||
# If not, the STRT layout is suspect (DLE-stuffing shift, different record variant, etc.).
|
||||
# Log the raw bytes for diagnosis and clamp pretrig to 0 so the viewer renders.
|
||||
# Log the raw bytes for diagnosis and clamp pretrig to 0 for now — will try to derive
|
||||
# a better value from the compliance config after the full waveform is decoded.
|
||||
_strt_invalid = False
|
||||
if pretrig_samples >= total_samples:
|
||||
log.warning(
|
||||
"_decode_a5_waveform: pretrig_samples=%d >= total_samples=%d — "
|
||||
"STRT layout suspect. Raw strt[0:21]: %s "
|
||||
"Clamping pretrig to 0 for rendering.",
|
||||
"Will attempt to derive pretrig from compliance config after decode.",
|
||||
pretrig_samples, total_samples, strt[0:21].hex(' '),
|
||||
)
|
||||
pretrig_samples = 0
|
||||
total_samples = 0 # also invalid; will be filled from decoded count below
|
||||
_strt_invalid = True
|
||||
|
||||
# strt[18] is a record-mode/type byte, NOT rectime in seconds.
|
||||
# Confirmed from analysis of 4-9-26 ACH capture (15 distinct events):
|
||||
@@ -1534,6 +1540,63 @@ def _decode_a5_waveform(
|
||||
"Mic": mic,
|
||||
}
|
||||
|
||||
# ── Correct STRT-invalid pretrig/total from decoded count + compliance config ──
|
||||
# When the STRT layout was suspect (pretrig >= total_samples), both values were
|
||||
# zeroed out earlier. Now that we know the actual decoded sample count, use it
|
||||
# together with the compliance config record_time to derive a meaningful pretrig.
|
||||
#
|
||||
# Formula:
|
||||
# post_trig = record_time (s) × sample_rate (sps)
|
||||
# pretrig = decoded_samples − post_trig
|
||||
#
|
||||
# This gives the pre-trigger window length, which correctly places t=0 in the
|
||||
# waveform. If compliance_config is not available, leave pretrig=0 (viewer shows
|
||||
# full waveform starting at t=0 — better than a crash or garbage).
|
||||
n_decoded = len(tran)
|
||||
if _strt_invalid:
|
||||
if compliance_config is not None:
|
||||
cc_sr = compliance_config.sample_rate or 1024
|
||||
cc_rt = compliance_config.record_time
|
||||
# Pre-trigger time is a separate device setting from Record Time.
|
||||
# Blastware documentation confirms the compliance monitoring standard
|
||||
# is 0.25 seconds pre-trigger ("the default Time Scale is -0.25 to 1
|
||||
# second — this negative number accounts for the pre-trigger set for
|
||||
# compliance monitoring").
|
||||
# The pre-trigger field has not yet been located in the raw compliance
|
||||
# config bytes; 0.25 s is used as the best-known default until it is
|
||||
# decoded. TODO: locate pretrig_time in ComplianceConfig bytes.
|
||||
_PRETRIG_SECONDS_DEFAULT = 0.25
|
||||
derived_pretrig = int(round(_PRETRIG_SECONDS_DEFAULT * cc_sr))
|
||||
if cc_rt and cc_rt > 0:
|
||||
post_trig_samples = int(round(cc_rt * cc_sr))
|
||||
# Clip total to pretrig + post_trig so the viewer doesn't show the
|
||||
# zero-padded tail frames the device appends beyond the record window.
|
||||
event.total_samples = derived_pretrig + post_trig_samples
|
||||
event.pretrig_samples = derived_pretrig
|
||||
event.rectime_seconds = int(round(cc_rt))
|
||||
log.info(
|
||||
"_decode_a5_waveform: STRT was invalid — using pretrig=%d "
|
||||
"(%.2fs default) from compliance standard; record_time=%.1fs "
|
||||
"sr=%d sps decoded=%d samples display_total=%d",
|
||||
derived_pretrig, _PRETRIG_SECONDS_DEFAULT,
|
||||
cc_rt, cc_sr, n_decoded, event.total_samples,
|
||||
)
|
||||
else:
|
||||
event.total_samples = n_decoded
|
||||
event.pretrig_samples = derived_pretrig
|
||||
log.warning(
|
||||
"_decode_a5_waveform: STRT invalid, compliance config missing "
|
||||
"record_time — pretrig=%d (%.2fs default), total=decoded %d",
|
||||
derived_pretrig, _PRETRIG_SECONDS_DEFAULT, n_decoded,
|
||||
)
|
||||
else:
|
||||
event.total_samples = n_decoded
|
||||
log.warning(
|
||||
"_decode_a5_waveform: STRT invalid, no compliance config available "
|
||||
"— pretrig left as 0, total set to decoded count %d",
|
||||
n_decoded,
|
||||
)
|
||||
|
||||
|
||||
def _extract_record_type(data: bytes) -> Optional[str]:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user