From 7e501620fca17fbe38e6e5d331dd3dcfc65ac199 Mon Sep 17 00:00:00 2001 From: Brian Harrison Date: Wed, 1 Apr 2026 13:07:04 -0400 Subject: [PATCH] fix: skip trigger/alarm extraction pending offset confirmation The heuristic offsets for trigger/alarm levels were causing struct unpack errors. These fields require detailed field mapping from actual E5 captures to determine exact byte positions relative to channel labels. For now, skip extraction and leave trigger_level_geo/alarm_level_geo as None. This prevents the '500 Device error: bytes must be in range(0, 256)' error. Once we capture an E5 response and map the exact float positions, we can re-enable this section with correct offsets. Co-Authored-By: Claude Haiku 4.5 --- minimateplus/client.py | 37 ++++--------------------------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/minimateplus/client.py b/minimateplus/client.py index dbb977e..a709d75 100644 --- a/minimateplus/client.py +++ b/minimateplus/client.py @@ -608,39 +608,10 @@ def _decode_compliance_config_into(data: bytes, info: DeviceInfo) -> None: log.warning("compliance_config: failed to unpack record_time at offset 0x28") # ── Per-channel trigger/alarm levels (✅ CONFIRMED at §7.6) ───────────────── - # Layout repeats per channel: [padding][max_range][padding][trigger]["in.\0"][alarm]["/s\0\0"][flag][label] - # For now, extract just the first geo channel (Transverse) as a representative. - try: - # Search for the "Tran" label to locate the first geo channel block - tran_pos = data.find(b"Tran") - if tran_pos > 0: - # Work backward from the label to find trigger and alarm - # From §7.6: trigger float is ~20 bytes before the label, alarm is ~8 bytes before - # Exact structure: [padding2][trigger_float][unit "in."][alarm_float][unit "/s"] - # We'll search backward for the last float before the label - # The trigger/alarm block format is complex; for now use heuristics - - # Look for trigger level at a few standard offsets relative to label - # From protocol: trigger is usually at label_offset - 14 - if tran_pos >= 14: - try: - trigger = struct.unpack_from(">f", data, tran_pos - 14)[0] - config.trigger_level_geo = trigger - log.debug("compliance_config: trigger_level_geo = %.3f in/s", trigger) - except (struct.error, ValueError): - pass - - # Alarm is usually after the "in." unit string following trigger - # Try offset tran_pos - 6 - if tran_pos >= 6: - try: - alarm = struct.unpack_from(">f", data, tran_pos - 6)[0] - config.alarm_level_geo = alarm - log.debug("compliance_config: alarm_level_geo = %.3f in/s", alarm) - except (struct.error, ValueError): - pass - except Exception as exc: - log.warning("compliance_config: trigger/alarm extraction failed: %s", exc) + # Layout (per §7.6): [padding2][max_range][padding][trigger]["in.\0"][alarm]["/s\0\0"][flag][label] + # Exact byte offsets relative to label require detailed field mapping from actual captures. + # For now, we skip extraction — this section will be populated once we have precise offsets. + # TODO: Capture E5 response and map exact trigger/alarm float positions # ── Project strings (from E5 / SUB 71 payload) ──────────────────────────── try: