feat: implement geophone sensitivity and recording mode settings in compliance config
This commit is contained in:
+43
-16
@@ -854,6 +854,7 @@ class MiniMateClient:
|
||||
# Threshold parameters (geo channels, in/s)
|
||||
trigger_level_geo: Optional[float] = None,
|
||||
alarm_level_geo: Optional[float] = None,
|
||||
geo_range: Optional[int] = None, # 0x00=Normal 10in/s, 0x01=Sensitive 1.25in/s
|
||||
# Project / operator strings
|
||||
project: Optional[str] = None,
|
||||
client_name: Optional[str] = None,
|
||||
@@ -875,9 +876,11 @@ class MiniMateClient:
|
||||
sample_rate : int — samples/sec; valid values: 1024, 2048, 4096
|
||||
record_time : float — record duration in seconds (e.g. 2.0, 3.0)
|
||||
|
||||
Trigger/alarm thresholds (geo channels, in/s):
|
||||
trigger_level_geo : float — trigger threshold (e.g. 0.5)
|
||||
alarm_level_geo : float — alarm threshold (e.g. 1.0)
|
||||
Trigger/alarm thresholds and range (geo channels):
|
||||
trigger_level_geo : float — trigger threshold in/s (e.g. 0.5)
|
||||
alarm_level_geo : float — alarm threshold in/s (e.g. 1.0)
|
||||
geo_range : int — 0x00=Normal 10.000 in/s, 0x01=Sensitive 1.250 in/s
|
||||
(written to Tran/Vert/Long channel blocks)
|
||||
|
||||
Project / operator strings (max 41 ASCII characters each):
|
||||
project : str
|
||||
@@ -923,6 +926,7 @@ class MiniMateClient:
|
||||
histogram_interval_sec=histogram_interval_sec,
|
||||
trigger_level_geo=trigger_level_geo,
|
||||
alarm_level_geo=alarm_level_geo,
|
||||
geo_range=geo_range,
|
||||
project=project,
|
||||
client_name=client_name,
|
||||
operator=operator,
|
||||
@@ -1660,6 +1664,7 @@ def _encode_compliance_config(
|
||||
record_time: Optional[float] = None,
|
||||
trigger_level_geo: Optional[float] = None,
|
||||
alarm_level_geo: Optional[float] = None,
|
||||
geo_range: Optional[int] = None, # 0x00=Normal 10in/s, 0x01=Sensitive 1.25in/s
|
||||
histogram_interval_sec: Optional[int] = None,
|
||||
project: Optional[str] = None,
|
||||
client_name: Optional[str] = None,
|
||||
@@ -1687,11 +1692,16 @@ def _encode_compliance_config(
|
||||
record_time → float32 BE at anchor_pos + 6
|
||||
|
||||
Channel block (anchored on b"Tran" with unit-string guard):
|
||||
geo_range → uint8 at tran_pos + 33 (confirmed 2026-04-20)
|
||||
0x00 = Normal 10.000 in/s, 0x01 = Sensitive 1.250 in/s
|
||||
Written to Tran, Vert, Long channel blocks (all three).
|
||||
adc_scale_factor → float32 BE at tran_pos + 28 (= 6.206053; do NOT write)
|
||||
trigger_level_geo → float32 BE at tran_pos + 34
|
||||
"in.\\x00" → unit string at tran_pos + 38 (layout guard)
|
||||
alarm_level_geo → float32 BE at tran_pos + 42
|
||||
NOTE: tran_pos + 28 (float32 = 6.206053) is the ADC-to-velocity scale factor
|
||||
(= 1/sensitivity, in/s per V) for the standard Instantel geophone. Confirmed
|
||||
from Interface Handbook §4.5: Range = 1.61133 V × 6.206053 = 10.000 in/s.
|
||||
"/s\\x00\\x00" → unit string at tran_pos + 46 (layout guard)
|
||||
NOTE: tran_pos+28 (float32 = 6.206053) is the ADC-to-velocity scale factor
|
||||
(= 1/sensitivity, (in/s)/V — Interface Handbook §4.5: 1.61133 V × 6.206053 = 10.000 in/s).
|
||||
This is a hardware/firmware constant common to all MiniMate Plus S3 units.
|
||||
It must NOT be written — do not add it back as a parameter.
|
||||
|
||||
@@ -1750,10 +1760,11 @@ def _encode_compliance_config(
|
||||
log.debug("_encode_compliance_config: record_time=%.3f -> offset %d", record_time, _anc + 6)
|
||||
|
||||
# ── Numeric: channel block (Tran label + unit-string guard) ───────────────
|
||||
# NOTE: tran_pos+28 (float32 = 6.206053) is the ADC-to-velocity scale factor
|
||||
# (1/sensitivity, (in/s)/V — Interface Handbook §4.5: 1.61133 V × 6.206053 = 10.000 in/s).
|
||||
# Hardware/firmware constant — never written here.
|
||||
_needs_channel = any(v is not None for v in (trigger_level_geo, alarm_level_geo))
|
||||
# NOTE: tran_pos+24 (write format) or tran_pos+28 (E5 read format) is the
|
||||
# ADC-to-velocity scale factor (6.206053, hardware constant — never written).
|
||||
# geo_range is written to ALL THREE geo channel blocks (Tran, Vert, Long),
|
||||
# confirmed from 4-20-26 captures showing the byte at label+29 in each block.
|
||||
_needs_channel = any(v is not None for v in (trigger_level_geo, alarm_level_geo, geo_range))
|
||||
if _needs_channel:
|
||||
_tran = buf.find(b"Tran", 44)
|
||||
_valid = (
|
||||
@@ -1766,7 +1777,7 @@ def _encode_compliance_config(
|
||||
if not _valid:
|
||||
log.warning(
|
||||
"_encode_compliance_config: 'Tran' channel block not found or unit "
|
||||
"guard failed — trigger/alarm will not be written"
|
||||
"guard failed — trigger/alarm/geo_range will not be written"
|
||||
)
|
||||
else:
|
||||
if trigger_level_geo is not None:
|
||||
@@ -1775,6 +1786,19 @@ def _encode_compliance_config(
|
||||
if alarm_level_geo is not None:
|
||||
struct.pack_into(">f", buf, _tran + 42, alarm_level_geo)
|
||||
log.debug("_encode_compliance_config: alarm_level_geo=%.4f -> offset %d", alarm_level_geo, _tran + 42)
|
||||
if geo_range is not None:
|
||||
# Write geo_range to all three geo channel blocks (Tran, Vert, Long).
|
||||
# Field at label+33 in the E5-format compliance bytes (same in read and write
|
||||
# since the 2126-byte payload is round-tripped verbatim).
|
||||
# 0x00 = Normal 10.000 in/s, 0x01 = Sensitive 1.250 in/s.
|
||||
for _ch_label in (b"Tran", b"Vert", b"Long"):
|
||||
_ch = buf.find(_ch_label, 44)
|
||||
if _ch >= 0 and buf[_ch + 4 : _ch + 5] != b"2" and _ch + 34 <= len(buf):
|
||||
buf[_ch + 33] = geo_range & 0xFF
|
||||
log.debug(
|
||||
"_encode_compliance_config: geo_range=0x%02X -> %s+33 offset %d",
|
||||
geo_range, _ch_label.decode(), _ch + 33,
|
||||
)
|
||||
|
||||
# ── ASCII strings (64-byte slot, value at label_pos+22) ───────────────────
|
||||
def _set_string(label: bytes, value: Optional[str]) -> None:
|
||||
@@ -1958,12 +1982,15 @@ def _decode_compliance_config_into(data: bytes, info: DeviceInfo) -> None:
|
||||
# download capture. Cross-checked 2026-04-17 across both BE11529 and BE18189.
|
||||
#
|
||||
# "Tran" label at tran_pos (+0 to +3)
|
||||
# max_range_enum uint8 at tran_pos + 20 (range selector: 0x01=10in/s, 0x00=1.25in/s — unconfirmed)
|
||||
# adc_scale float32_BE at tran_pos + 28 (= 1/sensitivity = 6.206053 (in/s)/V; confirmed: 1.61133 V × 6.206053 = 10.000 in/s Normal range; hardware constant — do NOT write)
|
||||
# adc_scale float32_BE at tran_pos + 28 (= 1/sensitivity = 6.206053 (in/s)/V; hardware constant — do NOT write)
|
||||
# geo_range uint8 at tran_pos + 33 CONFIRMED 2026-04-20
|
||||
# 0x00 = Normal 10.000 in/s, 0x01 = Sensitive 1.250 in/s
|
||||
# Same offset in E5 read and SUB 71 write (bytes are round-tripped verbatim).
|
||||
# NOTE: tran_pos+20 reads 0x01 on ALL captures — constant flag, NOT range field.
|
||||
# trigger float32_BE at tran_pos + 34 (e.g. 0.600000 in/s) ✅
|
||||
# "in.\x00" unit string at tran_pos + 38 ✅ confirmed
|
||||
# "in.\x00" unit string at tran_pos + 38 ✅ confirmed (layout guard)
|
||||
# alarm float32_BE at tran_pos + 42 (e.g. 1.250000 in/s) ✅
|
||||
# "/s\x00\x00" unit string at tran_pos + 46 ✅ confirmed
|
||||
# "/s\x00\x00" unit string at tran_pos + 46 ✅ confirmed (layout guard)
|
||||
#
|
||||
# Unit strings serve as layout anchors — if they match, the float offsets
|
||||
# are reliable. Skip "Tran2" (a later repeated label) via the +4 check.
|
||||
@@ -1976,7 +2003,7 @@ def _decode_compliance_config_into(data: bytes, info: DeviceInfo) -> None:
|
||||
and data[tran_pos + 38 : tran_pos + 42] == b"in.\x00"
|
||||
and data[tran_pos + 46 : tran_pos + 50] == b"/s\x00\x00"
|
||||
):
|
||||
config.geo_range = data[tran_pos + 20] # range selector (0x01=Normal 10in/s, 0x00=Sensitive 1.25in/s — unconfirmed)
|
||||
config.geo_range = data[tran_pos + 33] # CONFIRMED 2026-04-20: 0x00=Normal 10in/s, 0x01=Sensitive 1.25in/s
|
||||
config.geo_adc_scale = struct.unpack_from(">f", data, tran_pos + 28)[0] # hw scale factor (in/s)/V — do NOT write
|
||||
config.trigger_level_geo = struct.unpack_from(">f", data, tran_pos + 34)[0]
|
||||
config.alarm_level_geo = struct.unpack_from(">f", data, tran_pos + 42)[0]
|
||||
|
||||
Reference in New Issue
Block a user