Files
seismo-relay/CHANGELOG.md
2026-04-02 17:30:33 -04:00

7.7 KiB
Raw Blame History

Changelog

All notable changes to seismo-relay are documented here.


v0.6.0 — 2026-04-02

Added

  • True event-time metadata via SUB 5A bulk waveform streamget_events() now issues a SUB 5A request after each SUB 0C download, reads the A5 response frames, and extracts the Client:, User Name:, and Seis Loc: fields as they existed at the moment the event was recorded. Previously these fields were backfilled from the current compliance config (SUB 1A), which reflects today's setup, not the setup active when the event triggered.
    • build_5a_frame(offset_word, raw_params) in framing.py — reproduces Blastware's exact wire format for SUB 5A requests: raw (non-DLE-stuffed) offset_hi, DLE-stuffed params, and a DLE-aware checksum where 10 XX pairs count only XX.
    • bulk_waveform_params() returns 11 bytes (extra trailing 0x00 confirmed from 1-2-26 BW wire capture).
    • read_bulk_waveform_stream(key4, *, stop_after_metadata=True, max_chunks=32) in protocol.py — loops sending chunk requests (counter increments 0x0400 per chunk), stops early when b"Project:" is found, then sends a termination frame.
    • _decode_a5_metadata_into(frames_data, event) in client.py — needle-searches A5 frame data for Project:, Client:, User Name:, Seis Loc:, Extended Notes and overwrites event.project_info.
  • get_events() sequence extended — now 1E → 0A → 0C → 5A → 1F per event.

Fixed

  • Compliance config (SUB 1A) channel block missing — orphaned self._send(build_bw_frame(SUB_COMPLIANCE, 0x2A, _DATA_PARAMS)) before the B/C/D receive loop had no corresponding recv_one(), shifting all subsequent receives one step behind and leaving frame D's channel-block data (trigger_level_geo, alarm_level_geo, max_range_geo) unread. Removed the orphaned send. Total config bytes received now correctly ~2126 (was ~1071).
  • Compliance config anchor search range_decode_compliance_config_into() searched cfg[40:100] for the sample-rate/record-time anchor. With the orphaned-send bug fixed the 44-byte padding it had been adding is gone, and the anchor now appears at cfg[11]. Search widened to cfg[0:150] to be robust to future layout shifts.
  • Removed byte-content deduplication from read_compliance_config() — was masking the real receive-ordering bug.

Protocol / Documentation

  • SUB 5A frame format confirmedoffset_hi byte (0x10) must be sent raw (not DLE-stuffed); checksum is DLE-aware (only the second byte of a 10 XX pair is summed). Standard build_bw_frame DLE-stuffs 0x10 incorrectly for 5A — a dedicated build_5a_frame is required.
  • Event-time metadata source confirmedClient:, User Name:, and Seis Loc: strings are present in A5 frame 7 of the bulk waveform stream (SUB 5A), not in the 210-byte SUB 0C waveform record. They reflect the compliance setup as it was when the event was stored on the device.

v0.5.0 — 2026-03-31

Added

  • Console tab in seismo_lab.py — direct device connection without the bridge subprocess.
    • Serial and TCP transport selectable via radio buttons.
    • Four one-click commands: POLL, Serial #, Full Config, Event Index.
    • Colour-coded scrolling output: TX (blue), RX raw hex (teal), parsed/decoded (green), errors (red).
    • Save Log and Send to Analyzer buttons; logs auto-saved to bridges/captures/console_<ts>.log.
    • Queue/after(100) pattern — no UI blocking or performance impact.
  • minimateplus package — clean Python client library for the MiniMate Plus S3 protocol.
    • SerialTransport and TcpTransport (for Sierra Wireless RV50/RV55 cellular modems).
    • MiniMateProtocol — DLE frame parser/builder, two-step paged reads, checksum validation.
    • MiniMateClient — high-level client: connect(), get_serial(), get_config(), get_events().
  • TCP/cellular transport (TcpTransport) — connect to field units via Sierra Wireless RV50/RV55 modems over cellular.
    • read_until_idle(idle_gap=1.5s) to handle modem data-forwarding buffer delay.
    • Confirmed working end-to-end: TCP → RV50/RV55 → RS-232 → MiniMate Plus.
  • bridges/tcp_serial_bridge.py — local TCP-to-serial bridge for bench testing TcpTransport without a cellular modem.
  • SFM REST server (sfm/server.py) — FastAPI server with device info, event list, and event record endpoints over both serial and TCP.

