feat: implement SUB 1A (compliance config) read
Adds full support for reading device compliance configuration (2090-byte E5 response) containing record time, trigger/alarm levels, and project strings. protocol.py: - Implement read_compliance_config() two-step read (SUB 1A → E5) - Fixed length 0x082A (2090 bytes) models.py: - Add ComplianceConfig dataclass with fields: record_time, sample_rate, trigger_level_geo, alarm_level_geo, max_range_geo, project strings - Add compliance_config field to DeviceInfo client.py: - Implement _decode_compliance_config_into() to extract: * Record time float at offset +0x28 ✅ * Trigger/alarm levels per-channel (heuristic parsing) 🔶 * Project/setup strings from E5 payload * Placeholder for sample_rate (location TBD ❓) - Update connect() to read SUB 1A after SUB 01, cache in device_info - Add ComplianceConfig to imports sfm/server.py: - Add _serialise_compliance_config() JSON encoder - Include compliance_config in /device/info response - Updated _serialise_device_info() to output compliance config Both record_time (at fixed offset 0x28) and project strings are ✅ CONFIRMED from protocol reference §7.6. Trigger/alarm extraction uses heuristics pending more detailed field mapping from captured data. Sample rate remains undiscovered in the E5 payload — likely in the mystery flags at offset +0x12 or requires a "fast mode" capture. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -180,6 +180,9 @@ class DeviceInfo:
|
||||
manufacturer: Optional[str] = None # e.g. "Instantel" ✅
|
||||
model: Optional[str] = None # e.g. "MiniMate Plus" ✅
|
||||
|
||||
# ── From SUB 1A (COMPLIANCE_CONFIG_RESPONSE) ──────────────────────────────
|
||||
compliance_config: Optional["ComplianceConfig"] = None # E5 response, read in connect()
|
||||
|
||||
def __str__(self) -> str:
|
||||
fw = self.firmware_version or f"?.{self.firmware_minor}"
|
||||
mdl = self.model or "MiniMate Plus"
|
||||
@@ -253,6 +256,44 @@ class ProjectInfo:
|
||||
notes: Optional[str] = None # extended notes
|
||||
|
||||
|
||||
# ── Compliance Config ──────────────────────────────────────────────────────────
|
||||
|
||||
@dataclass
|
||||
class ComplianceConfig:
|
||||
"""
|
||||
Device compliance and recording configuration from SUB 1A (response E5).
|
||||
|
||||
Contains device-wide settings like record time, trigger/alarm thresholds,
|
||||
and operator-supplied strings. This is read once during connect() and
|
||||
cached in DeviceInfo.
|
||||
|
||||
All fields are optional — some may not be decoded yet or may be absent
|
||||
from the device configuration.
|
||||
"""
|
||||
raw: Optional[bytes] = None # full 2090-byte payload (for debugging)
|
||||
|
||||
# Recording parameters (✅ CONFIRMED from §7.6)
|
||||
record_time: Optional[float] = None # seconds (7.0, 10.0, 13.0, etc.)
|
||||
sample_rate: Optional[int] = None # sps (1024, 2048, 4096, etc.) — NOT YET FOUND ❓
|
||||
|
||||
# Trigger/alarm levels (✅ CONFIRMED per-channel at §7.6)
|
||||
# For now we store the first geo channel (Transverse) as representatives;
|
||||
# full per-channel data would require structured Channel objects.
|
||||
trigger_level_geo: Optional[float] = None # in/s (first geo channel)
|
||||
alarm_level_geo: Optional[float] = None # in/s (first geo channel)
|
||||
max_range_geo: Optional[float] = None # in/s full-scale range
|
||||
|
||||
# Project/setup strings (sourced from E5 / SUB 71 write payload)
|
||||
# These are the FULL project metadata from compliance config,
|
||||
# complementing the sparse ProjectInfo found in the waveform record (SUB 0C).
|
||||
setup_name: Optional[str] = None # "Standard Recording Setup"
|
||||
project: Optional[str] = None # project description
|
||||
client: Optional[str] = None # client name
|
||||
operator: Optional[str] = None # operator / user name
|
||||
sensor_location: Optional[str] = None # sensor location string
|
||||
notes: Optional[str] = None # extended notes / additional info
|
||||
|
||||
|
||||
# ── Event ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
@dataclass
|
||||
|
||||
Reference in New Issue
Block a user