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)
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
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!
-
Go to oauthplayground
-
Click on “Step 1 Select & authorize APIs”
Scroll down toFitness 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:
-
Click on “Auhtorize APIs” and go trough the authorization steps
-
In step 2, click on
Exchange authorization code for tokens
-
On the right you should see something like this:
copy the full json part on the bottom (with the access_token, scope, …) -
open your
.<name>_google_fit.token
file. This should be on the same level as yourconfiguration.yaml
file (I suggest you create a copy and format it, for easy working and having a backup) -
Paste the copied json in the
token_response
part (this should have the same keys, maybe different order) -
Copy the full
access_token
(yellow in reference screenshot), fullrefresh_token
(purple in reference screenshot) to the upper part of the json -
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"
],
- Save it (the token file doesn’t have to be on a single line, formatted also works)
- Restart Homeassistant and this should be working
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)
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()
Thanks for that
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
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
- Does the token file exist - if yes then use the token file, if no goto step 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)
- 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
That was with one account, another account token was generated some 18 hours later- let’s see
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…
Best Regards,
Rodrigo Marinangeli
Yep, 7 days is token lifespan
Will try to push to production and see if this helps
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
Maybe I am too impatient as always but after declaring the Fit app as “production” (no verification was needed) in Google it has been working for 10 days after last token generation via Python script… vs 7 days before Fingers crossed!
Reads all our family Google Fit data via MiBand and MiScale2 and displays nicely in HA
Best, JR
I’m getting the following error:
2021-09-30 15:25:16 ERROR (MainThread) [homeassistant.components.sensor] Error adding entities for domain sensor with platform google_fit
Traceback (most recent call last):
File "C:\Python38\lib\site-packages\homeassistant\helpers\entity_platform.py", line 382, in async_add_entities
await asyncio.gather(*tasks)
File "C:\Python38\lib\site-packages\homeassistant\helpers\entity_platform.py", line 587, in _async_add_entity
await entity.add_to_platform_finish()
File "C:\Python38\lib\site-packages\homeassistant\helpers\entity.py", line 698, in add_to_platform_finish
self.async_write_ha_state()
File "C:\Python38\lib\site-packages\homeassistant\helpers\entity.py", line 464, in async_write_ha_state
self._async_write_ha_state()
File "C:\Python38\lib\site-packages\homeassistant\helpers\entity.py", line 505, in _async_write_ha_state
extra_state_attributes = self.device_state_attributes
File "C:\Users\stefa\AppData\Roaming\.homeassistant\custom_components\google_fit\sensor.py", line 247, in device_state_attributes
return self._attributes
AttributeError: 'GoogleFitWeightSensor' object has no attribute '_attributes'
I already tried to remove token files and py cache…
When I restart HA, I also get as soon as I restart the following notification: Authentication code expired, please restart Home-Assistant and try again
Same here for me!
Now I am able to get the sensors showing up. Only height and weight data are being provided. All other sensors show this in the Configuration Log: oauth2client.client.HttpAccessTokenRefreshError: unauthorized_client: Unauthorized
Not sure how to resolve this…