nest-api
nest-api copied to clipboard
Google Home migration??
Google is pushing hard to get me to migrate my Nest account over to Google Home. Before I do that, can anyone tell me if doing such would break my access to this API?
Thank you!
Yes, it will (break your API access). Don't do it unless you find a working alternative that can work with the Google API, if there is such a thing (didn't look).
UGH!!!! Thank you! Stupid Google forced me to migrate grandma's Nest account to Google Home in order to update/add/delete family members (for Nest Protect notifications). Now I cannot add myself back into grandma's house without migrating my own Nest account over Google Home, which apparently is going to break this thing for my own house's thermostat.
I wrote a complex application that uses your API code to dump the thermostat data into my online database to track my tank's fuel oil level, graphs, average daily fuel consumption, etc. I really depend on this system since Nest does not have a usage counter built into it anyplace. My circa 1990 Honeywell actually had a resettable hourly usage meter built into it, so Nest takes a huge step backwards in this area.
This system I wrote keeps me from having to dip a stick into the oil tank like a caveman. Thanks Google for effing everything up so badly!
@sparky672 - I totally agree. The moment Google forces me to switch the account is the moment I head to Costco for the Ecobee 4.
I like the Nest. Not that I'm opposed to switching... but the amount of time I have invested into my custom data acquisition application is ridiculous. Does Ecobee have a similar API where I can get usage data?
@gboudreau, I thought your PHP class was accessing the same Nest API server as the Nest App so I'm confused about how this can be broken. Is it a matter of the user account? Once the user account is migrated to Google Home, then the API will reject access to that account, while somehow the Nest App is still able to connect?
@sparky672 > I like the Nest. Not that I'm opposed to switching... but the amount of time I have invested into my custom data acquisition application is ridiculous. Does Ecobee have a similar API where I can get usage data?
I don't mind the Nest. I do mind that my data is being held hostage.
It looks like Ecobee's API is much more supported: https://www.ecobee.com/home/developer/api/introduction/index.shtml
WRT authentication, I'm betting the Google account authentication uses the Google federated login, not the direct authentication.
And the part that gets the connection is here.
I cannot test this out since I have not migrated my Nest account. My grandmother's account was migrated but she only has Nest Protects. Is there anyone here who already migrated their Nest account to Google, who would be willing to experiment with getting this Nest API project working with the Google tokens?
I am in the same boat.....and have not migrated my nest account.
I have been recording multi zones and calculating oil usage with great success. Even ran a special "smart" script last year that adapted to outside conditions and saved 100 gallons over the season.
The homeassistant nest project is also stuck.....they all rushed to open API accounts before the cut off.
I am not switching units...so I keep looking for a solution.
Even ran a special "smart" script last year that adapted to outside conditions and saved 100 gallons over the season.
I've just been gathering and displaying usage data and calculating levels. Also wrote a script that tries to predict a refill date based on past usage. Never tried controlling it or gathering outside temperatures. I thought about trying to gather outside temps to display next to usage but didn't seem super useful.
What did your script do and how did it save your fuel usage?
Well...I have hydronic heating / oil /multi zone and live in the mid-atlantic which has variable temps in winter.
At first nest saved because it does vary "pre heat" times based on learning of the hydronic system.
After looking at my graphs, I realized that on a regular basis the heat was fighting the lowest temps of the day and not running during the highest temps. So the script does a little "heat banking" during the peak temps of the day (even when no one is home) and does a little deferment during the coldest.
Not real complicated....just heat bank if outside is above a certain temp / defer heating if outside is very cold and normal schedule the rest of the time. Just taking advantage of the non linear nature of heat loss based on the temperature gradient.
In operation it was not real noticeable....occasionally a little warmer / colder in the middle of the night than expected (which mirrored the outside climate).
Interesting. I have hydronic system too. But I also have variable rate electric, which is basically hourly pricing based on the wholesale market. When electricity is cheap at night, I would crank up the electric heaters and save oil.
I thought about tying my application into that but never finished figuring out how to get the hourly electric rates.
I've migrated my account and it broke access.
The badnest project (https://github.com/USA-RedDragon/badnest) managed to get google logins working. I'd be more than happy to test out google account logins with this project.
I've migrated my account and it broke access.
The badnest project (https://github.com/USA-RedDragon/badnest) managed to get google logins working. I'd be more than happy to test out google account logins with this project.
Yes, please!
The question is if Guillaume is even interested in modifying the code to fix it, at this point.
The question is if Guillaume is even interested in modifying the code to fix it, at this point.
Even if not, we can possibly modify it ourselves.
True, but I'm more of a bash developer (being a SysAdmin) than a php developer. If you wanna have a crack at it, I'll test it out.
I just checked the code of badnest; the implementation of how to use a Google account is pretty hackish. Expected, until Google releases better API access (early 2020 for enterprises; maybe later for individuals, if ever).
I could try to implement this, but to do so, I would need to migrate my Nest account to a Google account; not sure I want to do that until I'm sure I can make it work...
If someone who already migrated could provide me with their "issue_token", "cookie" and "api_key", per badnest's instructions, I could try to implement it using those values. (Of note: those values become unusable as soon as you logout from the Nest website, in the browser window that you used to get them. So I would suggest using a regular browser window, not an Incognito one, to get those values, in order to be able to Logout from this session, once I'm done.)
Don't post these values publicly though. Please contact @gboudreau through a different medium if you're willing to do so.
Isn't there a more 'correct' way to get a google authentication token to your account than this way? Wouldn't that method break any time you close the browser you used to get the token? That wouldn't be good for any sort of long-standing system, right?
Isn't there a more 'correct' way to get a google authentication token to your account than this way?
No. That's the point. This is not officially sanctioned by Google. You're tricking the API into thinking you're getting access via the Nest app.
Wouldn't that method break any time you close the browser you used to get the token? That wouldn't be good for any sort of long-standing system, right?
My understanding is that you're good for as long as you don't log out of your account. My main browser on my primary computer never asks me to log back into Google... I open Gmail.com and there it is - no login prompt... unless of course I click the "logout" or "switch accounts".
I also maintain other Google accounts for clients so I'm guessing if I log into those with a different browser, I wouldn't be disturbing my own Google log in.
Well, yes, I get the 'unofficial-ness' of accessing nest this way, but I'm talking just standard Google auth tokens. Surely there's some application-level way to obtain them that actually IS official, seeing as it's needed for all the other Google application stuff... right? Using the Nest page as the fake API is the unofficial bit. The Google auth token should be well established since it's been around for a while... right? (Please note: I'm claiming no knowledge of how this stuff actually works. Just asking questions that I don't know the answers to)
When you login on the Nest website, Google uses your session (OCAK cookie) to know which Google account you are logged in as. Using this info, it can then check if you already granted the Nest website access to your Google account. If not, it prompts. If you already granted access, it will use your OCAK cookie (along with some other tidbits) to get a short-lived access token to use the internal Nest API.
Since we, as developers, cannot ask to get access to the internal Nest API from Google, we need to 'steal' the info that the Nest website has been able to get from Google, and use those secrets ourselves to connect to the Nest API, and ourselves get the same short-lived access token that the Nest website is able to get. This process requires the issue_token, cookie and api_key values.
The process might be simplified somewhat, but we can't use the usual Google API methods of getting an access token; Google are not allowing that.
Well, yes, I get the 'unofficial-ness' of accessing nest this way, but I'm talking just standard Google auth tokens. Surely there's some application-level way to obtain them that actually IS official, seeing as it's needed for all the other Google application stuff... right? Using the Nest page as the fake API is the unofficial bit. The Google auth token should be well established since it's been around for a while... right? (Please note: I'm claiming no knowledge of how this stuff actually works. Just asking questions that I don't know the answers to)
I'm not sure either. However, since Google is not yet giving anyone API access to Nest data, I doubt anything official they provide could work. Edit: what Guillaume just said ^^^
As a side note, the whole Google thing is still such a totally convoluted mess (cluster-f***):
-
No support for Nest Protects in the Google Home app despite being forced to manage the Nest Home via the Google app. Forced to use Nest app for Nest Protects despite no way to manage "home" via this app.
-
Family users are being shown in the Nest app with no way to delete them. Just a message to use the Google Home app to add/remove family members. And yet, these same family members are NOT showing up in the Google Home app. In other words, there are a couple family user names in limbo. No access, cannot remove from Nest app, and yet also not showing up in Google Home app. < oh well, moot point once Google shuts down Nest app.
I pushed some kind of test code in the dev/google-account branch.
Maybe try that; see test.php on how to test it.
Really not sure my old implementation, which uses the {transport_url}/v3/mobile
URL, would work with the info we can get with a Google account...
Sending a post to https://home.nest.com/api/0.1/user/{$this->userid}/app_launch
seems to return many URLs; maybe one we need is in there.
Old code also needs a 'user', which I didn't find in basnest code... Not sure it's available in the response of app_launch
or not...
Seems to be working! :) Try this code, people with migrated Google account: https://github.com/gboudreau/nest-api/blob/dev/google-account/nest.class.php
This shows you how to instantiate the class, to provide the new information: https://github.com/gboudreau/nest-api/commit/26ac4de3664d01bded94967e242d6c948a35f950#diff-93bc3c03503d8768cf7cc1e39ce16fcb
Follow the instructions here to get the required values: https://github.com/USA-RedDragon/badnest#example-configurationyaml---when-you-are-using-the-google-auth-login
Make sure, for the cookie value, to provide all the cookies on one line:
$cookie = 'GoogleAccountsLocale_session=en; GALX=... ; SIDCC=...';
@Sal-Tepedino : maybe now would be a good time to logout, and re-login, in your browser! Thanks for providing the required detail to work on this.
Follow the instructions here to get the required values: https://github.com/USA-RedDragon/badnest#example-configurationyaml---when-you-are-using-the-google-auth-login
Instructions copy & pasted here:
The values of "issue_token", "cookie" and "api_key" are specific to your Google Account. To get them, follow these steps (only needs to be done once, as long as you stay logged into your Google Account).
- Open a Chrome browser tab in Incognito Mode (or clear your cache).
- Open Developer Tools (View/Developer/Developer Tools).
- Click on 'Network' tab. Make sure 'Preserve Log' is checked.
- In the 'Filter' box, enter issueToken
- Go to home.nest.com, and click 'Sign in with Google'. Log into your account.
- One network call (beginning with
iframerpc
) will appear in the Dev Tools window. Click on it. - In the Headers tab, under General, copy the entire Request URL (beginning with https://accounts.google.com, ending with nest.com). This is your
$issue_token
- In the 'Filter' box, enter
oauth2/iframe
- Several network calls will appear in the Dev Tools window. Click on the last iframe call.
- In the Headers tab, under Request Headers, copy the entire cookie (beginning OCAK=... - include the whole string which is several lines long and has many field/value pairs - do not include the cookie: name). This is your
$cookie
; make sure all of it is on a single line. -
In the 'Filter' box, enterissue_jwt
- Click on the last
issue_jwt
call - In the Headers tab, under Request Headers, copy the entire
x-goog-api-key
(do not include the x-goog-api-key: name). This is your$api_key
Pretty sure the $api_key
would be the same for everyone: AIzaSyAd...sZE4
(I think this is an API key that was created by the Nest website developers, and will be the same for everyone, until they change it on their side.)
Can you confirm yours is like that?
Similarly, only the login_hint
will be unique in $issue_token
:
https://accounts.google.com/o/oauth2/iframerpc?action=issueToken&response_type=token%20id_token&login_hint=UNIQUE_VALUE_HERE&client_id=733249279899-44tchle2kaa9afr5v9ov7jbuojfr9lrq.apps.googleusercontent.com&origin=https%3A%2F%2Fhome.nest.com&scope=openid%20profile%20email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fnest-account&ss_domain=https%3A%2F%2Fhome.nest.com
Of note: you'll get this, if the cookie ever becomes invalid (because you logged out, or timed out):
$ php test.php
Error: Response to login request doesn't contain required access token. Response: '(object) array(
'error' => 'USER_LOGGED_OUT',
'detail' => 'No active session found.',
)'
$
Pretty sure the
$api_key
would be the same for everyone:AIzaSyAd...sZE4
(I think this is an API key that was created by the Nest website developers, and will be the same for everyone, until they change it on their side.) Can you confirm yours is like that?
I logged into my grandmother's converted Nest account and cannot find x-goog-api-key
. Maybe because she only has Nest Protects?
I logged into my grandmother's converted Nest account and cannot find
x-goog-api-key
. Maybe because she only has Nest Protects?
I doubt; that API key is pretty much required for all subsequent API calls.
You don't see a HTTP request to issue_jwt
?
You don't see a HTTP request to
issue_jwt
?
Oops. I failed to follow the directions and skipped to the last step.
Here is what I got:
x-goog-api-key: AIzaSyAdkSIMNc51XGNEAYWasX9UOWkS5P6sZE4
Yeah, it's the same for everyone. I'll simplify my implementation to not require it.
Done; updated code, and README
Awesome, awesome, awesome! Thank you! However, with heating season just getting started, I'm not going to rush into this. Maybe see how it goes for the others first.
Hopefully, this all won't be for nothing once Google shuts down the Nest app.
I'm getting a dump of HTML then an error:
PHP Fatal error: Uncaught Error: Class 'Nest' not found in /var/www/html/rrd/nest-vars-test.php:14 Stack trace: #0 {main} thrown in /var/www/html/rrd/nest-vars-test.php on line 14
Line 14 is the $nest = new Nest(NULL, NULL, $issue_token, $cookies); line. The require line's in there and the class is there and permissions check out. I'm probably missing something obvious...
Nevermind. I was right. Obvious error...
Works! Updated the Request URL (issue token) and the cookie and it's working great!
Thanks!
Just to confirm... everything else works the same? Energy data dump looks the same as before?
$nest->getEnergyLatest();
Looks the same as far as I can tell. I'm using
$infos = $nest->getDeviceInfo("MySerialHere");
To grab the data and then a printf to output it. Works exactly as it did before.
Everything should be the same. I only changed how it logs in; it use another way to login, and fetch the required information (user ID, transport URL, etc.), but everything else was kept as-is, so unless for some reason the access token obtained using this new way to login is unusable for some of the API calls (which I doubt), it should work exactly the same as before.
Looks the same as far as I can tell. I'm using
$infos = $nest->getDeviceInfo("MySerialHere");
To grab the data and then a printf to output it. Works exactly as it did before.
Can you try $nest->getEnergyLatest()
just to be sure? Thanks!
so unless for some reason the access token obtained using this new way to login is unusable for some of the API calls (which I doubt), it should work exactly the same as before.
Just wanting to be sure before I break anything unnecessarily.
I did and it didn't output anything. Note: I'm not a php coder, so there's probably another step I don't know...
I did and it didn't output anything. Note: I'm not a php coder, so there's probably another step I don't know...
Do this....
var_dump($nest->getEnergyLatest());
and it should look something like this....
object(stdClass)#261 (1) { ["objects"]=> array(1) { [0]=> object(stdClass)#262 (4) { ["object_revision"]=> int(1) ["object_timestamp"]=> int(1) ["object_key"]=> string(30) "energy_latest.09AA01AC34150AGX" ["value"]=> object(stdClass)#263 (2) { ["recent_max_used"]=> int(0) ["days"]=> array(10) { [0]=> object(stdClass)#282 (16) { ["day"]=> string(10) "2019-10-21" ["device_timezone_offset"]=> int(-18000) ["total_heating_time"]=> int(0) ["total_cooling_time"]=> int(0) ["total_fan_cooling_time"]=> int(0) ["total_humidifier_time"]=> int(0) ["total_dehumidifier_time"]=> int(0) ["leafs"]=> int(1) ["whodunit"]=> int(-1) ["recent_avg_used"]=> int(0) ["usage_over_avg"]=> int(0) ["cycles"]=> array(0) { } ["events"]=> array(1) { [0]=> object(stdClass)#283 (6) { ["start"]=> int(0) ["end"]=> int(86399) ["type"]=> int(5) ["event_touched_by"]=> int(6) ["event_touched_where"]=> int(0) ["continuation"]=> bool(true) } } ["rates"]=> array(0) { } ["system_capabilities"]=> int(1) ["incomplete_fields"]=> int(0) } [1]=> object(stdClass)#280 (16) { ["day"]=> string(10) "2019-10-22" ["device_timezone_offset"]=> int(-18000) ["total_heating_time"]=> int(0) ["total_cooling_time"]=> int(0) ["total_fan_cooling_time"]=> int(0) ["total_humidifier_time"]=> int(0) ["total_dehumidifier_time"]=> int(0) ["leafs"]=> int(1) ["whodunit"]=> int(-1) ["recent_avg_used"]=> int(0) ["usage_over_avg"]=> int(0) ["cycles"]=> array(0) { } ["events"]=> array(1) { [0]=> object(stdClass)#281 (6) { ["start"]=> int(0) ["end"]=> int(86399) ["type"]=> int(5) ["event_touched_by"]=> int(6) ["event_touched_where"]=> int(0) ["continuation"]=> bool(true) } } ["rates"]=> array(0) { } ["system_capabilities"]=> int(1) ["incomplete_fields"]=> int(0) } [2]=> object(stdClass)#278 (16) { ["day"]=> string(10) "2019-10-23" ["device_timezone_offset"]=> int(-18000) ["total_heating_time"]=> int(0) ["total_cooling_time"]=> int(0) ["total_fan_cooling_time"]=> int(0) ["total_humidifier_time"]=> int(0) ["total_dehumidifier_time"]=> int(0) ["leafs"]=> int(1) ["whodunit"]=> int(-1) ["recent_avg_used"]=> int(0) ["usage_over_avg"]=> int(0) ["cycles"]=> array(0) { } ["events"]=> array(1) { [0]=> object(stdClass)#279 (6) { ["start"]=> int(0) ["end"]=> int(86399) ["type"]=> int(5) ["event_touched_by"]=> int(6) ["event_touched_where"]=> int(0) ["continuation"]=> bool(true) } } ["rates"]=> array(0) { } ["system_capabilities"]=> int(1) ["incomplete_fields"]=> int(0) } [3]=> object(stdClass)#276 (16) { ["day"]=> string(10) "2019-10-24" ["device_timezone_offset"]=> int(-18000) ["total_heating_time"]=> int(0) ["total_cooling_time"]=> int(0) ["total_fan_cooling_time"]=> int(0) ["total_humidifier_time"]=> int(0) ["total_dehumidifier_time"]=> int(0) ["leafs"]=> int(1) ["whodunit"]=> int(-1) ["recent_avg_used"]=> int(0) ["usage_over_avg"]=> int(0) ["cycles"]=> array(0) { } ["events"]=> array(1) { [0]=> object(stdClass)#277 (6) { ["start"]=> int(0) ["end"]=> int(86399) ["type"]=> int(5) ["event_touched_by"]=> int(6) ["event_touched_where"]=> int(0) ["continuation"]=> bool(true) } } ["rates"]=> array(0) { } ["system_capabilities"]=> int(1) ["incomplete_fields"]=> int(0) } [4]=> object(stdClass)#274 (16) { ["day"]=> string(10) "2019-10-25" ["device_timezone_offset"]=> int(-18000) ["total_heating_time"]=> int(0) ["total_cooling_time"]=> int(0) ["total_fan_cooling_time"]=> int(0) ["total_humidifier_time"]=> int(0) ["total_dehumidifier_time"]=> int(0) ["leafs"]=> int(1) ["whodunit"]=> int(-1) ["recent_avg_used"]=> int(0) ["usage_over_avg"]=> int(0) ["cycles"]=> array(0) { } ["events"]=> array(1) { [0]=> object(stdClass)#275 (6) { ["start"]=> int(0) ["end"]=> int(86399) ["type"]=> int(5) ["event_touched_by"]=> int(6) ["event_touched_where"]=> int(0) ["continuation"]=> bool(true) } } ["rates"]=> array(0) { } ["system_capabilities"]=> int(1) ["incomplete_fields"]=> int(0) } [5]=> object(stdClass)#272 (16) { ["day"]=> string(10) "2019-10-26" ["device_timezone_offset"]=> int(-18000) ["total_heating_time"]=> int(0) ["total_cooling_time"]=> int(0) ["total_fan_cooling_time"]=> int(0) ["total_humidifier_time"]=> int(0) ["total_dehumidifier_time"]=> int(0) ["leafs"]=> int(1) ["whodunit"]=> int(-1) ["recent_avg_used"]=> int(0) ["usage_over_avg"]=> int(0) ["cycles"]=> array(0) { } ["events"]=> array(1) { [0]=> object(stdClass)#273 (6) { ["start"]=> int(0) ["end"]=> int(86399) ["type"]=> int(5) ["event_touched_by"]=> int(6) ["event_touched_where"]=> int(0) ["continuation"]=> bool(true) } } ["rates"]=> array(0) { } ["system_capabilities"]=> int(1) ["incomplete_fields"]=> int(0) } [6]=> object(stdClass)#270 (16) { ["day"]=> string(10) "2019-10-27" ["device_timezone_offset"]=> int(-18000) ["total_heating_time"]=> int(0) ["total_cooling_time"]=> int(0) ["total_fan_cooling_time"]=> int(0) ["total_humidifier_time"]=> int(0) ["total_dehumidifier_time"]=> int(0) ["leafs"]=> int(1) ["whodunit"]=> int(-1) ["recent_avg_used"]=> int(0) ["usage_over_avg"]=> int(0) ["cycles"]=> array(0) { } ["events"]=> array(1) { [0]=> object(stdClass)#271 (6) { ["start"]=> int(0) ["end"]=> int(86399) ["type"]=> int(5) ["event_touched_by"]=> int(6) ["event_touched_where"]=> int(0) ["continuation"]=> bool(true) } } ["rates"]=> array(0) { } ["system_capabilities"]=> int(1) ["incomplete_fields"]=> int(0) } [7]=> object(stdClass)#268 (16) { ["day"]=> string(10) "2019-10-28" ["device_timezone_offset"]=> int(-18000) ["total_heating_time"]=> int(0) ["total_cooling_time"]=> int(0) ["total_fan_cooling_time"]=> int(0) ["total_humidifier_time"]=> int(0) ["total_dehumidifier_time"]=> int(0) ["leafs"]=> int(1) ["whodunit"]=> int(-1) ["recent_avg_used"]=> int(0) ["usage_over_avg"]=> int(0) ["cycles"]=> array(0) { } ["events"]=> array(1) { [0]=> object(stdClass)#269 (6) { ["start"]=> int(0) ["end"]=> int(86399) ["type"]=> int(5) ["event_touched_by"]=> int(6) ["event_touched_where"]=> int(0) ["continuation"]=> bool(true) } } ["rates"]=> array(0) { } ["system_capabilities"]=> int(1) ["incomplete_fields"]=> int(0) } [8]=> object(stdClass)#266 (16) { ["day"]=> string(10) "2019-10-29" ["device_timezone_offset"]=> int(-18000) ["total_heating_time"]=> int(0) ["total_cooling_time"]=> int(0) ["total_fan_cooling_time"]=> int(0) ["total_humidifier_time"]=> int(0) ["total_dehumidifier_time"]=> int(0) ["leafs"]=> int(1) ["whodunit"]=> int(-1) ["recent_avg_used"]=> int(0) ["usage_over_avg"]=> int(0) ["cycles"]=> array(0) { } ["events"]=> array(1) { [0]=> object(stdClass)#267 (6) { ["start"]=> int(0) ["end"]=> int(86399) ["type"]=> int(5) ["event_touched_by"]=> int(6) ["event_touched_where"]=> int(0) ["continuation"]=> bool(true) } } ["rates"]=> array(0) { } ["system_capabilities"]=> int(1) ["incomplete_fields"]=> int(0) } [9]=> object(stdClass)#264 (16) { ["day"]=> string(10) "2019-10-30" ["device_timezone_offset"]=> int(-18000) ["total_heating_time"]=> int(0) ["total_cooling_time"]=> int(0) ["total_fan_cooling_time"]=> int(0) ["total_humidifier_time"]=> int(0) ["total_dehumidifier_time"]=> int(0) ["leafs"]=> int(1) ["whodunit"]=> int(-1) ["recent_avg_used"]=> int(0) ["usage_over_avg"]=> int(0) ["cycles"]=> array(0) { } ["events"]=> array(1) { [0]=> object(stdClass)#265 (6) { ["start"]=> int(0) ["end"]=> int(86399) ["type"]=> int(5) ["event_touched_by"]=> int(6) ["event_touched_where"]=> int(0) ["continuation"]=> bool(true) } } ["rates"]=> array(0) { } ["system_capabilities"]=> int(1) ["incomplete_fields"]=> int(0) } } } } } }
Ah yes. It comes out more sane-ly formatted than what you pasted, but it's all there.
For those who have tested... are any of you using two-factor authentication (2FA) with their Google account?
I imagine it will still work with the token, but just wanted to ask.
Single-factor here.
I could try to implement this, but to do so, I would need to migrate my Nest account to a Google account; not sure I want to do that until I'm sure I can make it work...
So now that you implemented this successfully, did you end up migrating your account yet?
For those who have tested... are any of you using two-factor authentication (2FA) with their Google account?
Yes; I have 2FA enabled, and migrated my Nest account to a Google account, and it works fine.
So now that you implemented this successfully, did you end up migrating your account yet?
Yes. Working fine for now.
Migrated. :flushed:
Already logged into Google on two different browsers. If I plan on routinely logging in/out of Google from one browser, then I would keep the other browser logged in. Then I should obtain the cookie data from the browser I keep logged in, right? In other words, there could be multiple simultaneous Google Auth connection at a time... am I thinking about this correctly?
Already logged into Google on two different browsers. If I plan on routinely logging in/out of Google from one browser, then I would keep the other browser logged in. Then I should obtain the cookie data from the browser I keep logged in, right? In other words, there could be multiple simultaneous Google Auth connection at a time... am I thinking about this correctly?
Yes. I myself used a Incognito browser window to login to Nest; that way, I'm sure I won't log out by accident; that browser session doesn't exist any more. I am guessing as long as we use the cookies obtained from that session semi-regularly, the session will be kept alive.
I myself used a Incognito browser window to login to Nest; that way, I'm sure I won't log out by accident; that browser session doesn't exist any more.
Oh... I did the opposite... I assumed that when the session was destroyed it would stop working. So I was already logged in with Chrome (going to stay logged in with Chrome) and obtained the values there.
I'll just use Safari to log in/out of my various Google accounts as part of my normal workflow.
I am guessing as long as we use the cookies obtained from that session semi-regularly, the session will be kept alive.
Well, I hope that's not too often then.
Just to be clear, I migrated my Nest account to Google yesterday (goodbye to IFTTT) and implemented this solution. Working great so far! My CRON job fired last night and the usage data was dumped into my database.
Thank you again to @gboudreau !
@gboudreau, how would I write a conditional to check for Google login errors? In case I get logged out of Google. I don't see any of the examples using this? Thank you!
Would something like this be sufficient?
$nest = new Nest(NULL, NULL, $issue_token, $cookies);
if ($nest) {
// run my regular code... dumping into database
} else {
// ERROR - compose/send warning email
}
@gboudreau, how would I write a conditional to check for Google login errors? In case I get logged out of Google. I don't see any of the examples using this? Thank you!
Update the class (I made some changes for this), then catch exceptions:
try {
$nest = new Nest(NULL, NULL, $issue_token, $cookies);
// Execute all Nest-related code here: $nest->...()
} catch (UnexpectedValueException $ex) {
// Happens when the issue_token or cookie is not working, for whatever reason
$error_message = $ex->getMessage();
mail(...);
} catch (RuntimeException $ex) {
// Probably a temporary server-error
} catch (Exception $ex) {
// Other errors; should not happen if it worked in the past
}
// run my regular code... dumping into database
Hmmmm... I bungled up the login hint within the $issue_token
to test it. It failed... meaning that the energy report was not fetched... but the error message also did not work.
Getting NULL
on $error_message
.
Since the UnexpectedValueException
condition was apparently not triggered, the mail was not sent.
try {
$nest = new Nest(NULL, NULL, $issue_token, $cookies);
// Execute all Nest-related code here: $nest->...()
$energy_report = $nest->getEnergyLatest();
} catch (UnexpectedValueException $ex) {
// Happens when the issue_token or cookie is not working, for whatever reason
$subject = "Nest Data Dump Failure";
$email = "*******@gmail.com";
$headers = "From: ***@*****.com\r\n";
$headers .= "Content-type: text/plain; charset=utf-8\r\n";
$error_message = $ex->getMessage();
$message = $error_message;
mail($email, $subject, $message, $headers);
} catch (RuntimeException $ex) {
// Probably a temporary server-error
} catch (Exception $ex) {
// Other errors; should not happen if it worked in the past
}
var_dump($error_message); // this is NULL
Apparently breaking the issue_token does not throw a UnexpectedValueException
, but rather a RuntimeException
.
Here is what I ended up with. Not really sure if/how this can be cleaned up or if it's comprehensive enough.
try {
$nest = new Nest(NULL, NULL, $issue_token, $cookies);
// Execute all Nest-related code here: $nest->...()
$energy_report = $nest->getEnergyLatest();
} catch (UnexpectedValueException $ex) { // Happens when the issue_token or cookie is not working, for whatever reason
$error_message = "Unexpected Value Exception: ";
} catch (RuntimeException $ex) { // Probably a temporary server-error
$error_message = "Runtime Exception: ";
} catch (Exception $ex) { // Other errors; should not happen if it worked in the past
$error_message = "Other Exception: ";
} finally {
if (! is_null($ex)) {
$error = $error_message . $ex->getMessage();
$message = $error . "\n";
// send email
$subject = "Nest Data Dump Failure";
$email = "*******@gmail.com";
$headers = "From: ***@*****.com\r\n";
$headers .= "Content-type: text/plain; charset=utf-8\r\n";
mail($email, $subject, $message, $headers);
die($error . "<br/><br/>");
}
}
Seems to be working.
@gboudreau - can we close this issue?
Yes... everything seems to be working great! The API is staying logged in and my application has been collecting data as normal. Thank you!
Everything was working fine until today:
Runtime Exception: Error: Received empty response from request to https://accounts.google.com/o/oauth2/iframerpc?action=issueToken&response_type=token%20id_token&login_hint=xxxx&client_id=xxxx-xxxxxx.apps.googleusercontent.com&origin=https%3A%2F%2Fhome.nest.com&scope=openid%20profile%20email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fnest-account&ss_domain=https%3A%2F%2Fhome.nest.com.
I x'd out the personal info above. I went to Chrome and followed the whole procedure again to regenerate the token and cookie, but I'm getting the same error.
https://github.com/gboudreau/nest-api/issues/105
This issue should be resolved by 8c2dd5c1119d2079d252240f0e3913897400e305 (published on composer as v1.2.4)
Yes! Thank you!
Everything stopped working today. I don't know what's going on since I'm seeing no PHP errors and nothing being reported back from the API.
My tokens occasionally need to be renewed, if you haven't done that in awhile.
My thermostat and protects are showing online and getting data, but getEnergyLatest is returning false due to a 500 error. It's broken in the Nest app though as well.
I've had one of my thermostats change it's ID on the nest web page to 'DEVICE_#########' (in the URL) instead of the serial number. The other one is still the serial number. I can't query the 'DEVICE_' one at all. Doesn't even show up when I do a blank $nest->getDeviceInfo();
Perhaps related to your issue?
On Sat, Jan 23, 2021 at 12:22 PM bauzer714 [email protected] wrote:
My tokens occasionally need to be renewed, if you haven't done that in awhile.
My thermostat and protects are showing online and getting data, but getEnergyLatest is returning false due to a 500 error. It's broken in the Nest app though as well.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/gboudreau/nest-api/issues/95#issuecomment-766144588, or unsubscribe https://github.com/notifications/unsubscribe-auth/AELMMQO5TFHBLNGBAQMLZ6DS3MAWDANCNFSM4JA7YR3Q .
My tokens occasionally need to be renewed, if you haven't done that in awhile.
I just tried that and it's not working. I was able to get the new tokens but the result is the same. When following the instructions to use an incognito window, I am now getting a "cookies are blocked" message when attempted to log into my Nest account. This was not an issue when I got the token last.
What's weird is that I have my program written to catch this. If there is something wrong with the token, it would display this error message. Been working over a year and I can test it by deleting the token parameter.
However, as of this morning, I am getting absolutely nothing now.
try {
$nest = new Nest(NULL, NULL, $issue_token, $cookies); // new Nest object
// Execute all Nest-related code here: $nest->...()
$energy_report = $nest->getEnergyLatest(); // get the energy report from Nest API
} catch (UnexpectedValueException $ex) { // Happens when the issue_token or cookie is not working, for whatever reason
$error_message = "Unexpected Value Exception: ";
} catch (RuntimeException $ex) { // Probably a temporary server-error
$error_message = "Runtime Exception: ";
} catch (Exception $ex) { // Other errors; should not happen if it worked in the past
$error_message = "Other Exception: ";
} finally { // always runs
if (! is_null($ex)) { // send out messages only if there is an exception
$error = $error_message . $ex->getMessage();
$message = $error . "\n" . $footer;
mail($email, $subject, $message, $headers);
die($error . "<br/><br/>");
}
}
It's blowing right through this code without showing an error message. I just tested it again by putting in a dummy token and get Unexpected Value Exception: Response to login request doesn't contain required access token. Response: null
. Then I put in the correct token and I'm getting nothing... the response is empty or blank as far as I can tell.
I've had one of my thermostats change it's ID on the nest web page to 'DEVICE_#########' (in the URL) instead of the serial number. The other one is still the serial number. I can't query the 'DEVICE_' one at all. Doesn't even show up when I do a blank $nest->getDeviceInfo(); Perhaps related to your issue? …
I'm not using my device ID at all. I'm just trying to get my data...
$nest = new Nest(NULL, NULL, $issue_token, $cookies); // new Nest object
$energy_report = $nest->getEnergyLatest();
The issue is that getEnergyLatest is getting 500 errors from Google and thus you're getting "false" returned. It's not you. The app and the website both tell me I have no data for me after 6+ years. Similar reports across Reddit of missing history data.
There is a gap where there is no exception thrown. It's a weird case that I'll look into adding some resiliency to once the functionality is restored.
I had the same thing today...it is not a token issue since I still get current temp data.
the energy data is the specific issue (even on the nest app itself).....
and bauzer714 just typed faster than I did...
The issue is that getEnergyLatest is getting 500 errors from Google and thus you're getting "false" returned. It's not you. The app and the website both tell me I have no data for me after 6+ years. Similar reports across Reddit of missing history data.
ok THANK YOU! I missed your previous response.
There is a gap where there is no exception thrown. It's a weird case that I'll look into adding some resiliency to once the functionality is restored.
Thank you!
Pr submitted. #134
Nest has fixed the endpoint. I now see data.
Estimated fix time 1740 UTC.
Nest has fixed the endpoint. I now see data.
Estimated fix time 1740 UTC.
Working here too now.
The time it was fixed coincides with my Facebook conversation with Google Nest. I'm not taking any credit since they clearly have no clue... but was funny that it started working between these comments.
Me: Lisa, same here since Friday and if you log out and back in, it wipes it all out and says "check back tomorrow for history". The underlying issue here is that it's not you - it's everyone. The Google Nest server is returning a 500 error when the history data is requested. Hope they fix it soon.
Google Nest: Thanks for bringing this up, John. What type of thermostat do you have (Nest Thermostat E, Nest Learning Thermostat or the new Nest Thermostat)? Here's how to find out:
Me: I have a Nest Learning Thermostat 3rd gen. I also have two eyeballs and can see all the online reports just like Lisa's and mine.... and the "500 internal server error" coming back from your API when the history data is requested. Why are you not yet acknowledging this this as a widespread issue?
Google Nest: We'd like to isolate what's happening, John. Could you try restarting your thermostat to refresh it's connection? Also, try uninstalling and reinstalling the Nest app. Let us know how it goes.
Me: I did not do a restart or reinstall. The history has been missing and messed up since last Friday, but just now it looks like you guys finally fixed it. Thank you.
Stopped working today with a 403 error:
Runtime Exception: Error: HTTP 403 from request to https://czfe54-front01-iad01.transport.home.nest.com/v5/subscribe. JSON error: -
Still have access via app and website. Just no access via this API.
Anyone else?
Mine is still working. Timezone is EST.
Mine is still working. Timezone is EST.
When I put the URL from the error message directly into a browser, I am getting a 400 error...
I'm in the CST time zone.
Looks like you're assigned a different transport url. From browser you can see the transport URL that you should be using by filtering for "session" in the network tab in chrome. I can't call if this value is cached or not, but you could try clearing it.
Looks like you're assigned a different transport url. From browser you can see the transport URL that you should be using by filtering for "session" in the network tab in chrome. I can't call if this value is cached or not, but you could try clearing it.
Are you saying get a new token and cookie? Because this URL and error message are coming from the API, and I have no control over the URL being used or do anything with a cache. It was working fine before today.
I will redo token & cookie now.
That wasn't the intention. Your browser is working, I'd confirm which transport URL the web is using. If it's not the one the API is using, then clear the temp cache of your web server to force the API class to newly login. I'm speculating a bit here, it's been awhile since I've had to look into this part.
I went back a third time and regenerated another new token and cookie.
Now I am getting no errors, but the history dump is completely blank. $nest->getEnergyLatest()
Last 10 days energy report:
{
"keys": [
"energy_latest.06AAxxxxxxxxxxx"
]
}
06AAxxxxxxxxxxx is the serial number for my Nest Protect
This code is showing no thermostats.
echo "Devices list (thermostats):\n";
$devices_serials = $nest->getDevices();
jlog($devices_serials);
It's coming back completely blank...
Devices list (thermostats): ----------
Just wanted to clean up this thread a bit...
I had the same issue as described here: #115 (comment)
Here is what I did to resolve the issue:
- Delete/remove the thermostat from account via app.
- Did the Reset -> "Reset WWN Connection" from the thermostat's settings menu.
- Re-add the thermostat to the account using the QR code and the iOS app.
Energy dump seems to be working. It's show previous 10 days, with only the most recent day (same day as reset) coming up missing. Will edit this when the history resumes.
Notes:
- The "Reset" menu on the thermostat no longer shows a "Reset WWN Connection" option.
- My history data seemed to be intact. I lost no prior history data, but the day that I did this reset is completely missing from the energy dump. History data collection afterwards is also working fine. The one day is missing from online, app, and the API.
-
$nest->getDevices()
is still not working for some reason.