Skip to content

windows: build the drivers in CI, heart-rate docs, and the HR graph in the app - #10

Merged
arctumn merged 5 commits into
windows-nativefrom
windows/heart-rate-mtu
Sep 29, 2026
Merged

arctumn merged 5 commits into
windows-nativefrom
windows/heart-rate-mtu

Conversation

@arctumn

@arctumn arctumn commented Sep 29, 2026 •

Copy link
Copy Markdown
Owner

Summary

This finishes what #9 started, which was merged before these landed on the branch. It adds:

Changes

  • ci-windows.yml:
    • The runner is pinned to windows-2022, because windows-latest's VS2026 lacks WDK integration for WindowsKernelModeDriver10.0.
    • It installs the SDK and WDK 10.0.26100 via winget and builds LibrePodsAAP.vcxproj (/p:EnableInf2cat=false) and AudioCodec.sln.
    • It then regenerates both catalogs with Inf2Cat and overwrites windows/drivers/*/prebuilt, so make-dist.ps1 bundles the fresh builds.
    • PRs that touch the workflow now run it too.
    • The WDK-via-winget approach and the 2022 pin come from the Gab4545/librepods fork, which built the mic driver this way.
  • HeartRateCard:
    • The graph shows the last 24 readings, scaled around their centre with a 20 bpm minimum span, with a faint bar per reading, the line, and a dot on the newest (same shape as PR Add experimental AirPods heart-rate monitoring and RSSI librepods-org/librepods#702's HeartRateMiniGraph).
    • The daemon only pushes on BPM change, so the card samples at 1 Hz.
    • The InfoBar is now informational, in 4 locales, and there is a caption for the graph.
  • Docs: heart-rate.md, windows/README.md, windows/docs/README.md.

Added since opening

  • Releases carry the drivers: the CI-built driver packages are uploaded as a librepods-windows-drivers artifact and attached as LibrePods-Windows-drivers.zip to the nightly and versioned releases (1fe6932).
  • Heart-rate history in SQLite (b599677): the daemon stores every reading in %LOCALAPPDATA%\LibrePods\heart-rate.sqlite3 (sessions + samples with confidence), using rusqlite with SQLite bundled.
  • HR card v2 (88daa92):
    • the graph spans the card (last minute), with a BPM axis, min/avg/max and a hover readout;
    • a Readings picker shows past sessions from the DB (read-only, Microsoft.Data.Sqlite);
    • heart rate is no longer experimental: the card is always shown, and only hearing aid stays behind the opt-in.
  • README (b682565): heart-rate section, release assets, CI-built drivers, where the data lives.

Test

  • The WinUI app builds locally (VS MSBuild, Release x64).
  • CI runs for e3c8853, b599677 and 1fe6932 are green. They build both drivers, the daemon (with rusqlite) and the app, and upload the drivers artifact.
  • The SQLite tracking was verified live: 1 Hz rows, 72–81 bpm, confidence 236–239.

🤖 Generated with Claude Code

arctumn and others added 5 commits September 29, 2026 21:42
…and what was ruled out

heart-rate.md said there was no working heart rate on Windows and blamed a
host-privilege gate. Rewrite it around what was actually found: the AAP channel's
672-byte inbound MTU kept the AirPods from publishing the ~920-byte HEARTRATE
descriptors; requesting 1691 (ConfigIn on bthport) fixes it. Document what the
daemon sends (84 → reported on 20, 19 NAKs on iOS 27 firmware) and decodes (BPM
byte 1, confidence byte 2 gated at 0x80, tails), keep the ruled-out list, and
note that 0x0E is the activity classifier. Update the README and docs index.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on and app

The pipeline only built the daemon and the WinUI app and bundled the committed
prebuilt driver packages, so a driver source change (the AAP channel's 1691-byte
MTU that heart rate needs) never reached the install folder or the nightly.

Build the AAP (LibrePodsAAP.vcxproj) and hi-res mic (AudioCodec.sln) drivers on
the runner with the WDK installed via winget, regenerate their catalogs with
Inf2Cat, and overwrite windows/drivers/*/prebuilt so make-dist.ps1 bundles the
fresh builds. The WDK's own post-build Inf2Cat is disabled for the AAP project
(it runs before the .sys sits next to the .inf); the catalog is made afterwards.
Pinned to windows-2022: windows-latest's VS2026 lacks WDK integration for the
WindowsKernelModeDriver10.0 toolset. PRs touching the workflow now run it too.

WDK-via-winget approach and the windows-2022 pin come from the Gab4545/librepods
fork, which built the mic driver this way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t may not work

Add the recent-readings graph from upstream PR librepods-org#702's HeartRateMiniGraph to the
heart-rate card: the last 24 readings, scaled around their centre with a 20 bpm
minimum span, a faint bar per reading, the line, and a dot on the newest; three
guide lines while there's no data. The daemon only pushes a snapshot when the BPM
changes, so the card samples the latest value once a second to follow the
stream's 1 Hz cadence.

The InfoBar is now informational ("works on AirPods Pro 3, the first reading
takes a few seconds") in en-US/pt-PT/es-ES/fr-FR, with a caption for the graph,
and DevicePage's comment no longer claims heart rate can't work on Windows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every validated reading is stored in %LOCALAPPDATA%\LibrePods\heart-rate.sqlite3
(its own file, WAL):

- sessions(id, device, started_at, ended_at): opened by the first reading, closed
  when HR is switched off, the buds disconnect or the user disconnects; another
  pair of buds starts its own session.
- samples(id, session_id, ts, bpm, confidence): Unix ms, BPM and the sensor's
  confidence byte (the decoder now returns it alongside the BPM).

Writes go through a channel to one writer thread so the AAP receive loop never
waits on the disk; if the file can't be opened, tracking is disabled with a log
line and heart rate itself keeps working. rusqlite with `bundled` compiles SQLite
in, so nothing has to be installed. Verified: 1 Hz rows (72-81 bpm, confidence
236-239) in a live session.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rtifact and release asset

The install folder already carries both drivers built in the run; also upload
them on their own (librepods-windows-drivers artifact) and attach
LibrePods-Windows-drivers.zip to the nightly and versioned releases, so the
drivers can be installed or updated separately.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@arctumn
arctumn merged commit 7e7801f into windows-native Sep 29, 2026
1 check passed
arctumn added a commit that referenced this pull request Sep 29, 2026
windows: land the HR card v2 + READMEs that #10 missed, and ship one release zip
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