Files
seismo-relay/docs/sub_0x1c_analysis.md
claude a41e7a9e1a feat: Add monitoring functionality to MiniMate protocol and web interface
- Introduced new SUBs for monitoring status, start, and stop commands in protocol.py.
- Implemented read_monitor_status, start_monitoring, and stop_monitoring methods in MiniMateProtocol class.
- Added new API endpoints for monitoring status retrieval and control in server.py.
- Enhanced the web application with a monitoring panel, including battery and memory status display.
- Created a new Python script to parse SUB 0x1C response frames for monitoring status.
- Documented the monitoring status response format and field locations in markdown and text files.
2026-04-08 14:34:42 -04:00

275 lines
7.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SUB 0x1C — Monitoring Status Response Format
**Capture file:** `/sessions/intelligent-nice-wright/mnt/seismo-relay/bridges/captures/4-8-26/2ndtry/raw_s3_20260408_015927.bin`
**Analysis date:** 2026-04-08
---
## Overview
SUB 0x1C is a monitoring status query that returns different sized responses depending on device state:
- **IDLE/OFF (unit not monitoring):** 58-byte response with detailed fields
- **MONITORING/ON (unit actively monitoring):** 12-byte response with condensed format
The key fields CONFIRMED from wire capture analysis:
| Field | Offset | Format | Value (Idle) | Notes |
|-------|--------|--------|-------------|-------|
| **Monitor Mode** | [00] | uint8 | 0x2c (OFF) | 0x2c = Idle, 0x00 = Monitoring |
| **Day** | [0d] | uint8 | 0x08 | 131 |
| **Hour** | [0e] | uint8 | 0x10 | 023 (16 = 4 PM) |
| **Month** | [0f] | uint8 | 0x04 | 112 (April) |
| **Year** | [10:12] | uint16 BE | 0x07ea | 2026 |
| **Minute** | [12] | uint8 | 0x00 | 059 |
| **Second** | [13] | uint8 | 0x01 | 059 (but this seems off) |
| **Battery Voltage** | [2f:31] | uint16 BE, ÷100 | 0x02a8 | 680 → 6.80V |
| **Memory Total** | [31:35] | uint32 BE | 0x000efff2 | 983,026 bytes = 960.0 KB |
| **Memory Free** | [35:39] | uint32 BE | 0x000e9e52 | 958,034 bytes = 935.6 KB |
---
## Idle Frame (58 bytes) — Full Hex Dump
```
00: 2c 00 00 00 00 00 00 00 00 00 00 00 00 08 10 04 ,...............
10: 07 ea 00 01 3b 2d 00 00 00 00 00 00 01 01 07 cb ....;-..........
20: 00 06 00 00 01 01 07 cb 00 15 00 00 00 00 10 02 ................
30: a8 00 0e ff f2 00 0e 9e 52 ef ........R.
```
### Field Breakdown
**[00:01] = Monitor Mode**
```
Offset 00: 0x2c = 44 (decimal)
Interpretation: Unit is NOT currently monitoring (idle/off state)
Counter-example in monitoring frame: 0x00 (ON state)
```
**[01:0d] = Padding/Reserved (12 bytes of zeros)**
```
Offsets 01-0c: all 0x00
```
**[0d:12] = Timestamp (5 bytes)**
```
Offset 0d: 0x08 = 8 → DAY
Offset 0e: 0x10 = 16 → HOUR (4 PM)
Offset 0f: 0x04 = 4 → MONTH (April)
Offset 10-11: 0x07ea → YEAR (big-endian: 2026)
= 2026-04-08, 16:??:??
```
**[12:14] = Time (minute/second, ambiguous)**
```
Offset 12: 0x00 = 0 → Likely MINUTE
Offset 13: 0x01 = 1 → Likely SECOND
But this seems too low; may be wrong interpretation
```
**[14:16] = Unknown (2 bytes)**
```
Offset 14: 0x3b = 59 (decimal) - could be seconds?
Offset 15: 0x2d = 45 (decimal)
```
**[16:2f] = Unknown/Filler (25 bytes)**
```
Contains various device-specific configuration or state bytes.
Some patterns suggest repeating data structures (e.g., 01 01 07 cb appears twice).
```
**[2f:31] = Battery Voltage (2 bytes, uint16 BE, divide by 100)**
```
Offset 2f-30: 0x02a8
= 680 (decimal)
÷ 100 = 6.80 volts
Expected: ~6.8V ✓ CONFIRMED
```
**[31:35] = Memory Total (4 bytes, uint32 BE)**
```
Offset 31-34: 0x000efff2
= 983,026 (decimal, bytes)
÷ 1024 = 960.0 KB ✓ CONFIRMED
(Device spec: ~960 KB)
```
**[35:39] = Memory Free (4 bytes, uint32 BE)**
```
Offset 35-38: 0x000e9e52
= 958,034 (decimal, bytes)
÷ 1024 = 935.6 KB ✓ CONFIRMED
(Expected: ~936 KB)
```
**[39:3a] = Trailing byte**
```
Offset 39: 0xef = 239
```
---
## Monitoring Frame (12 bytes) — Condensed Response
When the unit is actively monitoring, the response shrinks to 12 bytes:
```
00: 00 00 00 00 2c 00 00 00 00 00 00 1f ....,.......
```
### Changes from Idle
| Field | Idle Frame | Monitoring Frame | Note |
|-------|------------|------------------|------|
| Monitor Mode | [00] = 0x2c | [04] = 0x2c → may shift or invert | Moved to offset [04]? |
| Size | 58 bytes | 12 bytes | Truncated response; only status, no detail |
| [0b] | varies | 0x1f | New/different byte at end |
**Interpretation:**
- The response layout changes based on monitoring state
- In monitoring mode, many detailed fields are suppressed
- The monitor_mode indicator may move or encode differently
---
## Date/Time Interpretation
The timestamp at [0d:12] uses this layout (confirmed from capture):
```
[0d] = DAY (131) = 0x08 = 8
[0e] = HOUR (023) = 0x10 = 16 (4 PM)
[0f] = MONTH (112) = 0x04 = 4 (April)
[10:12] = YEAR (uint16 BE) = 0x07ea = 2026
```
**Timestamp extracted:** 2026-04-08 16:??:??
Minutes and seconds are less clear:
- [12] = 0x00 → possibly minute
- [13] = 0x01 → possibly second (but unusually low)
- [14] = 0x3b = 59 (redundant second marker?)
---
## Voltage Encoding
Battery voltage is stored as **uint16 big-endian, divide by 100:**
```
[2f:31] = 0x02a8
Raw value: 680
Voltage: 680 / 100 = 6.80 V
Expected: ~6.8V ✓
```
Other attempted decodings (all ruled out):
- `÷1000`: 0.680V (too low)
- `÷10`: 68V (too high)
- float32 BE/LE: no match in range 68V
- Fixed-point: no other range matched
---
## Memory Encoding
Both fields use **uint32 big-endian, in bytes:**
```
Memory Total:
[31:35] = 0x000efff2 = 983,026 bytes = 960.0 KB
Memory Free:
[35:39] = 0x000e9e52 = 958,034 bytes = 935.6 KB
Sanity check: free < total ✓
Free percentage: 935.6 / 960.0 = 97.5% (plausible)
```
---
## Monitor Mode Field Transitions
**Idle/OFF State:**
```
[00] = 0x2c (decimal 44)
```
**Monitoring/ON State (response shrinks to 12 bytes):**
```
Byte layout shifts; [04] carries 0x2c or another value
Possible interpretation: the byte moves, or encoding inverts
```
**Confirmed behavior:**
- When idle: byte [00] = 0x2c, response is 58 bytes
- When monitoring: byte position shifts to [04], response is 12 bytes
- Value 0x2c appears to mean "OFF" or "not actively streaming"
- Value 0x00 appears to mean "ON" or "actively streaming"
---
## Unknown Fields (for future analysis)
The following regions have been observed but their purpose is unclear:
| Range | Hex (Idle) | Notes |
|-------|----------|-------|
| [01:0d] | all 0x00 | Padding or reserved? |
| [14:16] | 3b 2d | 59, 45 — possibly countdown timers or other state |
| [16:2f] | mixed | Appears to contain device configuration snapshots; pattern repeats suggest sub-structures (e.g., trigger levels, calibration dates) |
---
## Wire Frame Structure (S3 Format)
Raw S3 response for SUB 0x1C (response SUB = 0xE3):
```
[DLE=0x10][STX=0x02][destuffed_payload+chk][bare ETX=0x03]
Destuffed payload:
[0] CMD = 0x00
[1] flags = 0x10
[2] SUB = 0xE3 (response)
[3] PAGE_HI = 0x00
[4] PAGE_LO = 0x00
[5+] data = 58 or 12 bytes (depending on mode)
```
---
## Summary Table (Idle/OFF State)
| Field | Bytes | Value | Interpretation |
|-------|-------|-------|------------------|
| Monitor Mode | [00] | 0x2c | Device idle (not streaming) |
| Reserved | [01:0d] | 0x00×12 | Padding |
| **Date/Time** | — | — | — |
| Day | [0d] | 0x08 | 8th |
| Hour | [0e] | 0x10 | 16 (4 PM) |
| Month | [0f] | 0x04 | April |
| Year | [10:12] | 0x07ea | 2026 |
| Minute | [12] | 0x00 | 00 (uncertain) |
| Second | [13] | 0x01 | 01 (uncertain) |
| Unknown | [14:2f] | — | 27 bytes of mixed data |
| **Battery** | — | — | — |
| Voltage | [2f:31] | 0x02a8 | 6.80 V (BE ÷100) |
| **Memory** | — | — | — |
| Total | [31:35] | 0x000efff2 | 960.0 KB (BE) |
| Free | [35:39] | 0x000e9e52 | 935.6 KB (BE) |
| Trailer | [39:3a] | 0xef | Unknown (1 byte) |
---
## Next Steps
1. **Verify minute/second fields** — Compare against multiple captures to confirm [12:14] layout
2. **Decode unknown region [16:2f]** — Likely contains trigger levels, calibration dates, alarm thresholds
3. **Monitoring mode byte position** — Confirm whether it truly moves to [04] in the monitoring response or if response layout is completely different
4. **Min/max voltage limits** — Check if voltage ever deviates from 6.8V to validate encoding
5. **Memory dynamics** — Track total/free across sessions to understand flash layout