๐ SomnoTrace v2.1.0 โ Release Changelog
Changes since v2.0.5 ๐
โจ Highlights
- ๐ Experimental MQTT & Home Assistant Integration: Seamless auto-discovery, live device telemetry, and bidirectional CPAP controls right from your smart home dashboard!
- ๐ซ AirSense 11 Oximetry Support: View pulse and SpOโ data from AirSense 11 (Nonin) directly in the Web Portal dashboard, complete with an oximetry source toggle when you've got both Nonin and O2 Ring data.
- โฑ๏ธ Smarter Session Discontinuity Handling: Tightened split threshold from 2 minutes down to 10 seconds to keep flat, fabricated data out of clinical scoring (OSCAR / SleepHQ), with precise backdated session timestamps.
- ๐ท๏ธ EDF Annotation Deduplication Fix: Interleaved duplicate events at the exact same onset timestamp now deduplicate cleanly every time.
๐ New Features
1. ๐ Home Assistant & MQTT Integration (Experimental)
SomnoTrace can now publish real-time telemetry and accept remote commands via any standard MQTT broker!
- ๐ช Automatic Discovery: Publishes standard Home Assistant discovery payloads so your entities set themselves up automaticallyโno manual YAML wrestling required!
- ๐ Sensors & Telemetry: Reports live therapy status (
in_therapy), mask-off alerts, session duration, device uptime, and pending cloud upload counts every 60 seconds (with instant bypass on state changes). - ๐ฎ Bidirectional Controls:
- ๐จ Start or stop CPAP therapy (
cmd/therapy) - ๐ Acknowledge or silence the mask-off buzzer alarm (
cmd/alert) - โ๏ธ Trigger an immediate background scan/retry for pending uploads (
cmd/uploader)
- ๐จ Start or stop CPAP therapy (
- โ๏ธ Portal Configuration Card: Configure your broker URL (
mqtt://ormqtts://), credentials, topic prefix, and discovery toggle directly in the Web Portal under Settings. - ๐ก๏ธ Robust FreeRTOS Concurrency & Safety:
- ๐ฆ Zero Stalls: Blocking Bluetooth RPCs are offloaded to a dedicated background telemetry queue so your network client and web server stay buttery smooth.
- ๐ Thread-Safe RPCs: The Bluetooth command channel is serialized with a dedicated mutex (
s_cmd_mtx), preventing race conditions between physical hardware buttons, Web API calls, and incoming MQTT commands. - ๐ซ No Replay Surprises: Safely ignores stale retained commands on reconnect so therapy doesn't toggle unintentionally.
- ๐ Graceful Offline State: Automatically publishes a retained
offlinestatus when disabled or reconfigured.
2. ๐ซ Native AirSense 11 Oximetry in Dashboard
- ๐ The Web Portal dashboard now parses and graphs AirSense 11 pulse rate and blood oxygen waveforms (
SA2.snt), recorded when an attached Nonin Xpod or paired oximeter is in use. - ๐ Added a handy toggle to "Prefer AirSense 11 oximetry over O2 Ring", which pops up dynamically whenever both Nonin and Wellue/O2 Ring data exist for the same day.
- ๐ Extended the
/api/sessionsendpoint to includesa2_samplescounts with expanded JSON payload headroom.
๐ ๏ธ Bug Fixes & Reliability Improvements
โฑ๏ธ Discontinuity Splitting & Accurate Split Boundaries
- ๐ฉบ Clinical Integrity: Reduced the session split threshold from 120 seconds down to 10 seconds (>= 50 missing 200 ms notifications). Short pauses (< 10 s) are safely held to absorb AirSense 11 internal SD card write latency without losing waveform phase, while true radio dropouts (>= 10 s) cleanly split the session rather than fabricating minutes of flat data that could manufacture artificial apneas in clinical scoring software (OSCAR / SleepHQ).
- ๐ฏ Accurate Split Timestamps: Backdated the finalized session end time to
now - gap(the exact instant stream data stopped) rather than the wall-clock time when the split was triggered.
๐ท๏ธ EDF Annotation Deduplication Fix (PR #274)
- ๐ Fixed an issue in
edf_annotations.cwhere duplicate annotations sharing the same onset timestamp survived deduplication if another event label was interleaved (e.g.[A, B, A]at the same second). - ๐ค Event labels now serve as the tie-breaker during sorting, guaranteeing identical
(onset, label)pairs are strictly adjacent before the deduplication pass runs. - ๐งช Factored sorting and deduplication into
sort_and_dedup_events()and added dedicated host unit tests inscripts/edf_gen_test.c.
๐ Memory & Concurrency Hardening
- ๐ก๏ธ Protected
session_writer_get_duration_min()unders_active_mutexto eliminate read races against asynchronous session finalization. - ๐พ Right-sized MQTT client buffers from 2048 B to 1024 B, freeing up 2 KiB of precious internal SRAM for Wi-Fi and Bluetooth coexistence.
- โณ Migrated device uptime calculations to a 64-bit microsecond hardware timer (
esp_timer_get_time()) to kiss the 49.7-day 32-bit tick rollover goodbye! - ๐ Switched MAC address retrieval to
esp_read_mac(ESP_MAC_WIFI_STA)for robust client ID generation independent of Wi-Fi driver state. - ๐งผ Sanitized topic prefix input against invalid characters (spaces, wildcards, separators) both in the web frontend and C backend.
๐ Credits & Acknowledgements
- ๐ @Plantucha (Michal Planicka) โ for diagnosing the annotation deduplication edge-case and implementing the label tie-break sorting and unit tests in PR #274.
- ๐ ๏ธ @ilyakruchinin (Ilya Kruchinin) โ for designing and implementing the experimental MQTT/Home Assistant integration, AirSense 11 oximetry dashboard support, session split improvements, and concurrency hardening.