Skip to content

feat: /api/iq_capture + /api/record_analyze signal diagnostics#27

Closed
hunterhubble wants to merge 2 commits into
HubbleNetwork:mainfrom
hunterhubble:iq-capture
Closed

feat: /api/iq_capture + /api/record_analyze signal diagnostics#27
hunterhubble wants to merge 2 commits into
HubbleNetwork:mainfrom
hunterhubble:iq-capture

Conversation

@hunterhubble

Copy link
Copy Markdown
Contributor

Summary

Adds two RX diagnostic endpoints so a customer can capture and characterise a device's signal against protocol expectations, without needing the live GUI.

1. GET /api/iq_capture?seconds=N — records N s (1–60) of raw IQ forward from now and returns a .npy (complex64) download with X-Sample-Rate-Hz / X-Center-Freq-Hz / X-N-Samples headers.

2. GET /api/record_analyze?seconds=N — records N s (1–30) and returns a plain-text diagnostic report file the customer sends back. For the representative decoded packet it prints, per symbol:

  • Timing — duration, inter-symbol gap, and clock drift vs the ideal 8 ms/0.8 ms grid.
  • Frequency / channel hopping — dominant tone per symbol vs the expected (calibrated) channel window, with a PASS/FAIL count.
  • Amplitude — per-symbol RMS dBFS and SNR above the inter-symbol noise floor.

Plus decoder-reported chipset / synth-res, frequency offset, and Reed-Solomon correction counts, and a one-line summary per packet.

Scope / design

  • Decoded packets only for now — the report characterises devices that decode locally (the common bench case). Diagnosing packets that don't decode is deliberately left for a later iteration.
  • Values are printed as-measured — no timing tolerances or margin verdicts (the only pass/fail is the channel-window check, whose tolerances are defined by the protocol).
  • Reuses existing DSPcorrect_symbol_edges for symbol edges; shared helpers were factored into timing.py (dominant_symbol_freq, symbol_amplitudes_dbfs) and config.py (packet_symbol_grid, rotated_hop_sequence) and are now also called by spectrogram.py / processor.py, removing pre-existing duplication.
  • Analysis runs in the Flask handler on a copied buffer (like iq_capture), so the live spectrogram isn't stalled; capture is serialised by a shared lock.

Files

  • src/stream_web/analysis.py (new) — the diagnostic pipeline (detection → per-symbol analyses → report).
  • src/stream_web/app.pyiq_capture + record_analyze routes, shared _capture_iq helper.
  • src/stream_web/{timing,config,spectrogram,processor}.py — shared symbol-DSP / geometry helpers.
  • CLAUDE.md — endpoint docs.

Testing

  • ruff check src/ clean; mock test suite 12/12 pass.
  • Verified end-to-end on a recorded capture: per-symbol tables render, channel validation 60/60 in-window.

🤖 Generated with Claude Code

Helpful for:
- Extra signal processing through numpy or matplotlib
- Recording samples with pyhubblenetwork
- Testing Satellite hardware with IQ samples from real devices
- Determining the frequency of a continuous tone

Signed-off-by: hunterhubble <hunter@hubble.com>
Signed-off-by: hunterhubble <hunter@hubble.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant