fix: serial decode offset, PPV label scan, debug mode for waveform records

- _decode_serial_number: read from data[11:] not data[:8] — was returning
  the LENGTH_ECHO byte (0x0A = '\n') instead of the serial string
- _extract_peak_floats: search for channel label strings ("Tran" etc) and
  read float at label+6; old step-4 aligned scan was reading trigger levels
  instead of PPV values
- get_events: add debug=False param; stashes raw 210-byte record on
  Event._raw_record when True for field-layout inspection
- server /device/events: add ?debug=true query param; includes
  raw_record_hex + raw_record_len in response when set
- models: add Event._raw_record optional bytes field
This commit is contained in:
Brian Harrison
2026-03-31 23:46:07 -04:00
parent 9f52745bb4
commit f74992f4e5
3 changed files with 32 additions and 11 deletions

View File

@@ -126,8 +126,8 @@ def _serialise_device_info(info: DeviceInfo) -> dict:
}
def _serialise_event(ev: Event) -> dict:
return {
def _serialise_event(ev: Event, debug: bool = False) -> dict:
d: dict = {
"index": ev.index,
"timestamp": _serialise_timestamp(ev.timestamp),
"sample_rate": ev.sample_rate,
@@ -135,6 +135,11 @@ def _serialise_event(ev: Event) -> dict:
"peak_values": _serialise_peak_values(ev.peak_values),
"project_info": _serialise_project_info(ev.project_info),
}
if debug:
raw = getattr(ev, "_raw_record", None)
d["raw_record_hex"] = raw.hex() if raw else None
d["raw_record_len"] = len(raw) if raw else 0
return d
# ── Transport factory ─────────────────────────────────────────────────────────
@@ -257,6 +262,7 @@ def device_events(
baud: int = Query(38400, description="Serial baud rate"),
host: Optional[str] = Query(None, description="TCP host — modem IP or ACH relay"),
tcp_port: int = Query(DEFAULT_TCP_PORT, description=f"TCP port (default {DEFAULT_TCP_PORT})"),
debug: bool = Query(False, description="Include raw record hex for field-layout inspection"),
) -> dict:
"""
Connect to the device, read the event index, and download all stored
@@ -264,15 +270,18 @@ def device_events(
Supply either *port* (serial) or *host* (TCP/modem).
Pass debug=true to include raw_record_hex in each event — useful for
verifying field offsets against the protocol reference.
This does NOT download raw ADC waveform samples — those are large and
fetched separately via GET /device/event/{idx}/waveform (future endpoint).
"""
log.info("GET /device/events port=%s host=%s", port, host)
log.info("GET /device/events port=%s host=%s debug=%s", port, host, debug)
try:
def _do():
with _build_client(port, baud, host, tcp_port) as client:
return client.connect(), client.get_events()
return client.connect(), client.get_events(debug=debug)
info, events = _run_with_retry(_do, is_tcp=_is_tcp(host))
except HTTPException:
raise
@@ -286,7 +295,7 @@ def device_events(
return {
"device": _serialise_device_info(info),
"event_count": len(events),
"events": [_serialise_event(ev) for ev in events],
"events": [_serialise_event(ev, debug=debug) for ev in events],
}