github ilyakruchinin/SomnoTrace v4.0.0-beta4

latest release: v4.0.0-beta5
pre-release2 hours ago

SomnoTrace v4.0.0-beta4

The SomnoBridge release. πŸŒ‰ SomnoTrace now pairs, provisions, time-syncs
and pulls therapy data through the Wi-Fi↔BLE bridge β€” the AirSense's SD
card never has to leave the machine.

beta4 fixes the one thing that could stop you pairing at all: a local
NimBLE bond-store limit made every SomnoBridge pairing attempt fail with
"bridge refused pairing" β€” while the bridge was never even contacted.

✨ New since v4.0.0-beta3

πŸ”— SomnoBridge pairing β€” local bond-store failures fixed

  • Pairing no longer fails before the bridge is contacted β€” NimBLE's
    SM layer refuses to start pairing when its capacity check
    (ble_sm_chk_store_overflow) trips, returning BLE_HS_ENOTSUP (8)
    synchronously. That check counts stored bonds plus any active SMP
    procedure
    against CONFIG_BT_NIMBLE_MAX_BONDS β€” which was 2 (and 1
    in the shipped defaults). One stored bridge bond plus a single live
    pairing procedure was enough to block every attempt. The failure was
    then reported as "bridge refused pairing β€” FORGET_PEER is required",
    which sent users to reset the bridge for no reason.
  • Bond store now self-heals β€” registered a store-status callback
    that evicts the oldest peer bond (ble_store_util_delete_oldest_peer)
    when the store reports FULL, instead of refusing to pair.
  • Capacity raised β€” CONFIG_BT_NIMBLE_MAX_BONDS 2 β†’ 4, and
    sdkconfig.defaults 1 β†’ 4 (a clean build from defaults could not
    pair anything at all).
  • Honest diagnostics β€” rc=8 now logs "local SM refusal β€” bond store
    full; the bridge was never contacted", and the portal reports
    "pairing blocked locally (bond store)" instead of blaming the bridge.
  • No more spurious "Pair failed" β€” a connect still winding down
    answers EBUSY (15); the pair op now retries once after 400 ms
    instead of surfacing an error on a quick second press.
  • Verified on hardware β€” NVS bond-store dump (IDF
    nvs_partition_tool) confirmed a single valid bridge bond (LTK
    present, LESC, authenticated); live pairing completes
    encrypted, authenticated and bonded β†’ paired β†’ subscribed.

✨ New since v4.0.0-beta1

πŸ’Ύ SomnoBridge "Configure" dialog β€” smarter Save & Test

  • Join is now verified, not assumed β€” after saving a custom card
    password, the dialog polls the bridge's real link state
    (GET_STATUS.sta_connected, 1 s Γ— 12) instead of running a redundant
    probe-join. Success shows "Bridge joined the card"; a typo'd password
    gets a clear red error instead of a false "good".
  • Security probe only when it matters β€” the factory-password check
    now runs only when the saved password is 88888888 or the card is
    open. Custom passwords skip it entirely.
  • Dialog closes itself on success β€” the button flips to OK and the
    window auto-dismisses; nothing left to configure means nothing left
    on screen. It stays open on any failure.
  • GET_STATUS added to the /api/sb/op proxy whitelist;
    EZSHARE_CHECK timeout raised 25 s β†’ 32 s.

