Changes since v1.0.7
Oximetry
- Persistent-mode polling: Added an experimental persistent BLE connection mode for the O2 Ring that uses sparse unauthenticated
cmd=0x04queries at 30-second intervals, eliminating repeated connect/discovery/auth/setup cycles and reducing heart-rate artifacts caused by reconnection bursts. - Upload support: Added full oximetry upload pipeline with separate transport scope, canonical format generation (VLD3 export for SleepHQ, full directory tree for SMB), and per-unit state tracking with fingerprinting.
- SleepHQ summary fix: VLD v3 export now copies precomputed summary statistics (avg SpO₂, lowest SpO₂, drops ≥ 3%, drops ≥ 4%, time < 90%, distinct desat episodes, O₂ score, avg HR) from the O2 Ring's Format A trailer into the VLD header fields that SleepHQ reads for its summary panel. Previously these header bytes were left as zero, causing missing or zeroed-out summary metrics on SleepHQ.
- Invalid-value normalization: SpO₂ and HR values of
0(Format A invalid sentinel) are now written as0xFFin VLD records, and the invalid flag byte uses0xFFinstead of0x01, matching the VLD v3 spec and preventing SleepHQ from interpreting invalid readings as real 0% SpO₂. - Canonical conversion reliability: Simplified error handling and added FATFS rename-over workaround in the canonical conversion pipeline. Added comprehensive logging to help diagnose migration failures.
- Deferred migration: Moved canonical oximetry migration to a background task so it no longer blocks
app_mainstartup.
Dashboard / Web UI
- Unified oximetry charts: Integrated oximetry panels (SpO₂, pulse) directly into the main dashboard alongside CPAP charts, with an optional "clamp to CPAP times" toggle that filters oximetry data to the therapy window.
- SpO₂ line rendering fix: Aligned the SpO₂ gradient canvas rendering with uPlot's pixel-grid alignment, eliminating blurry/thin lines on high-DPI displays.
- Unified line width: All dashboard graphs now use a consistent 0.75 CSS-pixel line width for a cleaner, more uniform appearance.
- Flow Limit axis: Removed the fixed y-axis ceiling on the Flow Limit graph; it now scales dynamically from 0 to the data maximum.
- Zoom scroll fix: Fixed a bug where clicking reset-zoom or zooming out to full range caused the page to jump to the top on desktop. Reset now updates existing charts in-place instead of destroying and rebuilding the entire chart DOM.
- Terminology: Replaced "session" with "part" in upload UI and status messages for clarity.
- Screenshots: Updated web dashboard screenshot with corrected aspect ratio.
Documentation
- AirSense 11 pairing guide: Added step-by-step BLE pairing instructions for the AirSense 11, linked from the README and flashing guide.
System / Stability
- NVS safety: Serialized all NVS reads through
nvs_writer_runand eliminated unsafe PSRAM pointer access by copying arguments to internal-stack locals. Doublednvs_writerstack to 8 KB with a low-watermark warning to catch potential overflows. - WebSocket reliability: Refactored WebSocket send operations to use
httpd_queue_workand increased thews_fwdstack to 12 KB. - FATFS compatibility: Added
unlink()beforerename()inupload_ox_saveto work around FATFS's inability to rename over an existing file, fixing a bug where oximetry upload state was not persisted across reboots, causing repeated re-uploads. - SPIRAM: Large buffers now allocated in SPIRAM when available.