- Establish v0.5.0 as first versioned release - README rewritten to reflect current scope: Blastware replacement in progress, not just a reverse-engineering capture tool - Documents all current components: seismo_lab.py, minimateplus, sfm/server.py, Console tab, TCP/cellular transport - Adds ACEmanager required settings table (Quiet Mode etc.) - Adds roadmap section - CHANGELOG.md created with entries from v0.1.0 through v0.5.0 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
252 lines
8.4 KiB
Markdown
252 lines
8.4 KiB
Markdown
# seismo-relay `v0.5.0`
|
|
|
|
A ground-up replacement for **Blastware** — Instantel's aging Windows-only
|
|
software for managing MiniMate Plus seismographs.
|
|
|
|
Built in Python. Runs on Windows. Connects to instruments over direct RS-232
|
|
or cellular modem (Sierra Wireless RV50 / RV55).
|
|
|
|
> **Status:** Active development. Core read pipeline working (device info,
|
|
> config, event index). Event download and write commands in progress.
|
|
> See [CHANGELOG.md](CHANGELOG.md) for version history.
|
|
|
|
---
|
|
|
|
## What's in here
|
|
|
|
```
|
|
seismo-relay/
|
|
├── seismo_lab.py ← Main GUI (Bridge + Analyzer + Console tabs)
|
|
│
|
|
├── minimateplus/ ← MiniMate Plus client library
|
|
│ ├── transport.py ← SerialTransport and TcpTransport
|
|
│ ├── protocol.py ← DLE frame layer (read/write/parse)
|
|
│ ├── client.py ← High-level client (connect, get_config, etc.)
|
|
│ ├── framing.py ← Frame builder/parser primitives
|
|
│ └── models.py ← DeviceInfo, EventRecord, etc.
|
|
│
|
|
├── sfm/ ← SFM REST API server (FastAPI)
|
|
│ └── server.py ← /device/info, /device/events, /device/event
|
|
│
|
|
├── bridges/
|
|
│ ├── s3-bridge/
|
|
│ │ └── s3_bridge.py ← RS-232 serial bridge (capture tool)
|
|
│ ├── tcp_serial_bridge.py ← Local TCP↔serial bridge (bench testing)
|
|
│ ├── gui_bridge.py ← Standalone bridge GUI (legacy)
|
|
│ └── raw_capture.py ← Simple raw capture tool
|
|
│
|
|
├── parsers/
|
|
│ ├── s3_parser.py ← DLE frame extractor
|
|
│ ├── s3_analyzer.py ← Session parser, differ, Claude export
|
|
│ ├── gui_analyzer.py ← Standalone analyzer GUI (legacy)
|
|
│ └── frame_db.py ← SQLite frame database
|
|
│
|
|
└── docs/
|
|
└── instantel_protocol_reference.md ← Reverse-engineered protocol spec
|
|
```
|
|
|
|
---
|
|
|
|
## Quick start
|
|
|
|
### Seismo Lab (main GUI)
|
|
|
|
The all-in-one tool. Three tabs: **Bridge**, **Analyzer**, **Console**.
|
|
|
|
```
|
|
python seismo_lab.py
|
|
```
|
|
|
|
### SFM REST server
|
|
|
|
Exposes MiniMate Plus commands as a REST API for integration with other systems.
|
|
|
|
```
|
|
cd sfm
|
|
uvicorn server:app --reload
|
|
```
|
|
|
|
**Endpoints:**
|
|
|
|
| Method | URL | Description |
|
|
|--------|-----|-------------|
|
|
| `GET` | `/device/info?port=COM5` | Device info via serial |
|
|
| `GET` | `/device/info?host=1.2.3.4&tcp_port=9034` | Device info via cellular modem |
|
|
| `GET` | `/device/events?port=COM5` | Event index |
|
|
| `GET` | `/device/event?port=COM5&index=0` | Single event record |
|
|
|
|
---
|
|
|
|
## Seismo Lab tabs
|
|
|
|
### Bridge tab
|
|
|
|
Captures live RS-232 traffic between Blastware and the seismograph. Sits in
|
|
the middle as a transparent pass-through while logging everything to disk.
|
|
|
|
```
|
|
Blastware → COM4 (virtual) ↔ s3_bridge ↔ COM5 (physical) → MiniMate Plus
|
|
```
|
|
|
|
Set your COM ports and log directory, then hit **Start Bridge**. Use
|
|
**Add Mark** to annotate the capture at specific moments (e.g. "changed
|
|
trigger level"). When the bridge starts, the Analyzer tab automatically wires
|
|
up to the live files and starts updating in real time.
|
|
|
|
### Analyzer tab
|
|
|
|
Parses raw captures into DLE-framed protocol sessions, diffs consecutive
|
|
sessions to show exactly which bytes changed, and lets you query across all
|
|
historical captures via the built-in SQLite database.
|
|
|
|
- **Inventory** — all frames in a session, click to drill in
|
|
- **Hex Dump** — full payload hex dump with changed-byte annotations
|
|
- **Diff** — byte-level before/after diff between sessions
|
|
- **Full Report** — plain text session report
|
|
- **Query DB** — search across all captures by SUB, direction, or byte value
|
|
|
|
Use **Export for Claude** to generate a self-contained `.md` report for
|
|
AI-assisted field mapping.
|
|
|
|
### Console tab
|
|
|
|
Direct connection to a MiniMate Plus — no bridge, no Blastware. Useful for
|
|
diagnosing field units over cellular without a full capture session.
|
|
|
|
**Connection:** choose Serial (COM port + baud) or TCP (IP + port for
|
|
cellular modem).
|
|
|
|
**Commands:**
|
|
| Button | What it does |
|
|
|--------|-------------|
|
|
| POLL | Startup handshake — confirms unit is alive and identifies model |
|
|
| Serial # | Reads unit serial number |
|
|
| Full Config | Reads full 166-byte config block (firmware version, channel scales, etc.) |
|
|
| Event Index | Reads stored event list |
|
|
|
|
Output is colour-coded: TX in blue, raw RX bytes in teal, decoded fields in
|
|
green, errors in red. **Save Log** writes a timestamped `.log` file to
|
|
`bridges/captures/`. **Send to Analyzer** injects the captured bytes into the
|
|
Analyzer tab for deeper inspection.
|
|
|
|
---
|
|
|
|
## Connecting over cellular (RV50 / RV55 modems)
|
|
|
|
Field units connect via Sierra Wireless RV50 or RV55 cellular modems. Use
|
|
TCP mode in the Console or SFM:
|
|
|
|
```
|
|
# Console tab
|
|
Transport: TCP
|
|
Host: <modem public IP>
|
|
Port: 9034 ← Device Port in ACEmanager (call-up mode)
|
|
```
|
|
|
|
```python
|
|
# In code
|
|
from minimateplus.transport import TcpTransport
|
|
from minimateplus.client import MiniMateClient
|
|
|
|
client = MiniMateClient(transport=TcpTransport("1.2.3.4", 9034))
|
|
info = client.connect()
|
|
```
|
|
|
|
### Required ACEmanager settings (Serial tab)
|
|
|
|
These must match exactly — a single wrong setting causes the unit to beep
|
|
on connect but never respond:
|
|
|
|
| Setting | Value | Why |
|
|
|---------|-------|-----|
|
|
| Configure Serial Port | `38400,8N1` | Must match MiniMate baud rate |
|
|
| Flow Control | `None` | Hardware flow control blocks unit TX if pins unconnected |
|
|
| **Quiet Mode** | **Enable** | **Critical.** Disabled → modem injects `RING`/`CONNECT` onto serial line, corrupting the S3 handshake |
|
|
| Data Forwarding Timeout | `1` (= 0.1 s) | Lower latency; `5` works but is sluggish |
|
|
| TCP Connect Response Delay | `0` | Non-zero silently drops the first POLL frame |
|
|
| TCP Idle Timeout | `2` (minutes) | Prevents premature disconnect |
|
|
| DB9 Serial Echo | `Disable` | Echo corrupts the data stream |
|
|
|
|
---
|
|
|
|
## minimateplus library
|
|
|
|
```python
|
|
from minimateplus import MiniMateClient
|
|
from minimateplus.transport import SerialTransport, TcpTransport
|
|
|
|
# Serial
|
|
client = MiniMateClient(port="COM5")
|
|
|
|
# TCP (cellular modem)
|
|
client = MiniMateClient(transport=TcpTransport("1.2.3.4", 9034), timeout=30.0)
|
|
|
|
with client:
|
|
info = client.connect() # DeviceInfo — model, serial, firmware
|
|
serial = client.get_serial() # Serial number string
|
|
config = client.get_config() # Full config block (bytes)
|
|
events = client.get_events() # Event index
|
|
```
|
|
|
|
---
|
|
|
|
## Protocol quick-reference
|
|
|
|
| Term | Value | Meaning |
|
|
|------|-------|---------|
|
|
| DLE | `0x10` | Data Link Escape |
|
|
| STX | `0x02` | Start of frame |
|
|
| ETX | `0x03` | End of frame |
|
|
| ACK | `0x41` (`'A'`) | Frame-start marker sent before every frame |
|
|
| DLE stuffing | `10 10` on wire | Literal `0x10` in payload |
|
|
|
|
**S3-side frame** (seismograph → Blastware): `ACK DLE+STX [payload] CHK DLE+ETX`
|
|
|
|
**De-stuffed payload header:**
|
|
```
|
|
[0] CMD 0x10 = BW request, 0x00 = S3 response
|
|
[1] ? unknown (0x00 BW / 0x10 S3)
|
|
[2] SUB Command/response identifier ← the key field
|
|
[3] PAGE_HI Page address high byte
|
|
[4] PAGE_LO Page address low byte
|
|
[5+] DATA Payload content
|
|
```
|
|
|
|
**Response SUB rule:** `response_SUB = 0xFF - request_SUB`
|
|
Example: request SUB `0x08` (Event Index) → response SUB `0xF7`
|
|
|
|
Full protocol documentation: [`docs/instantel_protocol_reference.md`](docs/instantel_protocol_reference.md)
|
|
|
|
---
|
|
|
|
## Requirements
|
|
|
|
```
|
|
pip install pyserial fastapi uvicorn
|
|
```
|
|
|
|
Python 3.10+. Tkinter is included with the standard Python installer on
|
|
Windows (make sure "tcl/tk and IDLE" is checked during install).
|
|
|
|
---
|
|
|
|
## Virtual COM ports (bridge capture)
|
|
|
|
The bridge needs two COM ports on the same PC — one that Blastware connects
|
|
to, and one wired to the seismograph. Use a virtual COM port pair
|
|
(**com0com** or **VSPD**) to give Blastware a port to talk to.
|
|
|
|
```
|
|
Blastware → COM4 (virtual) ↔ s3_bridge.py ↔ COM5 (physical) → MiniMate Plus
|
|
```
|
|
|
|
---
|
|
|
|
## Roadmap
|
|
|
|
- [ ] Event download — pull waveform records from the unit (SUBs `1E` → `0A` → `0C` → `5A`)
|
|
- [ ] Write commands — push config changes to the unit (compliance setup, channel config, trigger settings)
|
|
- [ ] ACH inbound server — accept call-home connections from field units
|
|
- [ ] Modem manager — push standard configs to RV50/RV55 fleet via Sierra Wireless API
|
|
- [ ] Full Blastware parity — complete read/write/download cycle without Blastware
|