Sandra
Sandra

Reputation: 21

Huawei Watch 2 sleep sessions are not in Google Fit Api sleep endpoint

We have an application, which connects to Google Fit, and we obtain user sessions, such as sleep activity (activity = 72). We have this application running every day, for more than two years, with about 15.000 users, working seamlessly.

We discovered recently one user in our app, who has a Huawei Watch 2 Pro, connected to Google Fit. This user has sleep sessions on his mobile, but does not have these sessions in Google Fit API (in the sessions endpoint).

We have connected the same Googlefit account to a second mobile phone, so we could verify if the sessions were in the cloud or not, and this second mobile phone has been able to load all the sleep sessions; so we believe these sessions are in the cloud, but we can not see them as sleep sessions (through the sessions endpoint).

For further analysis, we have also inserted a manual sleep measurement, from the Google Fit app, and it does appear in the Google Fit API. So we think it has something to do about how the huawei app saves sleep sessions in Google Fit.

So we have tried to look where was Huawei saving data, if it was not in sleep sessions. We looked inside dataSources, raw:com.google.activity.segment:com.huawei.health: and then, dataset aggregate:

https://www.googleapis.com/fitness/v1/users/userId/dataset:aggregate

With a request body, and a range of dates that we know the user has a sleep session:

{
  "aggregateBy": [{
    "dataSourceId": "raw:com.google.activity.segment:com.huawei.health:",
    "dataTypeName": "com.google.activity.segment"
  }],
 
  "bucketByTime": { "durationMillis": 86400000 },
  "startTimeMillis": 1603753199000, //GMT: Monday, 26 October 2020 22:59:59
  "endTimeMillis": 1603782000000   //GMT: Tuesday, 27 October 2020 7:00:00
}

We obtain a series of points, which could be the sleep sessions, for example: Response:

{
    "bucket": [
        {
            "startTimeMillis": "1603753199000",
            "endTimeMillis": "1603782000000",
            "dataset": [
                {
                    "dataSourceId": "derived:com.google.activity.summary:com.google.android.gms:aggregated",
                    "point": [
                        {
                            "startTimeNanos": "1603753380000000000",  //GMT: Monday, 26 October 2020 23:03:00
                            "endTimeNanos": "1603780140000000000", //GMT: Tuesday, 27 October 2020 6:29:00
                            "dataTypeName": "com.google.activity.summary",
                            "originDataSourceId": "raw:com.google.activity.segment:com.huawei.health:",
                            "value": [
                                {
                                    "intVal": 109,
                                    "mapVal": []
                                },
                                {
                                    "intVal": 20160000,
                                    "mapVal": []
                                },
                                {
                                    "intVal": 336,
                                    "mapVal": []
                                }
                            ]
                        },
                        {
                            "startTimeNanos": "1603755240000000000", //GMT: Monday, 26 October 2020 23:34:00
                            "endTimeNanos": "1603779600000000000", //GMT: Tuesday, 27 October 2020 6:20:00
                            "dataTypeName": "com.google.activity.summary",
                            "originDataSourceId": "raw:com.google.activity.segment:com.huawei.health:",
                            "value": [
                                {
                                    "intVal": 110,
                                    "mapVal": []
                                },
                                {
                                    "intVal": 6600000,
                                    "mapVal": []
                                },
                                {
                                    "intVal": 110,
                                    "mapVal": []
                                }
                            ]
                        },
                        {
                            "startTimeNanos": "1603781520000000000", //GMT: Tuesday, 27 October 2020 6:52:00
                            "endTimeNanos": "1603781880000000000", GMT: Tuesday, 27 October 2020 6:58:00
                            "dataTypeName": "com.google.activity.summary",
                            "originDataSourceId": "raw:com.google.activity.segment:com.huawei.health:",
                            "value": [
                                {
                                    "intVal": 7,
                                    "mapVal": []
                                },
                                {
                                    "intVal": 240000,
                                    "mapVal": []
                                },
                                {
                                    "intVal": 4,
                                    "mapVal": []
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

We think that these points could be the sleep sessions because:

Then:

Could the sleep sessions be in a dataSource and not being collected in the sleep sessions? Can we differentiate somehow in the Google Fit app, that this is not a session, but a dataset? Why could it be that it is not being collected inside sleep sessions? Is it something from the Huawei app? How can we really know that these datasets are sleep sessions?

Upvotes: 2

Views: 687

Answers (1)

Mr L
Mr L

Reputation: 520

I collect sleep data from my Oppo Watch via Google Fitness API using Python.

I don't access the data using sessions, I only use datasets.

source = "derived:com.google.sleep.segment:com.google.android.gms:sleep_from_activity<-raw:com.google.activity.segment:com.heytap.wearable.health:stream_sleep"

startEnd = "%s-%s" % (START, END)

dataset = fitService().users().dataSources().datasets().get(userId='me', dataSourceId=source, datasetId=startEnd ).execute()

The response then looks like this (snippet):

"minStartTimeNs": "1607990400000000000",
    "maxEndTimeNs": "1608063421000000000",
    "dataSourceId": "derived:com.google.sleep.segment:com.google.android.gms:sleep_from_activity<-raw:com.google.activity.segment:com.heytap.wearable.health:stream_sleep",
    "point": [
        {
            "startTimeNanos": "1607992860000000000",
            "endTimeNanos": "1607994180000000000",
            "dataTypeName": "com.google.sleep.segment",
            "originDataSourceId": "raw:com.google.activity.segment:com.heytap.wearable.health:stream_sleep",
            "value": [
                {
                    "intVal": 4,
                    "mapVal": []
                }
            ],
            "modifiedTimeMillis": "1607996640613"
        },
        {
            "startTimeNanos": "1607994180000000000",
            "endTimeNanos": "1607994360000000000",
            "dataTypeName": "com.google.sleep.segment",
            "originDataSourceId": "raw:com.google.activity.segment:com.heytap.wearable.health:stream_sleep",
            "value": [
                {
                    "intVal": 5,
                    "mapVal": []
                }
            ],
            "modifiedTimeMillis": "1607996640613"
        },

The points contain segments including 'light sleep' (intVal 4) and 'deep sleep' (intVal) 5. I calculate how many light and deep segments there are and the start/end time for each one.

All segments retrieved using this method exactly match what is shown in the Google Fit app and the Oppo app (HeyTap Health). I have so far had no issues.

I am not sure if this helps, but I thought it best to mention that I do not use "sessions" at all.

Upvotes: 0

Related Questions