"""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