Health connect sleep stages - #7356
Conversation
There was a problem hiding this comment.
Hi @KruseLuds
It seems you haven't yet signed a CLA. Please do so here.
Once you do that we will be able to review and accept this pull request.
Thanks!
|
Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍 |
There was a problem hiding this comment.
Pull request overview
Adds richer Health Connect sleep session reporting by reusing a single SleepSessionRecord read per update cycle and deriving additional sensors for sleep start/end and per-stage durations, while keeping the existing sleep duration sensor for backward compatibility.
Changes:
- Added new Health Connect sensors for sleep start/end timestamps and standardized sleep-stage durations.
- Centralized sleep record processing via
updateSleepSensors()+analyzeSleepStages()to avoid duplicate Health Connect queries. - Added unit tests validating per-stage duration aggregation and timeline preservation.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| common/src/main/res/values/strings.xml | Adds new sensor names/descriptions for sleep start/end and stage durations. |
| app/src/main/kotlin/io/homeassistant/companion/android/sensors/HealthConnectSensorManager.kt | Implements new sleep sensors and shared sleep-stage analysis + attribute building. |
| app/src/test/kotlin/io/homeassistant/companion/android/sensors/HealthConnectSensorManagerTest.kt | Adds tests for sleep-stage analysis aggregation and timeline preservation. |
| app/src/main/res/xml/changelog_master.xml | Documents the new Health Connect sleep sensors in the 2026.8.4 changelog. |
Suppressed comments (2)
app/src/main/kotlin/io/homeassistant/companion/android/sensors/HealthConnectSensorManager.kt:1135
stagesis passed as aList<Map<String, Any>>, but the attribute serialization inSensorManager.onSensorUpdatedtreats non-primitive lists asliststringand storesmap.toString()values. That means the sleep-stage timeline won’t actually arrive as structured data (type/start/end fields), which conflicts with the PR description and likely makes the attribute hard to consume reliably.
"deviceManufacturer" to sleepRecord.metadata.device?.manufacturer,
"deviceModel" to sleepRecord.metadata.device?.model,
"stages" to analysis.timeline,
)
app/src/main/kotlin/io/homeassistant/companion/android/sensors/HealthConnectSensorManager.kt:1133
buildSleepSessionAttributesincludestitle,notes, and record/client IDs plus device manufacturer/model. Unlike other Health Connect sensors in this file (which only expose time + source), this expands the data sent to Home Assistant and may unintentionally expose sensitive/free-text data (especiallynotes). Consider limiting attributes to what’s needed for consumers (e.g., start/end, source, and stage timeline) or making the extra metadata opt-in.
"title" to sleepRecord.title,
"notes" to sleepRecord.notes,
"sources" to sleepRecord.metadata.dataOrigin.packageName,
"recordId" to sleepRecord.metadata.id,
"lastModifiedTime" to sleepRecord.metadata.lastModifiedTime,
"clientRecordId" to sleepRecord.metadata.clientRecordId,
"clientRecordVersion" to sleepRecord.metadata.clientRecordVersion,
"recordingMethod" to sleepRecord.metadata.recordingMethod,
"deviceType" to sleepRecord.metadata.device?.type,
"deviceManufacturer" to sleepRecord.metadata.device?.manufacturer,
"deviceModel" to sleepRecord.metadata.device?.model,
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Hi @KruseLuds
It seems you haven't yet signed a CLA. Please do so here.
Once you do that we will be able to review and accept this pull request.
Thanks!
Done |
|
Sleep-stage timeline serialization Fixed. The nested list of maps has been replaced with parallel primitive lists for stage type, stage type ID, start time, and end time so the Companion App attribute serializer preserves the timeline structure. Unnecessary/sensitive sleep metadata fixed - Removed the additional title, notes, record/client IDs, device metadata, and other unnecessary sleep-session metadata. The attributes are now limited to the session times, source, and sleep-stage timeline data needed for this feature. |
|
All review feedback has been addressed and the latest changes are pushed. The targeted Health Connect tests and ktlint passed locally, and all GitHub CI checks are now green. Ready for maintainer review when someone has availability. Thanks! |
Summary
Adds richer Health Connect sleep session data to the Android Companion App by exposing the individual standardized sleep stages already available through
SleepSessionRecord.The existing Health Connect sleep duration sensor remains unchanged for backward compatibility. This change adds sensors for sleep start/end times and the duration of each standardized Health Connect sleep stage, including Light, Deep, REM, Awake, Awake in bed, Out of bed, Sleeping/unspecified, and Unknown.
The latest
SleepSessionRecordis read once per sensor update and its stages are analyzed once, avoiding duplicate Health Connect queries when multiple sleep sensors are enabled.The existing Sleep Duration sensor also preserves the ordered sleep-stage timeline as structured attributes containing each stage's type, start time, and end time, allowing Home Assistant consumers to use the original Health Connect stage data for dashboards and analysis.
The implementation is provider-neutral. It does not contain Samsung-, Fitbit-, or device-specific logic and does not attempt to merge separate
SleepSessionRecordentries.Missing stage data is kept unavailable/unknown rather than being converted to zero, because a provider not supplying a stage is semantically different from reporting zero duration.
Related feature request:
home-assistant/feature-requests#4080
Checklist
Select exactly one option that describes AI usage in this contribution:
Link to pull request in documentation repositories
User Documentation: home-assistant/companion.home-assistant#1407
Developer Documentation: home-assistant/developers.home-assistant#
Any other notes
Targeted
HealthConnectSensorManagerTest: 6/6 tests passed.:app:lintFullDebug: passed.ktlintCheck :build-logic:convention:ktlintCheck --continue: passed.The full
:app:testFullDebugUnitTestrun completed 1,530 tests with two unrelated failures inWearOnboardingNavigationTestandServerDiscoveryNavigationTest. Both failures were reproduced independently when those test classes were run in isolation.