-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Limit device discovery by Homes #183
Comments
Not sure where to get the home that the device is in from, but some documentation is at If anyone has a Homegraph sample response it'd be easier to implement. |
Just for reference. By using the following script I was able to fetch the Homegraph API response for my Google Account: from glocaltokens.client import GLocalAuthenticationTokens
client = GLocalAuthenticationTokens(
username="...",
password="..."
)
print("\n[*] Fetching homegraph...")
homegraph = client.get_homegraph() An example of a Google Device is:
However, it's strange, since this device, even though it has been configured in my first home, the home name shown in the Homegraph API is the one from my second home, so something is wrong around here. Some deeper investigation needs to be done. Maybe there's an issue on how the Homegraph request is performed at This brings to me the question if it's time to switch from the ugly and bad optimized RPC API to the new REST API which I have just noticed that exists. I believe this wasn't an option back when the package was first developed, and it's a new API created by Google, so maybe we should take a look and consider migrating, since I keep finding the RPC responses ugly, frustrating and really really strange. What do you think @leikoilja ? |
Nice investigation, @ArnyminerZ 🚀 Regarding the new REST API... wow, that would be so amazing to switch to that instead of the bloated RPC. However, last time i quickly skimmed through google documentation it didn't seem like things are well documented and easy to migrate, so we might stumble across a few issues while migrating. But if someone would be up for taking it for a spin, that would significantly lighten up this package :) |
Okey, after some investigation on the REST API I have found that Google recommends using one of their "per-language" SDKs, so in our case it'd be the Python's SDK, which can be found here. And we can use the I just don't know if this is a better option than the RPC, or if it'd help with the homes organization, some testing is still needed. I'm writing a Python script to test this out, but authorisation works a little different here, so maybe the API change doesn't fit our needs, since as far as I have found for now, a Google Cloud project is needed, something that wasn't required before, and I would not like it to be required, since it'd make the integration far harder to configure. Whatsoever, I will keep digging deeper on how auth works, and if we can simplify this process. |
Okey, I found a way that might be the one to go on over authorisation, however, it seems to have issues with Homegraph API authorisation. As far as I have found out, it seems like the Homegraph API is like a restricted one, so when you ask the user for permission the following error gets returned:
The code that I'm using is: import google.oauth2.credentials
import google_auth_oauthlib.flow
# client_secret.json should be a general Google Cloud secret for all the users, not every user must create its own.
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
'client_secret.json',
scopes=['https://www.googleapis.com/auth/homegraph'])
flow.redirect_uri = 'https://www.example.com/oauth2callback'
authorization_url, state = flow.authorization_url(
# Enable offline access so that you can refresh an access token without
# re-prompting the user for permission. Recommended for web server apps.
access_type='offline',
# Enable incremental authorization. Recommended as a best practice.
include_granted_scopes='true'
)
print(authorization_url) Will keep researching on how to fix this, or ask the user for auth in another way. |
Okey, got some big news on the authorisation side. I've managed to request permission to the user successfully for accessing the resources of their Google Cloud Account, which should help on automating the requests required to set up the user's account to use the Homegraph API, since as far as I have found a GCloud project is needed, even though I'm not sure. Whatsoever, I've managed to get an access token for the user's account successfully with a right now quite dirty code. First I get an authorisation URL from the following code: import google.oauth2.credentials
import google_auth_oauthlib.flow
# client_secret.json should be a general Google Cloud secret for all the users, not every user must create its own.
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
'client_secret.json',
scopes=['https://www.googleapis.com/auth/cloud-platform'])
# Returns as get parameters:
flow.redirect_uri = 'https://www.example.com/oauth2callback'
authorization_url, state = flow.authorization_url(
# Enable offline access so that you can refresh an access token without
# re-prompting the user for permission. Recommended for web server apps.
access_type='offline',
# Enable incremental authorization. Recommended as a best practice.
include_granted_scopes='true'
)
print(authorization_url) Please note that I've set up my own personal GCloud project for doing all of this, but in this way there will be only one Google Cloud project for all the user's codebase, so for the final user this doesn't matter a lot. And I've put the authorisation keys for the project at And then, with the following code I extract the authorisation credentials that should work for all of our requests to the Python's Homegraph API, whose example I will post ASAP. Take a look at this: from googleapiclient.discovery import build
import google.oauth2.credentials
import google_auth_oauthlib.flow
response_url="https://www.example.com/oauth2callback?state=...&code=...&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform"
def credentials_to_dict(credentials):
return {'token': credentials.token,
'refresh_token': credentials.refresh_token,
'token_uri': credentials.token_uri,
'client_id': credentials.client_id,
'client_secret': credentials.client_secret,
'scopes': credentials.scopes}
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
'client_secret.json',
scopes=['https://www.googleapis.com/auth/cloud-platform']
)
flow.redirect_uri = 'https://www.example.com/oauth2callback'
flow.fetch_token(authorization_response=response_url)
credentials = credentials_to_dict(flow.credentials)
print(credentials) The At the end you get a {
"token":"",
"refresh_token":"",
"token_uri":"",
"client_id":"",
"client_secret":"",
"scopes":[]
} Reference (mostly):
|
Those are some amazing findings and progress, @ArnyminerZ 🚀 |
I don't know, can be tested. I'd wait to implement new login methods in the future if we find it necessary, but as you've stated, maybe requesting through the REST API can be done with the credentials we already got. Will check asap. 😉 |
Haven't tried it yet, but it looks like the official homegraph API (REST or RPC) is different from the one used by the app. @ArnyminerZ's links: Unofficial one used by GH app: The official one gives limited info and only fields exposed by the device manufacturer (color, temperature, power, etc.) and not meta details about the device itself (which is what's needed to get the local auth token). |
Yeah, I understand, so we should keep using the same API 😄 |
Is your feature request related to a problem? Please describe.
When multiple homes exist in the Google Home app, this integration discovers devices from all connected homes.
Describe the solution you'd like
Ability to limit google device discovery to a particular home if desired.
Additional context
Related to leikoilja/ha-google-home#363
The text was updated successfully, but these errors were encountered: