Google Fit Support

I’m using the vmanuel integration and its been great!

1 Like

For those taking the plunge and upgrading to 2021.4, you’ll need to modify the manifest.json by adding:
"version":"v1.1.14",
Otherwise the custom integration won’t load. File should be located under the custom_components\google_fit\ folder.

3 Likes

I forked the original HACS repo to return weight, height, and distance in U.S. imperial measurements (pounds, feet, and miles). The Google Fit API returns data in metric format so I just added formula calculations to each of the returned values before coming into Home Assistant.

1 Like

Does sleep sensor work?

I am using the Sleep As Android app to link the data to Google Fit. The sleep data shows up in Google Fit just not in HA. I’ve tried several versions of this custom component (vmanual, cyberjunky, kernel61) but my sensor.google_fit_sleep is always empty.

1 Like

Let me know if you get to solve your problem, I have the same one, heart rate and sleep show up in Google Fit (Synced through Notify for Mi Band), but my heart_rate and sleep sensors in HA remain empty

Google changed intents for them (sleep and heart rate) :frowning:
Will look at it when weather turns bad again (no outdoor activity).
Best, JR
PS link to Google changes as of May 4th: Sleep and Heart rate API changes

2 Likes

so heart rate and sleep sensors are not working because of API changes from Google’s side, right?

That’s my understanding

Hello everyone.
I already installed GoogleFit in two ways, but I can’t get the heart rate data to appear.
What is currently running is vmanuel / hacs-google-fit.
I am using a Samtband 4.
Does anyone have any idea di that may be happening?

After some research I found that Sleep and HeartRate sensors stopped working due to changes in Google’s API, so either developers didn’t have a time to update or they abandoned the integration.

I’ve found a solution that seems to work (sort off, the refresh_token isn’t really working).

I tried first adding the required scopes to the sensor.py removing my token file but then I got a invalid_scope error, I searched a bit, but couldn’t figure out why.

After some more messing around I found a method that seems to work

Required;

  • Setup the HACS integration a first time so it is authorized (and the token file is generated)
  • This requires some JSON knowledge and now how
  • full “tutorial” must be done in 3599 seconds (so basically within 1 hour, we are going to change the access token, and the get refreshed every hour)

Let’s goo!

  1. Go to oauthplayground

  2. Click on “Step 1 Select & authorize APIs”
    Scroll down to Fitness API v1
    Normally all scopes should be enabled with read and write (this isn’t fully needed, but I didn’t had the time to fully figure out what needs to be enabled)
    If not, these are the ones that worked for me:

  3. Click on “Auhtorize APIs” and go trough the authorization steps

  4. In step 2, click on Exchange authorization code for tokens

  5. On the right you should see something like this:


    copy the full json part on the bottom (with the access_token, scope, …)

  6. open your .<name>_google_fit.token file. This should be on the same level as your configuration.yaml file (I suggest you create a copy and format it, for easy working and having a backup)

  7. Paste the copied json in the token_response part (this should have the same keys, maybe different order)

  8. Copy the full access_token (yellow in reference screenshot), full refresh_token (purple in reference screenshot) to the upper part of the json

  9. Copy the following scopes (green in reference screenshot) to the scopes part (remove the ones you didn’t authorize):

  "scopes": [
    "https://www.googleapis.com/auth/fitness.location.write",
    "https://www.googleapis.com/auth/fitness.sleep.read",
    "https://www.googleapis.com/auth/fitness.heart_rate.read",
    "https://www.googleapis.com/auth/fitness.location.read",
    "https://www.googleapis.com/auth/fitness.activity.read",
    "https://www.googleapis.com/auth/fitness.body.write",
    "https://www.googleapis.com/auth/fitness.activity.write",
    "https://www.googleapis.com/auth/fitness.body.read",
    "https://www.googleapis.com/auth/fitness.sleep.write",
    "https://www.googleapis.com/auth/fitness.heart_rate.write"
  ],
  1. Save it (the token file doesn’t have to be on a single line, formatted also works)
  2. Restart Homeassistant and this should be working :slight_smile:

Refrenced screenshot of my <name>.google_fit.token file (not my full tokens obvisouly) :

I’m still waiting for a new token token to be generated, but this should give any issue (from my knowledge of these tokens, but then again I don’t understand why the scope was giving issues)

1 Like

Success or fail?
Best, JR

I tried this manual solution (Thanks Glenn) and it worked initially but then stopped
I also did some digging into the methods for getting tokens and then coded 2 standalone python routines

The first was using the same method as the various google fit sensors (calling oauth2client.client.Oauth2Webserverflow and then …step1_get_device_and_user code() from the Google api python client) … when this works then it gives you a code to enter at www.google.com/device. With this routine it was quick to try different sets of scopes and see which work/didn’t work and also use the debugger to confirm that it is the google server rejecting the requests

In the second method I used oauth2client.tools.run_flow which then takes you through the browser based authorisation and returns the credentials needed. The routine then writes these into a file whcih can then be renamed to match your expected google fit sensor token file .

