Closed pkhivesara closed 2 months ago
I could obtain the Awake, REM, Deep and In Bed data collected from my Apple Watch. However, the SLEEP_CORE
is missing.
I second this For myself It seems that Asleep unspecified and Sleep core is missing which was explained in #803
I investigated and figured out the problem here.
Apple allows the following Sleep Types (Reference: Health Kit Documentation) :
- inBed : The user is in bed
- awake: The user is awake
- asleepCore: The user is in light or intermediate sleep
- asleepDeep: The user is in deep sleep
- asleepREM: The user is in REM sleep
- asleepUnspecified: The user is asleep, but the specific stage isn't known. (Possibly captured when the watch isn't used for sleep detection and sleep is logged manually or automatically based on phone usage) Note: asleep is now deprecated.
Currently, the mapping for some of these in this package is incorrect. Refer this file - https://github.com/cph-cachet/flutter-plugins/blob/master/packages/health/ios/Classes/SwiftHealthPlugin.swift.
Currently, SLEEP_IN_BED - 0 SLEEP_ASLEEP - 1 SLEEP_AWAKE - 2 SLEEP_DEEP - 3 SLEEP_REM - 4
How it should be (corrections in bold) - SLEEP_IN_BED - 0 SLEEP_ASLEEP - 1 (sleepUnspecified in terms of HealthKit. Value is going to be zero when all sleep stages' data is available.) SLEEP_AWAKE - 2 SLEEP_LIGHT - 3 (sleepCore in terms of HealthKit. This should be allowed as a data type similar to Android.) SLEEP_DEEP - 4 SLEEP_REM - 5
I am going to attempt this change and will raise a PR if that works. EDIT - Noticed that a PR is already here: #816 . Though this PR doesn't deal with SLEEP_LIGHT to be added as a datatype which is a crucial data point.
Hi all,
Thanks for raising this issue. When I try to query the data requested in the original issue using these types:
static final types = [
HealthDataType.SLEEP_AWAKE,
HealthDataType.SLEEP_ASLEEP_CORE,
HealthDataType.SLEEP_ASLEEP_REM,
HealthDataType.SLEEP_ASLEEP_DEEP
];
I am able to get results for all of the requested types. A screenshot from my Apple Health app:
... compared to a quick visualization I made using the datapoints that the health package returns:
the order of the y-axis in the plot isn't correct but the data seems to align nevertheless, and I am able to get datapoints for core sleep as well. If there's something I'm misunderstanding could you please explain further?
@SlimShadyIAm Can you share a code snippet for your example? I think our issue is that the data is not consistent compared to what we see on apple. And SLEEP_CORE does not pull any data at all?
Hi, The one I am missing is AsleepUnspecified. https://developer.apple.com/documentation/healthkit/hkcategoryvaluesleepanalysis/asleepunspecified
I believe apple made that category when the stages were implemented and deprecated the old option.
Note, It seems that the categories that you mentioned above are not listed in the readme docs
@pkhivesara I used the example app which you can find in our repo.
On these lines: https://github.com/cph-cachet/flutter-plugins/blob/310d13d8f91b6481b82389a8f558c1010678b5c5/packages/health/example/lib/main.dart#L40-L58
you can set types
to:
static final types = [
HealthDataType.SLEEP_AWAKE,
HealthDataType.SLEEP_ASLEEP_CORE,
HealthDataType.SLEEP_ASLEEP_REM,
HealthDataType.SLEEP_ASLEEP_DEEP
];
Hi, The one I am missing is AsleepUnspecified. https://developer.apple.com/documentation/healthkit/hkcategoryvaluesleepanalysis/asleepunspecified
I believe apple made that category when the stages were implemented and deprecated the old option.
Note, It seems that the categories that you mentioned above are not listed in the readme docs
Yes, I can see that this is unclear. I'm going to look into what needs to be changed here -- it also seems like we have multiple sleep related HealthDataType
categories that seem to serve the same purpose, and also how to support the unspecified sleep type.
And SLEEP_CORE does not pull any data at all?
@pkhivesara just to be clear you are using HealthDataType.SLEEP_ASLEEP_CORE
?
I've looked into how sleep stages have previously been implemented in the health package and noticed a few things with regards to what is documented vs what is supported.
This table shows the current state of supported sleep stages. I noticed some of the types are overlapping and it was unclear which was supported on what platform.
Stage | iOS | Android | Notes |
---|---|---|---|
SLEEP_IN_BED | ✅ | ||
SLEEP_ASLEEP | ✅ | ✅ | |
SLEEP_AWAKE | ✅ | ✅ | |
SLEEP_DEEP | ✅ | ✅ | |
SLEEP_LIGHT | ✅ | ||
SLEEP_REM | ✅ | ✅ | |
SLEEP_OUT_OF_BED | ✅ | ||
SLEEP_SESSION | ✅ | ||
SLEEP_ASLEEP_CORE | ✅ | This was undocumented. Rename to SLEEP_CORE for consistency? | |
SLEEP_ASLEEP_DEEP | ✅ | This was undocumented. Serves the same purpose as SLEEP_DEEP, combine | |
SLEEP_ASLEEP_REM | ✅ | This was undocumented. Serves the same purpose as SLEEP_REM, combine |
This is how I propose it should be changed. While it might not solve a potential issue that @pkhivesara is raising, it would provide clarity for the types and documentation, improve consistency and add support for all sleep stages across both HealthKit and Health Connect.
Stage | iOS | Android | Notes |
---|---|---|---|
SLEEP_UNKNOWN | ✅ | ✅ | (NEW) on iOS this is SLEEP_UNSPECIFIED, name changed to fit Android (consistent with other measures) |
SLEEP_AWAKE | ✅ | ✅ | |
SLEEP_CORE | ✅ | renamed for consistency | |
SLEEP_LIGHT | ✅ | ||
SLEEP_DEEP | ✅ | ✅ | combined |
SLEEP_REM | ✅ | ✅ | combined |
SLEEP_IN_BED | ✅ | ||
SLEEP_SLEEPING | ✅ | (NEW) | |
SLEEP_OUT_OF_BED | ✅ | ||
SLEEP_AWAKE_IN_BED | ✅ | (NEW) | |
~SLEEP_ASLEEP~ | ~✅~ | Remove? This value currently simply corresponds to core sleep: link to code |
I did look into the suggestion from the previous issue linked above (https://github.com/cph-cachet/flutter-plugins/issues/803#issuecomment-1804712277), however I'm unsure whether SLEEP_LIGHT and SLEEP_CORE describe the same stages of sleep - ChatGPT says they don't. And also I don't think SLEEP_ASLEEP should correspond to asleepUnspecified in HealthKit terms because HealthKit already provides us with a category value for this.
I'd like to hear your thoughts on this before I make this change, if you have any differing suggestions please let me know.
I am happy with that, It will add the missing stage which our app needs. How long would you say you need for this to go out? Thanks Khaleel
How long would you say you need for this to go
We're planning a major release in the next couple of weeks and it could potentially be included in that. Would you be able to help test whether getting unspecified sleep works? I looked through my own personal data but couldn't find any recordings which had unspecified sleep.
Hi, Sure that is not a problem on my end. The unspecified stage seems to be linked to certain ios watch software versions.
You can also manully add stages of sleep via the apple health app if that helps. It is what I have been doing to test and debugg the issue we were getting.
Thanks Khaleel
SLEEP_ASLEEP_CORE
Nope, this attribute is not listed on the docs from what I see. You are suggesting that SLEEP_ASLEEP_CORE indeed returns the correct values. Is that right? I will give it a shot and drop an update here once done.
Yes, this isn't in the README but please give it a try.
On second thought, Apple's documentation says asleepCore
also refers to light sleep, so I will combine ASLEEP_CORE
into ASLEEP_LIGHT
and add a note in the docs that this also refers to core sleep.
Also, Apple's asleepUnspecified
is defined as:
The user is asleep, but the specific stage isn’t known
which seems to correspond to STAGE_TYPE_SLEEPING
on Android:
The user is asleep but the particular stage of sleep (light, deep or REM) is unknown.
so I will also combine these into SLEEP_ASLEEP
.
As a result, SLEEP_UNKNOWN
will become Android only, representing STAGE_TYPE_UNKNOWN
: https://developer.android.com/reference/kotlin/androidx/health/connect/client/records/SleepSessionRecord
Stage | iOS | Android | Notes |
---|---|---|---|
SLEEP_ASLEEP | ✅ | ✅ | (NEW) - on iOS this refers to asleepUnspecified |
SLEEP_AWAKE | ✅ | ✅ | |
SLEEP_AWAKE_IN_BED | ✅ | (NEW) | |
SLEEP_DEEP | ✅ | ✅ | combined |
SLEEP_IN_BED | ✅ | ||
SLEEP_LIGHT | ✅ | ✅ | combined - on iOS this refers to asleepCore |
SLEEP_OUT_OF_BED | ✅ | ||
SLEEP_REM | ✅ | ✅ | combined |
SLEEP_UNKNOWN | ✅ | (NEW) |
Yes, this isn't in the README but please give it a try.
Sorry forgot to reply yesterday, but asleep_core seems to point to asleep_light as per Apple, which is what my original question was here. How does one pull in the CORE sleep data?
Thanks @pkhivesara but I'm having some trouble understanding the issue you're facing --- reading SLEEP_ASLEEP_CORE
in version 10.2.0 points to HKCategoryValueSleepAnalysis.asleepCore
as you can see here in our Swift implementation of getData
:
There isn't a separate "light sleep" category on iOS, asleepCore
covers that according to Apple's docs. We have no way of differentiating the two and we can only read the data HealthKit provides as it is.
In my earlier comments, I queried for all the sleep stages the Health package currently supports and the visualization was the same as the one in the Health app, including core sleep.
Could you please help me understand if I'm missing something or clarify where you're seeing asleep_core associated with asleep_light?
I've just opened #1026 to implement the changes discussed above - would greatly appreciate if you all could help test. If you have Android devices with sleep data on Health Connect, it would also be greatly appreciated if you could test that.
@pkhivesara, please check if you are able to access the data you require using this version.
I've just opened #1026 to implement the changes discussed above - would greatly appreciate if you all could help test. If you have Android devices with sleep data on Health Connect, it would also be greatly appreciated if you could test that.
@pkhivesara, please check if you are able to access the data you require using this version.
We tried the changes you suggested, but we are seeing few issues with the latest library update.
If you see the screenshots below, the asleep interval times fetched from the plugin does not match the hours shown in Apple health. Is that a known issue?
Hi,
That seems strange, but it's not clear from the information you provided - is this a sleep session you added manually to the Health app and you chose the "Asleep" category?
I'm assuming yes; I tried to reproduce this by adding a session like so:
Then I used the example app to query for the data and passed in this as the types:
static final types = [
HealthDataType.SLEEP_ASLEEP,
];
And I got this as the result:
I've merged the PR to address the original issue in this thread, as before it was not clear how to query sleep data on iOS. If you are still experiencing problems could you please open a new issue?
Fetch Awake, REM, Core, and Deep attributes as seen in Apple Health
Device / Emulator and OS
Please complete the following information for each phone and/or emulator you're experiencing this bug on:
Describe the bug
How can we obtain sleep_rem, sleep_core, sleep_deep, and sleep_awake, time_asleep, and time_in_bed entries from this health package, similar to the sleep intervals shown in the Apple Health app?
I do see a closed ticket here: https://github.com/cph-cachet/flutter-plugins/issues/803
However it appears we do not get the correct data based on the thread in the above ticket.