fix: correct monitoring flag and battery/memory offsets in _decode_monitor_status

section[6] is the monitoring flag (was wrongly section[1] — section[1] is always
0x00 in both states). Battery and memory fields use relative-from-end offsets
(section[-11:-9], section[-9:-5], section[-5:-1]) instead of absolute positions,
which broke when the payload grew by 3 bytes in monitoring mode.

Confirmed from full byte diff of 142 0xE3 frames in 4-8-26/2ndtry capture.
SFM start_monitoring now polls /device/monitor/status every 5s for up to 60s
instead of a fixed 25s delay (unit runs ~40s on-device sensor check before
confirming monitoring state).

Also corrects stale 1C→6E response anomaly claim in protocol reference — no
exceptions to the 0xFF−SUB rule are known.
This commit is contained in:
2026-04-08 23:41:11 -04:00
parent dda5683572
commit 990cb8850e
4 changed files with 345 additions and 56 deletions
+92 -9
View File
@@ -586,19 +586,24 @@ Response SUB = 0xFF 0x1C = **0xE3** (standard formula — no exception).
is NOT a reliable mode indicator. Earlier note claiming "12 bytes when monitoring"
was wrong (confirmed 2026-04-08 from 4-8-26/mid-monitor captures).
**Monitoring flag (confirmed from 4-8-26/2ndtry byte-by-byte comparison):**
- `section[1] == 0x00` → unit is **idle**
- `section[1] == 0x10` → unit is **monitoring** (flips exactly at start/stop transitions)
**Monitoring flag (CORRECTED 2026-04-08 — full byte diff of 2ndtry capture):**
- `section[6] == 0x00` → unit is **idle**
- `section[6] == 0x10` → unit is **monitoring**
Battery and memory fields are present in **both** states.
Earlier note claiming `section[1]` was the flag was WRONG — section[1] is always 0x00 in both states. The correction was found by diffing all 0xE3 data frames across the start/stop transitions: `section[6]` is the only byte that flips cleanly at frame #36 (start) and #132 (stop) within the 2ndtry 0xE3 frame sequence.
**Field offsets (relative to `data[11:]` = section, confirmed from 2ndtry IDLE frames):**
Battery and memory fields are present in **both** states, but the payload grows by **3 bytes** when monitoring is active (section goes from ~52 to ~55 bytes), shifting subsequent fields by +3.
| Offset | Field | Type | Notes |
**Field offsets (relative to `data[11:]` = section):**
Battery and memory are at **relative offsets from the end** — the payload can vary by ±13 bytes due to counter jitter and monitoring-mode expansion, but these 10 bytes are always anchored at the end:
| Offset (relative to end) | Field | Type | Notes |
|---|---|---|---|
| `[36:38]` | battery voltage × 100 | uint16 BE | `0x02A8` = 680 → 6.80 V |
| `[38:42]` | memory total (bytes) | uint32 BE | e.g. 983026 ≈ 960 KB |
| `[42:46]` | memory free (bytes) | uint32 BE | decreases as events are stored |
| `section[-11:-9]` | battery voltage × 100 | uint16 BE | `0x02A8` = 680 → 6.80 V |
| `section[-9:-5]` | memory total (bytes) | uint32 BE | e.g. 983026 ≈ 960 KB |
| `section[-5:-1]` | memory free (bytes) | uint32 BE | decreases as events are stored |
| `section[-1]` | frame checksum | — | last byte, skip |
### SESSION_RESET signal (`41 03`) — required for monitoring units
@@ -632,10 +637,88 @@ Wire bytes (confirmed frame 305 of 2ndtry BW capture):
Both start and stop acks are standard 17-byte zero-data S3 frames.
### On-device sensor check behavior (confirmed 2026-04-08)
Confirmed from 4-8-26/sensor-check BW+S3 capture (Blastware "Unit Channel Test" comms
check issued while unit was performing its on-device sensor check).
**Unit IS reachable during on-device sensor check** — POLL (SUB 5B) responded normally
throughout. However, the unit partially handled channel-test commands (SUB 0x0E) for
channels 04 and then went **silent for ~40 seconds** while the sensor check ran, before
resuming responses for channels 57 and the trigger test (SUB 0x98).
Key findings:
- On-device sensor check duration: approximately **40 seconds** (log gap `18:40:48``18:41:28`)
- Unit IS reachable for POLL during the check window — SESSION_RESET + POLL works
- Partial command responses during check are possible (device may buffer some, drop others)
- The Blastware "Unit Channel Test" (remote comms check, SUBs 0x0E + 0x98) is a SEPARATE
operation from the on-device check — it is a passive remote read; the unit's screen does
not change during a remote comms check
**SFM behavior after `POST /device/monitor/start`:** `_pollMonitorConfirm()` polls
`/device/monitor/status` every 5 s for up to 60 s, updating the badge on each poll.
Status will show MONITORING once `section[6]` flips to `0x10`.
### SUBs known from sensor-check capture (4-8-26) — NOT YET IMPLEMENTED
| BW SUB | RSP SUB | Function | Notes |
|---|---|---|---|
| 0x15 | 0xEA | Serial number / short ID | 2-step read; data offset = 0x0A (10 bytes); confirmed serial `"BE11529"` at `data[11+5:]` |
| 0x01 | 0xFE | Device info block | 2-step read; data offset = 0x98 (152 bytes); payload includes serial + firmware + float config fields |
| 0x0E | 0xF1 | Channel sensor data | 2-step read; channel selector in `params[6:8]` (`0x0000``0x0007`); data length 0x0A per channel; used by Blastware "Unit Channel Test" — see docs/ for details |
| 0x98 | 0x67 | Trigger test | Single probe frame (`params[0]=0xFF`); sent twice per test cycle; all-zero data response; used after 0x0E channel scan |
Blastware's "Unit Channel Test" sequence: `POLL×N → 0x15 → 0x01 → 0x08 → 0x01 → 0x0E×8 → 0x98×2 → 0x0E×8` (repeat pass with live ADC readings).
---
## Compliance config field inventory (from Blastware UI, 2026-04-08)
Fields visible in the Blastware Compliance Setup dialog — most are NOT YET decoded to byte
offsets in the raw 1A/E5 payload. Only fields with `✅` have confirmed offsets in the code.
**Recording Setup tab:**
- Recording Mode: Continuous / Single Shot / Histogram (enum)
- Record Stop Mode: Fixed Record Time / Auto / Manual Stop (enum)
- Sample Rate: Standard 1024 / Fast 2048 / Faster 4096 sps ✅ (anchor2)
- Record Time: float, seconds ✅ (anchor+10)
- Histogram Interval: 5 / 15 / 30 / 60 minutes (enum, mode-gated)
- Storage Mode: Save All Data / Save Triggered (enum)
- Geophone Type: Standard Triaxial / 4.5 Hz (bool/enum)
- Geophone Channels: Enable all geophones (bool), Trigger Source (bool)
- Chan 1-3 Trigger Level (float, in/s) ✅ (`trigger_level_geo`)
- Chan 1-3 Maximum Range: Normal 10.000 / 1.25 in/s (enum) ✅ (`max_range_geo`)
- Microphone Channels: Enable all microphones (bool), Trigger Source (bool)
- Chan 4 Trigger Level (dB or psi depending on units)
**Notes tab:**
- Enable User Notes (bool)
- Project, Client, User Name, Seis Loc (ASCII strings) ✅ (sourced from A5 frame 7 via 5A)
- Enable Extended Notes (bool); Extended Notes text; Extended Notes Title
- Enable Job Number (bool); Job Number (int)
- Enable Scaled Distance (bool); Distance from Blast (float); Charge Weight (float) — Scaled Distance is derived
**Special Setups tab:**
- Unit Timer: Timer Mode (Off/On), Start Date/Time, Stop Date/Time
- Self Check: Mode (Off/On), Time (HH:MM)
- Sensor Check: **Before monitoring** / After each event / **Disabled** ❓ (byte offset unknown)
- Measurement Units: Imperial / Metric
- Show Mic units in dB (bool)
- Time Format: 24 Hour / 12 Hour (AM/PM)
- Backlight on Time (seconds) ✅ (event index block +75)
- Power Saving Timeout (minutes) ✅ (event index block +83)
- Monitoring LCD Cycle ✅ (event index block +84:86)
- Set unit time with setup (bool)
The "Sensor Check" dropdown (`Before monitoring` / `After each event` / `Disabled`) has NOT
been located in the raw config bytes. The user's unit always runs with `Before monitoring`.
Full compliance config encoder is a future task.
---
## What's next
- Compliance config encoder — build raw write payloads from a `ComplianceConfig` object
- Locate "Sensor Check" byte in compliance config (need capture with Disabled vs Before-monitoring)
- ACH inbound server — accept call-home connections from field units
- Modem manager — push RV50/RV55 configs via Sierra Wireless API