feat: add histogram_interval setting and update UI with new field.
This commit is contained in:
+54
-36
@@ -847,9 +847,10 @@ class MiniMateClient:
|
||||
self,
|
||||
*,
|
||||
# Recording parameters
|
||||
recording_mode: Optional[int] = None,
|
||||
sample_rate: Optional[int] = None,
|
||||
record_time: Optional[float] = None,
|
||||
recording_mode: Optional[int] = None,
|
||||
sample_rate: Optional[int] = None,
|
||||
record_time: Optional[float] = None,
|
||||
histogram_interval_sec: Optional[int] = None,
|
||||
# Threshold parameters (geo channels, in/s)
|
||||
trigger_level_geo: Optional[float] = None,
|
||||
alarm_level_geo: Optional[float] = None,
|
||||
@@ -919,6 +920,7 @@ class MiniMateClient:
|
||||
recording_mode=recording_mode,
|
||||
sample_rate=sample_rate,
|
||||
record_time=record_time,
|
||||
histogram_interval_sec=histogram_interval_sec,
|
||||
trigger_level_geo=trigger_level_geo,
|
||||
alarm_level_geo=alarm_level_geo,
|
||||
project=project,
|
||||
@@ -1657,12 +1659,13 @@ def _encode_compliance_config(
|
||||
sample_rate: Optional[int] = None,
|
||||
record_time: Optional[float] = None,
|
||||
trigger_level_geo: Optional[float] = None,
|
||||
alarm_level_geo: Optional[float] = None,
|
||||
project: Optional[str] = None,
|
||||
client_name: Optional[str] = None,
|
||||
operator: Optional[str] = None,
|
||||
seis_loc: Optional[str] = None,
|
||||
notes: Optional[str] = None,
|
||||
alarm_level_geo: Optional[float] = None,
|
||||
histogram_interval_sec: Optional[int] = None,
|
||||
project: Optional[str] = None,
|
||||
client_name: Optional[str] = None,
|
||||
operator: Optional[str] = None,
|
||||
seis_loc: Optional[str] = None,
|
||||
notes: Optional[str] = None,
|
||||
) -> bytes:
|
||||
"""
|
||||
Patch a live 2126-byte compliance buffer (read from the device) with any
|
||||
@@ -1674,13 +1677,14 @@ def _encode_compliance_config(
|
||||
DLE-jitter shifts):
|
||||
|
||||
Anchor: b'\\xbe\\x80\\x00\\x00\\x00\\x00' (confirmed stable, both BE11529 and BE18189)
|
||||
recording_mode → uint8 at anchor_pos - 7 (write payload; one byte earlier than read format)
|
||||
Values: 0x00=Single Shot, 0x01=Continuous, 0x03=Histogram, 0x04=Histogram+Continuous
|
||||
NOTE: In the E5 read response the field is at anchor_pos - 8 due to an extra
|
||||
0x10 byte at anchor_pos - 7 present only in the read format. The write
|
||||
payload does NOT have this extra byte — use anchor_pos - 7 here.
|
||||
sample_rate → uint16 BE at anchor_pos - 6
|
||||
record_time → float32 BE at anchor_pos + 6
|
||||
recording_mode → uint8 at anchor_pos - 7 (write payload)
|
||||
Values: 0x00=Single Shot, 0x01=Continuous, 0x03=Histogram, 0x04=Histogram+Continuous
|
||||
NOTE: In the E5 read response (decode) field is at anchor_pos - 8 due to an
|
||||
extra 0x10 byte at read anchor_pos - 7. Write payload has no extra byte.
|
||||
sample_rate → uint16 BE at anchor_pos - 6
|
||||
histogram_interval_sec → uint16 BE at anchor_pos - 4 (seconds; mode-gated to Histogram/Histogram+Continuous)
|
||||
Valid values: 2, 5, 15, 60, 300, 900 (= 2s, 5s, 15s, 1m, 5m, 15m)
|
||||
record_time → float32 BE at anchor_pos + 6
|
||||
|
||||
Channel block (anchored on b"Tran" with unit-string guard):
|
||||
trigger_level_geo → float32 BE at tran_pos + 34
|
||||
@@ -1730,6 +1734,14 @@ def _encode_compliance_config(
|
||||
struct.pack_into(">H", buf, _anc - 6, sample_rate)
|
||||
log.debug("_encode_compliance_config: sample_rate=%d -> offset %d", sample_rate, _anc - 6)
|
||||
|
||||
if histogram_interval_sec is not None:
|
||||
if _anc < 4:
|
||||
log.warning("_encode_compliance_config: anchor not found — cannot write histogram_interval")
|
||||
else:
|
||||
struct.pack_into(">H", buf, _anc - 4, histogram_interval_sec)
|
||||
log.debug("_encode_compliance_config: histogram_interval=%ds -> offset %d",
|
||||
histogram_interval_sec, _anc - 4)
|
||||
|
||||
if record_time is not None:
|
||||
if _anc < 0 or _anc + 10 > len(buf):
|
||||
log.warning("_encode_compliance_config: anchor not found — cannot write record_time")
|
||||
@@ -1841,29 +1853,27 @@ def _decode_compliance_config_into(data: bytes, info: DeviceInfo) -> None:
|
||||
except Exception as exc:
|
||||
log.warning("compliance_config: setup_name extraction failed: %s", exc)
|
||||
|
||||
# ── Record time + sample rate — anchor-relative ───────────────────────────
|
||||
# The 10-byte anchor sits between sample_rate and record_time in the cfg.
|
||||
# Absolute offsets are NOT reliable because sample_rate = 4096 (0x1000) is
|
||||
# DLE-escaped in the raw S3 frame (10 10 00 → 10 00 after unstuffing),
|
||||
# making frame C 1 byte shorter than for 1024/2048 and shifting everything.
|
||||
# sample_rate: uint16_BE at anchor - 2
|
||||
# record_time: float32_BE at anchor + 10
|
||||
# 6-byte suffix anchor — confirmed stable across BE11529 and bench unit (BE18189).
|
||||
# The preceding 4 bytes (old anchor prefix 01 2c / 00 3c) vary by unit config;
|
||||
# only be 80 00 00 00 00 is constant.
|
||||
# sample_rate : uint16 BE at anchor_pos - 6
|
||||
# record_time : float32 BE at anchor_pos + 6
|
||||
# ── recording_mode / sample_rate / histogram_interval / record_time ─────────
|
||||
# 6-byte stable anchor: b'\xbe\x80\x00\x00\x00\x00' — confirmed across BE11529
|
||||
# and BE18189. The 4 bytes immediately before the anchor are NOT constant:
|
||||
# bytes -4:-2 are the histogram_interval (uint16 BE, seconds), and bytes -2:0
|
||||
# are zero padding. The old "10-byte anchor" (\x01\x2c\x00\x00 prefix) was
|
||||
# only constant when the histogram interval happened to be 5 min (0x012C = 300).
|
||||
#
|
||||
# E5 read format layout relative to 6-byte anchor:
|
||||
# _anchor - 8 : recording_mode (uint8)
|
||||
# _anchor - 7 : 0x10 (extra byte E5 read only; absent in SUB 71 write)
|
||||
# _anchor - 6 : sample_rate_hi (uint16 BE, MSB)
|
||||
# _anchor - 5 : sample_rate_lo (uint16 BE, LSB)
|
||||
# _anchor - 4 : histogram_interval_hi (uint16 BE, seconds, MSB)
|
||||
# _anchor - 3 : histogram_interval_lo (uint16 BE, seconds, LSB)
|
||||
# _anchor - 2 : 0x00 (padding)
|
||||
# _anchor - 1 : 0x00 (padding)
|
||||
# _anchor : \xbe\x80\x00\x00\x00\x00 (6-byte anchor)
|
||||
# _anchor + 6 : record_time (float32 BE)
|
||||
_ANCHOR = b'\xbe\x80\x00\x00\x00\x00'
|
||||
_anchor = data.find(_ANCHOR, 0, 150)
|
||||
if _anchor >= 8 and _anchor + 10 <= len(data):
|
||||
# Layout (E5 read format, relative to 6-byte anchor suffix):
|
||||
# _anchor - 8 : recording_mode (uint8)
|
||||
# _anchor - 7 : 0x10 (extra byte present in E5 read only; absent in SUB 71 write)
|
||||
# _anchor - 6 : sample_rate_hi (uint8, MSB of uint16 BE)
|
||||
# _anchor - 5 : sample_rate_lo (uint8, LSB of uint16 BE)
|
||||
# _anchor - 4 : \x01\x2c\x00\x00 (10-byte anchor prefix)
|
||||
# _anchor : \xbe\x80\x00\x00\x00\x00 (6-byte anchor suffix)
|
||||
# _anchor + 6 : record_time (float32 BE)
|
||||
try:
|
||||
config.recording_mode = data[_anchor - 8]
|
||||
log.debug(
|
||||
@@ -1878,6 +1888,14 @@ def _decode_compliance_config_into(data: bytes, info: DeviceInfo) -> None:
|
||||
)
|
||||
except Exception as exc:
|
||||
log.warning("compliance_config: sample_rate extraction failed: %s", exc)
|
||||
try:
|
||||
config.histogram_interval_sec = struct.unpack_from(">H", data, _anchor - 4)[0]
|
||||
log.debug(
|
||||
"compliance_config: histogram_interval = %d s (anchor@%d)",
|
||||
config.histogram_interval_sec, _anchor
|
||||
)
|
||||
except Exception as exc:
|
||||
log.warning("compliance_config: histogram_interval extraction failed: %s", exc)
|
||||
try:
|
||||
config.record_time = struct.unpack_from(">f", data, _anchor + 6)[0]
|
||||
log.debug(
|
||||
|
||||
Reference in New Issue
Block a user