Results - as we have all found, any use of the new scopes with the get_device_and_user_code routine fails (and fails after the data has been sent across to https://oauth2.googleapis.com/device/code
Looking at the documentation OAuth 2.0 for TV and Limited-Input Device Applications it does state that this method does support a limited number of scopes (and does not list any fitness scopes) -so perhaps we were lucky that the sensor worked at all

Better news is that the second method (generating the token file) has been running for 48 hours now and is still collecting steps, heart rate and sleep data.

Here is the standalone routine

import os
REQUIREMENTS = [
    'google-api-python-client==1.6.4',
    'oauth2client==4.0.0',
    'httplib2'
]

# Sensor base attributes.

CONF_CLIENT_ID = '32..............apps.googleusercontent.com'
CONF_CLIENT_SECRET = 'H....................5'



TOKEN_FILE = ''

# Endpoint scopes required for the sensor.
# Read more: https://developers.google.com/fit/rest/v1/authorization

SCOPES = ["https://www.googleapis.com/auth/fitness.location.write",
          "https://www.googleapis.com/auth/fitness.sleep.read",
          "https://www.googleapis.com/auth/fitness.heart_rate.read",
          "https://www.googleapis.com/auth/fitness.location.read",
          "https://www.googleapis.com/auth/fitness.activity.read",
          "https://www.googleapis.com/auth/fitness.body.write",
          "https://www.googleapis.com/auth/fitness.activity.write",
          "https://www.googleapis.com/auth/fitness.body.read",
          "https://www.googleapis.com/auth/fitness.sleep.write",
          "https://www.googleapis.com/auth/fitness.heart_rate.write" ]

def do_authentication():

    from oauth2client import client as oauth2client
    from oauth2client import file as oauth2file
    from oauth2client.file import Storage
    from oauth2client.tools import run_flow
    import google.oauth2.credentials

    oauth = oauth2client.OAuth2WebServerFlow(
        client_id=CONF_CLIENT_ID,
        client_secret=CONF_CLIENT_SECRET,
        scope=SCOPES,
        redirect_uri='urn:ietf:wg:oauth:2.0:oob',
    )

    storage = Storage('google_fit.token')
    # Open a web browser to ask the user for credentials.
    credentials = run_flow(oauth, storage)
    assert credentials.access_token is not None
    return credentials.access_token

    token = get_access_token()
    credentials = google.oauth2.credentials.Credentials(token)

    TOKEN_FILE = "google_fit.token"
    storage = oauth2file.Storage(TOKEN_FILE)
    storage.put(credentials)

    return True

do_authentication()
1 Like

Thanks for that :slight_smile:
Now my (digital) heartbeat is visible again and I sleep well (digitally)…
Only hickup was the filename- forgot to rename it to .google_fit.token :frowning:
So far so good- and another mega thanks.
Best, JR

What steps can be taken to update the current integration to work broken sensors again? can someone help

At the moment it does not seem possible to fix this by modifying the sensor.py routine. When HA starts, the sensory.py logic is

  1. Does the token file exist - if yes then use the token file, if no goto step 2
  2. Send the required scopes to google and get a device code for the user to then authenticate (this is shown to the user in the notification message)
  3. Wait for authentication by the user (who needs to open www.google.com/device and enter the device code) and then create the token file

Step 2 is not working because Google is not allowing this method to be used with these new sensitive/restricted fitness scopes, so step 3 never happens and none of the requests for google fit data work.

So in How to resolve the issue with the new API's · Issue #13 · vmanuel/hacs-google-fit · GitHub there is some discussion on how to run the code above in a python environment to create the required token file. (HA needs to restarted after the token file has been created so that it is found in Step 1 above).
Please make sure this new token file is renamed to be exactly what sensor.py is expecting

Generated token lived for 7 days, then got revoked :frowning:
That was with one account, another account token was generated some 18 hours later- let’s see :slight_smile:
Maybe the culprit is testing status, not production? Worth a try?
Best, JR

Yeap! Same here… i have tried something similar a couple of months ago, and have the same problem with token been revoked 7 days before created. Unfortenely I don’t know much of python or auth2, so I was hopping that someone could generated a ‘long-term’ token… I tried the code posted here (thank you so much astronaut63) but today i have to generate a new one too… btw, thank you all, community and developers of home assistant, wonderful piece of project <3… sorry for my english, this is my first post so… :sweat_smile:
Best Regards,
Rodrigo Marinangeli

Yep, 7 days is token lifespan :frowning:
Will try to push to production and see if this helps :slight_smile:
See you all in a week…
Best, JR

I’m also waiting for a few more hours for the 7 days to expire. I have a separate client/token for the Google calendar integration (created using the “old” device method) and then the token file for Google Fit created by the standalone code so it will be interesrting to see if both stop. I had also experienced the 7 day issue on a completely different Windows Google Cal to Outlook synchroisation tool and have now seen the official documentation confirming this limit: Using OAuth 2.0 to Access Google APIs  |  Google Identity

I did spend some time looking at a) using the official google_auth_oauthlib python modules which should allow something closer to the way the Google fit sensor originally worked (a notification message telling you to go to a google address where you approve the scopes and then a verification code to be entered back into Home Assistant - via an Input_text (?) or b) using the oauth callbacks already in HA – but this I think would mean having to open access to HA via DuckDNS and Router port forwards which not everyone wants to do.
I’ve not seen anything that explains what happens if you change your application from testing to production but then do not get it verified . This might be more critical for these fitness scopes
Some of the Google docs talk about “Personal” use applications being exempt from verification but I haven’t found out any more