Follow-up to the ts1→ts2 fix: get the trigger to the second from the binary alone, instead of falling back to the stop time (~record-duration late) for no-report events. The configured post-trigger record time is a big-endian float32 in the recording-setup config block, exactly 30 bytes before the "Standard Recording Setup" marker. _parse_record_time_seconds reads it; the waveform branch now stamps trigger = ts2 - record_time. Verified: the field reads 1.0 / 2.0 / 3.0 s across different setups in the corpus, and all 7 BE12844 oracle events now decode to their exact Blastware trigger (N844LQHB 10:33:29) from the binary, no paired .TXT needed. Falls back to ts2 (the stop) if the config block is absent. A paired report's event_datetime stays authoritative (clock drift). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YDXjZCr4RqT2U3QvMDhgzf
55 lines
2.6 KiB
Python
55 lines
2.6 KiB
Python
"""Event timestamp decode — waveform trigger/stop vs histogram window start.
|
|
|
|
The Blastware footer holds two timestamps: ts1 = footer[2:10], ts2 = footer[10:18].
|
|
Their meaning depends on record type:
|
|
|
|
* Waveform: ts1 is the monitoring-SESSION start (e.g. 06:00 for a unit that
|
|
arms at 06:00 daily — shared across every event that day), and ts2 is THIS
|
|
event's recording STOP. read_blastware_file used to stamp events with ts1 →
|
|
every waveform showed the session start (~4.5 h off). Binary-only, the best
|
|
estimate is ts2 (the stop); the exact trigger BW displays (= ts2 - record
|
|
duration) comes from the paired report's event_datetime, since the binary
|
|
STRT record-time byte is a misparsed record-type marker.
|
|
* Histogram: ts1/ts2 are the ~24 h window [start, stop]; the event time is the
|
|
window start = ts1 (unchanged).
|
|
"""
|
|
import datetime
|
|
from pathlib import Path
|
|
|
|
from minimateplus.event_file_io import read_blastware_file, apply_report_to_event
|
|
from minimateplus.bw_ascii_report import BwAsciiReport
|
|
from minimateplus.models import Event
|
|
|
|
FIX = Path(__file__).parent / "fixtures"
|
|
WAVEFORM = FIX / "fft-oracle-2026-09-14" / "N844LQHB.ZT0W" # footer ts2 = 2026-08-25 10:33:32
|
|
HISTOGRAM = FIX / "ts-fix" / "K441LKZU.C30H" # window start 2026-05-10 19:04:50
|
|
|
|
|
|
def _tuple(ts):
|
|
return (ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second)
|
|
|
|
|
|
def test_waveform_timestamp_is_exact_trigger_from_binary():
|
|
ev = read_blastware_file(WAVEFORM)
|
|
# The EXACT Blastware trigger, from the binary alone: ts2 (stop 10:33:32)
|
|
# minus the config record time (3.0 s) = 10:33:29 — NOT the 06:00:13
|
|
# monitoring-session start the old decode used.
|
|
assert _tuple(ev.timestamp) == (2026, 8, 25, 10, 33, 29), _tuple(ev.timestamp)
|
|
|
|
|
|
def test_histogram_timestamp_is_window_start_unchanged():
|
|
ev = read_blastware_file(HISTOGRAM)
|
|
# Histogram event time = the window start (ts1); must NOT get the waveform
|
|
# ts2 treatment (that would land ~24 h off).
|
|
assert _tuple(ev.timestamp) == (2026, 5, 10, 19, 4, 50), _tuple(ev.timestamp)
|
|
|
|
|
|
def test_report_event_datetime_is_authoritative_over_binary():
|
|
# The binary already yields the exact trigger, but a paired report stays
|
|
# authoritative (e.g. if the unit clock had drifted) — applying it wins.
|
|
ev = read_blastware_file(WAVEFORM)
|
|
assert _tuple(ev.timestamp) == (2026, 8, 25, 10, 33, 29) # exact, from binary
|
|
apply_report_to_event(ev, BwAsciiReport(
|
|
event_datetime=datetime.datetime(2026, 8, 25, 10, 35, 0)))
|
|
assert _tuple(ev.timestamp) == (2026, 8, 25, 10, 35, 0) # report wins
|