Fixed

  • protocol.py startup() was using a hardcoded POLL_RECV_TIMEOUT = 10.0 constant, ignoring the configurable self._recv_timeout. Fixed to use self._recv_timeout throughout.
  • sfm/server.py now retries once on ProtocolError for TCP connections to handle cold-boot timing on first connect.

Protocol / Documentation

  • Sierra Wireless RV50/RV55 modem config — confirmed required ACEmanager settings: Quiet Mode = Enable, Data Forwarding Timeout = 1, TCP Connect Response Delay = 0. Quiet Mode disabled causes modem to inject RING\r\nCONNECT\r\n onto the serial line, breaking the S3 handshake.
  • Calibration year confirmed at SUB FE (Full Config) destuffed payload offset 0x560x57 (uint16 BE). 0x07E7 = 2023, 0x07E9 = 2025.
  • "Operating System" boot string — 16-byte UART boot message captured on cold-start before unit enters DLE-framed mode. Parser handles correctly by scanning for DLE+STX.
  • RV50/RV55 sends RING/CONNECT over TCP to the calling client even with Quiet Mode enabled — this is normal behaviour, parser discards it.

v0.4.0 — 2026-03-12

Added

  • seismo_lab.py — combined Bridge + Analyzer GUI. Single window with two tabs; bridge start auto-wires live mode in the Analyzer.
  • frame_db.py — SQLite frame database. Captures accumulate over time; Query DB tab searches across all sessions.
  • bridges/s3-bridge/proxy.py — bridge proxy module.
  • Large BW→S3 write frame checksum algorithm confirmed and implemented (SUM8 of payload [2:-1] skipping 0x10 bytes, plus constant 0x10, mod 256).
  • SUB A4 identified as composite container frame with embedded inner frames; _extract_a4_inner_frames() and _diff_a4_payloads() reduce diff noise from 2300 → 17 meaningful entries.

Fixed

  • BAD CHK false positives on BW POLL frames — BW frame terminator 03 41 was being included in the de-stuffed payload. Fixed to strip correctly.
  • Aux Trigger read location confirmed at SUB FE offset 0x0109.

v0.3.0 — 2026-03-09

Added

  • Record time confirmed at SUB E5 page2 offset +0x28 as float32 BE.
  • Trigger Sample Width confirmed at BW→S3 write frame SUB 0x82, destuffed payload offset [22].
  • Mode-gating documented: several settings only appear on the wire when the appropriate mode is active.

Fixed

  • 0x082A mystery resolved — fixed-size E5 payload length (2090 bytes), not a record-time field.

v0.2.0 — 2026-03-01

Added

  • Channel config float layout fully confirmed: trigger level, alarm level, and unit string per channel (IEEE 754 BE floats).
  • Blastware .set file format decoded — little-endian binary struct mirroring the wire payload.
  • Operator manual (716U0101 Rev 15) added as cross-reference source.

v0.1.0 — 2026-02-26

Added

  • Initial s3_bridge.py serial bridge — transparent RS-232 tap between Blastware and MiniMate Plus.
  • s3_parser.py — deterministic DLE state machine frame extractor.
  • s3_analyzer.py — session parser, frame differ, Claude export.
  • gui_bridge.py and gui_analyzer.py — Tkinter GUIs.
  • DLE framing confirmed: DLE+STX / DLE+ETX, 0x41 = ACK (not STX), DLE stuffing rule.
  • Response SUB rule confirmed: response_SUB = 0xFF - request_SUB.
  • Year 0x07CB = 1995 confirmed as MiniMate factory RTC default.
  • Full write command family documented (SUBs 6883).