github ilyakruchinin/SomnoTrace v2.1.0

3 hours ago

๐Ÿš€ 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)
  • โš™๏ธ Portal Configuration Card: Configure your broker URL (mqtt:// or mqtts://), 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 offline status 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/sessions endpoint to include sa2_samples counts 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.c where 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 in scripts/edf_gen_test.c.

๐Ÿ”’ Memory & Concurrency Hardening

  • ๐Ÿ›ก๏ธ Protected session_writer_get_duration_min() under s_active_mutex to 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.

Don't miss a new SomnoTrace release

NewReleases is sending notifications on new releases.