✍️ Portal wording β€” data-source direction made explicit (#345)

  • Pairing card renamed "ResMed Series 11 / SomnoBridge" β€” covers
    AirSense 11 and AirCurve 11 plus the bridge path (was "ResMed
    AirSense 11 CPAP" even though it pairs a SomnoBridge too).
  • Scan button renamed "Scan for ResMed / SomnoBridge".
  • Upload Window now states the direction: "days recorded on this
    device
    are uploaded from SomnoTrace to the destinations above" β€”
    plus a note that SomnoTrace records live over Bluetooth and cannot
    import history stored on the SD card inside your CPAP machine.
  • Reset Upload State description and confirm dialog say the same,
    and now correctly state the upload-window cap instead of "all days".
  • Maintenance section says "the SomnoTrace SD card" β€” no more
    ambiguity about which card an action touches.

πŸ› Fixes

  • πŸ“Š Dashboard could shimmer forever β€” with no sessions recorded,
    the "Connecting & loading sessions…" progress bar was never
    dismissed; "No sessions recorded yet" appeared only as a small muted
    line. This is what looked like an 18-hour hang in #345. The dashboard
    now stops loading and explains the empty state in one line.

Everything in v4.0.0-beta1

✨ Highlights

  • πŸŒ‰ SomnoBridge integration β€” a complete BLE client (sb_ble,
    ~1.5k LoC): discovery, passkey pairing, bonded GATT ops over the
    framed protocol, streaming file pulls, and a /api/sb/op HTTP proxy
    that drives every bridge op from the portal.
  • πŸ• Authoritative UTC & drift correction β€” SomnoTrace anchors its
    NTP time on the bridge's monotonic clock with periodic exchanges,
    reads back the fitted drift on every sync pass, and applies the
    estimate when importing sessions β€” AS11 clock wander is corrected
    instead of silently skewing therapy data.
  • βš™οΈ "Configure SomnoBridge" dialog β€” card network picker (scrollable
    AP list, OPEN/SECURED badges, saved network), AS10/AS11 machine cards
    with the AS11 GMT-offset picker, an X close button, and an
    insecure-card flow: factory 88888888 and open cards are detected by
    a real probe-join, flagged with a warning, and can be re-secured
    in-place via EZSHARE_ADMIN β€” the bridge changes the card's own Wi-Fi
    password through its admin form and rejoins automatically.
  • πŸ“Š Bridge status in the portal β€” pairing state, card Wi-Fi,
    therapy-active and transfer-allowed indicators, last sync, and sync
    progress straight from the bridge.
  • πŸ“₯ Session augmentation β€” late-recovered stream files now merge
    into already-committed sessions instead of being discarded as
    duplicates; coverage is verified against the manifest and annotations
    are regenerated byte-identically.

πŸ› Fixes

  • πŸ—‚οΈ Duplicate recording folders β€” oximetry day labels are now a pure
    function of the recording's civil digits (ESP-local noon rule) and an
    existing recording_id under any day folder wins β€” DST/offset changes
    can no longer file one recording under two days.
  • πŸ” Uploader fingerprint ping-pong β€” duplicate recording_ids across
    day folders are deduplicated in reconcile (newest day wins) so two
    files can never take turns invalidating each other's uploads.
  • πŸ›‘ Retry storms β€” any unit that fails 5 uploads is parked and
    retried at most once a day, reviving automatically when its content
    changes. A local anomaly can never again become hours of HTTP 429s.
  • πŸ“± Logs tab scroll β€” narrow screens no longer open the log view at
    the oldest line of a page-long scrollback.

πŸ—οΈ Under the hood

  • sb_proto request/response framing with reassembly; BLE ops run off
    the NimBLE host task so provisioning never starves indications.
  • Transfer ledger coordination keeps already-downloaded card files from
    re-pulling β€” zero redundant transfers across reconnects.
  • edf_import events rendering extracted behind a byte-identical
    emit-to-file / emit-to-set abstraction for coverage checks.
  • AS11 BLE: connection handling improvements alongside the bridge path.

βœ… Testing

  • New sb_ble_test host suite: 153 checks covering pairing state
    machine, framing, reassembly and op dispatch.
  • somno_ml_worker survivor tests: guards, deadlines, SST checks,
    fragment grouping.
  • Full host suite: 31 targets, 0 failures, sanitizer-clean.

πŸ“š Docs

  • Windows 10/11 SMB share setup guide with screenshots (contributed).

Don't miss a new SomnoTrace release

NewReleases is sending notifications on new releases.