Google Nest Device Access Console now available

That is amazing thank you so much for the response!

I look forward to the official release, thank you!

I’m using Pub/Sub, you could try also with oh restart, it won’t work until you remove thermostat thing from paper ui and add it back. Same behaviour as internet outage. OH 2.5.x here

I’ve got the same error:

openhab> config:list "(service.pid=org.openhab.nestdeviceaccess)"
----------------------------------------------------------------
Pid:            org.openhab.nestdeviceaccess
BundleLocation: null
Properties:
   clientId = xxxx
   clientSecret = xxxx
   felix.fileinstall.filename = file:/openhab/userdata/etc/org.openhab.nestdeviceaccess.cfg
   projectId = xxxx
   refreshToken = xxxx
   service.pid = org.openhab.nestdeviceaccess

Stacktrace:

2021-02-07 22:19:04.733 [ERROR] [core.thing.internal.ThingManagerImpl] - Exception occurred while calling thing handler factory 'org.openhab.binding.nestdeviceaccess.internal.nestdeviceaccessHandlerFactory@3d7b5314': null
java.lang.NullPointerException: null
        at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:878) ~[?:?]
        at com.google.api.client.util.Preconditions.checkNotNull(Preconditions.java:125) ~[?:?]
        at com.google.api.client.auth.oauth2.RefreshTokenRequest.setRefreshToken(RefreshTokenRequest.java:142) ~[?:?]
        at com.google.api.client.googleapis.auth.oauth2.GoogleRefreshTokenRequest.setRefreshToken(GoogleRefreshTokenRequest.java:120) ~[?:?]
        at com.google.api.client.googleapis.auth.oauth2.GoogleRefreshTokenRequest.setRefreshToken(GoogleRefreshTokenRequest.java:75) ~[?:?]
        at com.google.api.client.auth.oauth2.RefreshTokenRequest.<init>(RefreshTokenRequest.java:95) ~[?:?]
        at com.google.api.client.googleapis.auth.oauth2.GoogleRefreshTokenRequest.<init>(GoogleRefreshTokenRequest.java:86) ~[?:?]
        at org.openhab.binding.nestdeviceaccess.internal.nesthelper.NestUtility.refreshAccessToken(NestUtility.java:197) ~[?:?]
        at org.openhab.binding.nestdeviceaccess.internal.nesthelper.NestUtility.<init>(NestUtility.java:71) ~[?:?]
        at org.openhab.binding.nestdeviceaccess.internal.thermostat.NestThermostatHandler.<init>(NestThermostatHandler.java:67) ~[?:?]
        at org.openhab.binding.nestdeviceaccess.internal.nestdeviceaccessHandlerFactory.createHandler(nestdeviceaccessHandlerFactory.java:79) ~[?:?]

Have I missed something here?

After a good long while and many trips through this thread, I was able to get the binding working in my OH setup (2.5.12 via the official Docker image running on Debian host). Is there a way to add Things (thermostats) and Items through the text config files, or are we limited to adding them through PaperUI? The documentation doesn’t seem to give any options at least for adding the Things. I tried creating a nestdeviceaccess:nest-device-thermostat Thing using the deviceId was grabbed from PaperUI plus the refreshToken, projectId, clientId, and clientSecret from the config file, but that didn’t work (“UNINITIALIZED - HANDLER_REGISTERING_ERROR”).

Update: I seem to be able to add Items in the config files, but adding Things would be great as well. I’m happy to update the documentation if someone points me in the right direction to getting it working.

OH seems to be receiving information from Nest just fine, but posting information is spotty. Posting HVAC mode or Eco mode seems to work, but posting temperature setpoints does not. I’ve tried posting both min temp setting and target temp, and neither seem to actually make it through to the thermostat (the OH value just resets to the thermostat value on the next update). Is this a known bug or am I doing something wrong?

I have not had a chance to try to set up PubSub yet, if that has anything to do with it.

Replying to myself again to give an update. I think I got pub/sub set up. I went through the instructions here Subscribe to Events  |  Device Access  |  Google Developers . I created my own subscriptionId for use in the cfg file in one of the steps of those instructions. I took the pubsubProjectId from the Project ID field for my project on the Google Cloud Platform dashboard (https://console.cloud.google.com/home/dashboard). And I downloaded the json file for my OAuth credentials (https://console.developers.google.com/apis/credentials) to a folder accessible to my docker container and added the file path to the serviceAccountPath in my cfg file. I am getting no errors, but I really don’t know how I would tell if the binding is using pub/sub or whatever the non-pub/sub alternative is. (Again, I only have thermostats, so my understanding is that pub/sub is not strictly necessary.)

Anyway, I’m having the same problem as the previous post where I’m getting good two-way connection between my thermostats and my OH installation for Eco mode and HVAC mode (i.e., I can control those modes from either OH or the thermostat and they will update in both places), but I still am only getting one-way connection on the temperatures (i.e., I can update the temperatures on the thermostat and they will be updated on OH, but not the other way around). Not sure what I’m doing.

Good questions so I took a look at the documentation. Based on the excerpt below from Nest Device Access - Subscribe to Events:

For example, if the ambient temperature near your Google Nest Thermostat changes,
an event for the Temperature trait will automatically be sent with a new 
ambientTemperatureCelsius value.

To manually generate one, either:

Physically change the state of your device, such as changing the mode of your Nest
Thermostat.
 
Trigger an event, such as motion, person, or sound on a Google Nest Cam.
Execute a device command using the SDM API.

My interpretation is that the subscription does publish events associated with nest devices - for both thermostats (e.g. ambient temperature changes) and cameras (e.g. sound, motion, and people being detected). I am definitely seeing messages being queued from my cameras, but have not seen them from my thermostats though I have not been looking for them.

Also, reading through some of the traits around thermostats there are a lot of “notes” highlighting the fact that when the thermostat is in ECO mode, changing certain settings will not be accepted. This may go for publishing events as well. To be sure changes are accepted from OH, you will need to make sure they are valid for whichever mode your thermostat is in. Not sure that logic can be included in the binding or if it should happen outside of it…

You can view the messages that are in the queue on the subscription on the google site where you set up your subscription. This link should get you to that area: Google Cloud - PubSub Topic List.

@BHigg (primary developer) is probably the best person to comment on this binding, my experience is that there are still some funky things going on that may need some troubleshooting to resolve - especially when it comes to the cameras.

Hope that helps…

Hi @kovacsi2899, did you ever find a solution to this issue? I am having the same problem. I was able to follow the instructions here https://developers.google.com/nest/device-access/authorize#get_an_access_token up to the step titled “Get an access token”… but when I attempt to use the generated curl expression with my oauth2-client-id, oauth2-client-secret and authorization-code, I get the same error in Windows PowerShell as you saw (I have also attempted at the Windows 10 command prompt and in the Google Cloud shell console, with different errors there):

Invoke-WebRequest : A parameter cannot be found that matches parameter name 'L'.
At line:1 char:6
+ curl -L -X POST 'https://www.googleapis.com/oauth2/v4/token?
+      ~~
+ CategoryInfo          : InvalidArgument: (:) [Invoke-WebRequest], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

I’m a little in above my head here but hoping someone might be able to make a suggestion as to what I am missing?

Not much of an expert on using curl on windows and especially Powershell. So I can only suggest what you might try. And good if you included the command your executing, hard to tell based on the error message if you have a properly formatted request.

Windows Powershell converts the curl command to Invoke-Webrequest - by knowing that you would need to understand how to specify the parameters using the Invoke-Webrequest (typically they are loaded into variables and then variable are used on the command). The message your getting is telling you that it does not know what the -L means and what to do with it. Most likely you need to use the Invoke-Restmethod since your trying to do a POST, so you may want to research that approach if you really need to do this in Powershell.

The basic format for Invoke-Restmethod:
    
Invoke-Restmethod -Method Post -Uri "enter your URL here between double quotes"

I would first try this in a windows command prompt rather than Powershell. If you do that, you will need to enclose the URI in double quotes (") rather than single quotes (') because this curl URL is using HTTPS. If that works, great, but if not then, I would try to find a linux based system to do the curl command from…

You can also try to google a forum searching for convert curl to Invoke-Restmethod, or convert curl to Invoke-Webrequest. Try asking the forum how to convert the curl command and see if they can give you the answer that way.

One other thought, if you don’t mind installing some software on your windows machine, the git bash client will give you a linux environment that you can run the curl command from and it works without issues, just tried it on my Windows 10 PC…

Instructions here: Git-Guides: Install Git

Good luck, hope this helps…

Thanks so much, I will give this stuff a try. You are right - I made it hard on you by not including the command which is as follows (as specified in the instructions here https://developers.google.com/nest/device-access/authorize#get_an_access_token):

curl -L -X POST 'https://www.googleapis.com/oauth2/v4/token?
client_id=oauth2-client-id&
client_secret=oauth2-client-secret&
code=authorization-code&
grant_type=authorization_code&
redirect_uri=https://www.google.com'

I don’t need to do this in powershell, I am just in over my head and don’t know any better :slight_smile:
I will give this a try at the command prompt and at the console on my RaspberryPi. Thanks again for the help :+1:

1 Like

Hi there,
I’m relative new to Openhab and try to integrate my NEST devices to OpenHab.
I have a Doorbell and a Camera
When using OpenHab 2.5 (a quick test setup on my workstation), things seem to work fine. Both devices are discovered, events are pushed to openhab when someone is seen by the camera or rings the doorbell.

However, when trying to get things working in my OpenHab 3.0 environment (openhabian on a Raspberry Pi 4), I have the following issues:

  • Only the doorbell thing is discovered. The Camera is missing. I however have seen the 2.5 build is from 20201117 (version 2.5.5.202011172030), while the 3.0 build is from 20201103 (202011030026). Is there a difference in functionality?
  • Second issue I see on my Openhab3.0 setup are the following errors when trying to add the thing:
22:21:57.198 [DEBUG] [l.discovery.nestdeviceaccessDiscovery] - Starting Discovery NestDeviceAccess
22:22:00.739 [INFO ] [l.discovery.nestdeviceaccessDiscovery] - nestdeviceaccessDiscovery adding Doorbell: [Voordeur] to inbox
22:22:49.341 [INFO ] [ternal.nestdeviceaccessHandlerFactory] - supportsThingType reporting nestdeviceaccess:nest-device-doorbell
22:22:49.348 [INFO ] [ternal.nestdeviceaccessHandlerFactory] - supportsThingType reporting nestdeviceaccess:nest-device-doorbell
22:22:49.351 [INFO ] [ternal.nestdeviceaccessHandlerFactory] - createHandler reporting nestdeviceaccess:nest-device-doorbell
22:22:49.353 [DEBUG] [ternal.nestdeviceaccessHandlerFactory] - createHandler reporting Doorbell..
22:22:49.359 [DEBUG] [ccess.internal.nesthelper.NestUtility] - NestUtility constructor failed to parse date Unparseable date: "Feb 25, 2021, 11:21:56 PM"
22:22:49.364 [DEBUG] [ccess.internal.nesthelper.NestUtility] - NestUtility constructor failed to parse date Unparseable date: "Feb 25, 2021, 11:21:56 PM"

Locale settings are nl_BE.UTF-8, which means I would expect dd-mm-yyyy and 24 hour format.

Any suggestions?
Thanks,
Michiel

Sorry Michiel, I only have nest thermostats… and to my dismay, after a full week of essentially flawless performance, I seem to have broken something, and now the thermostats consistently to lose their connection to OH exactly one hour after re-establishing the link (by re-discovering devices, then disabling & re-enabling the thermostat thing in the UI).

Stupidly, I think I may be responsible for this, as the change seemed to coincide with implementing two factor authentication on the google account associated with the Nests while setting up a different binding (you know, linking to a phone so that you can’t sign in without typing the code in a text message or whatever). I am a little surprised that doing that would have such an effect, but I am unable to identify any other possible culprit to explain the transition from that first week of flawless function to now only being able to maintain the connection for an hour. Curious if anyone else has had similar issues? I am no programmer, but I did a little digging, and I suspect that maybe this has something to do with the “expires_in”: 3599 property associated with the access_token provided by google… if I am correct in assuming that this number is in seconds, then that corresponds to one hour - which is the same period of time that I am able to maintain the link after losing the connection. So it seems that perhaps the refresh token is not successfully able to facilitate the generation of a new access token after the old one expires? The thing is, I have attempted to re-establish the connection using only the refresh token in the .cfg file (to prove that the refresh token is valid), and it works fine. So I am definitely confused. And also devastated, because having the nests integrated into all my other coming home/leaving home/going to bed/waking up routines was so amazing. Too good to be true maybe. Hopefully not. Any ideas would be very much appreciated! In case this clue is helpful - after the hour is up, in the OH log, I can see that the binding continues to attempt to update the thermostats every 5 minutes (which is my arbitrary refresh interval), but the actual values for current temperature and such fail to get updated. There is never any error/warning - superficially everything appears to be working fine, it is just that after that hour long period OH can no longer update values at the refresh interval, or send commands. I am running OH3.0.1 (with openHABian) on a RPi 4.

Also - in case this helps anyone else out (especially you @kovacsi2899) I found the solution to the problem I was experiencing in my last post above, when following the instructions here Get Started  |  Device Access  |  Google Developers. Specifically, at step #1 under “Get an access token” - when attempting to use the code within the google cloud shell terminal:

curl -L -X POST 
'https://www.googleapis.com/oauth2/v4/token?
client_id=oauth2-client-id&
client_secret=oauth2-client-secret&
code=authorization-code&
grant_type=authorization_code&
redirect_uri=https://www.google.com'

I was receiving this error:

A parameter cannot be found that matches parameter name 'L'.
At line:1 char:6
+ curl -L -X POST 'https://www.googleapis.com/oauth2/v4/token?
+      ~~
+ CategoryInfo          : InvalidArgument: (:) [Invoke-WebRequest], ParameterBindingException
+ FullyQualifiedErrorId : 
NamedParameterNotFound,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

It turns out that the error was related to paragraph formatters within the text copied/pasted from the instructions at the above linked site - after removing those in notepad, the code ran perfectly. The code that ended up working was just one really long text string - like this:

curl -L -X POST 'https://www.googleapis.com/oauth2/v4/token?client_id=oauth2-client-id&client_secret=oauth2-client-secret&code=authorization-code&grant_type=authorization_code&redirect_uri=https://www.google.com'

One last thing in case it helps anyone - after succeeding with this step, I frustratingly got stuck again, at the very last step entitled “make a device list call” after attempting the code below in google cloud shell terminal:

curl -X GET 'https://smartdevicemanagement.googleapis.com/v1/enterprises/project-id/devices' \    -H 'Content-Type: application/json' \    -H 'Authorization: Bearer access-token'

I got the error something to the effect of, invalid request or invalid code or some such. I have no idea why this worked, but all I had to do was repeat the preceding steps in the instructions to generate a new authorization code, access token and refresh token - and it miraculously worked like a charm.

Thanks so much to @BHigg, @wborn, and everyone else who I am not informed enough to mention specifically for all your hard work on this binding! I am so excited about it and very appreciative to you guys and everyone else in here helping each other out :+1:

2 Likes

While I am at about the same skill level as you on troubleshooting this stuff, I may have a few things for you to consider.

If the binding is working - checking your logs, you should see some messages related to the channel refresh for the thermostats. They would be in the openhab.log and the events.log. The openhab.log would have INFO entries similar to this:

==> /var/log/openhab2/openhab.log <==
2021-02-28 19:24:55.066 [INFO ] [nal.thermostat.NestThermostatHandler] - refreshChannels process a timer for Updating thing Channels for:nestdeviceaccess:nest-device-thermostat:AVPHwEs0OlH-kM0VcvCbIAJP_BhqtJqhoHfsdQoZrm3Jgz5P1sM1CUa732N5uP69SCddtXA_Oiu3CHzFrynPqgS9GjnKQQ
2021-02-28 19:24:55.640 [INFO ] [nal.thermostat.NestThermostatHandler] - refreshChannels process a timer for Updating thing Channels for:nestdeviceaccess:nest-device-thermostat:AVPHwEtiwOaLlO-WxC0CsAs7ecHUT0RdXAQSWzkWXa2v1v5wM67K4sPVc4osEWUHNXtOL5N8ugyuLm4SonccnCJI_55Lxw

And the event.log would have entry(s) around same time frame that look like this:

==> /var/log/openhab2/events.log <==
2021-02-28 19:24:56.092 [vent.ItemStateChangedEvent] - nestdeviceaccess_nest_device_thermostat_AVPHwEtiwOaLlO_WxC0CsAs7ecHUT0RdXAQSWzkWXa2v1v5wM67K4sPVc4osEWUHNXtOL5N8ugyuLm4SonccnCJI_55Lxw_thermostatHumidityPercent changed from 50.0 in to 48.0 in

Since the subscription is set up as a “pull”, the binding needs to request the messages from the queue. There seems to be a set time frame configured in the binding to do that pull - hence the process timer log entries.

As for the token expiration, it is true that it lasts one hour, but if the binding gets an error using the token, it should be doing a token request with the refresh-token. I assume that the refresh token does not expire and is the way you get a new token much like you did when you got an authorization token and made the initial request for your tokens during setup. Hope that makes sense.

I have had times when the thermostat stops getting updated, and hard to say what caused it but as in your case I was fiddling around on the Google side trying to understand this stuff a little better and probably messed it up. I have found that stopping and starting the binding seems to clear up those issues 99% of the time. You can do that from the openhab-cli console. In an extreme way you can also stop and start openHAB - that way your positive everything is starting fresh.

The binding is still under development which means you can expect to have issues. Hopefully Brian is still active here and can help.

Lately I have noticed (two thermostats and 5 cameras) - some handler Missing errors when I try to update the Thing definition for my nest devices (i.e. assign a location or refresh interval) using the Paper UI. This always messes up the device and the binding stops updating the device. That’s when I resort to restarting the binding…

Today, I completed documenting the setup process for the Device Access Console; not being a programmer, this was the best I could do to help others understand the steps behind getting the Google SDM API set up on Googles cloud platform. I will post a link to the Wiki after this reply. Perhaps there are some other clues in there to help you as well…

1 Like

Since setting up Device Access using Google’s new Smart Device Management (SDM) API isn’t the easiest process to follow, I went ahead and documented, as best I could, the steps to set this up and collect the information needed to configure the Nest Device Access Binding that @BHigg developed for the community.

Here’s a link to that guide on a GitHub Wiki I created:

Nest On OpenHAB - Step By Step Guide

My intent is to improve/keep this information up to-date. Constructive feedback is always welcome and can be provided here on openHab’s Community forum for this Topic.

5 Likes

Thank you Dave, this is very helpful!

I noticed a lot of commits by @wborn on github against the Nest binding. I am still on the “Works with Nest” API with my devices so holding off to convert to SDM for my OH3 setup. Looking forward however to convert once this is integrated in OH. Meanwhile hoping no family member “upgrades” the account…

1 Like

Hello, I have found out these hints by myself also, but it was working neither with Windows CMD nor with Windows Power Shell. Does not matter wich version I used. This was the magic word what helped me: Google Cloud shell console. I Looked for that and in a Chrome browser it started to work. Thanks! But as I migrated to OH3 in a meantime I can’t use it, till OH3 version will be ready.

1 Like

Thank you so much for the reply and for the amazing documentation!! You did a really good job with this, it is going to make this process much more straightforward anyone setting this up in the future.

In case this tidbit helps anyone… the solution to the problem i described above regarding the connection between OH3 and Nest expiring after one hour despite having a valid access token and refresh token was extremely simple… all I had to do was delete the nest thermostat thing from the UI and then add it again. After doing that, the refresh token has successfully maintained the connection for going on 10 days now. Somehow, restarting the binding and clearing the cache were not sufficient. I don’t know what caused the problem but as I said it seems to have vanished, so I am happy :+1:

Also @kovacsi2899, happy to hear that the Google Cloud shell console hint helped. Just to be clear though, I am also on OH3, and it is working for me - so I think you should be able to get the binding working with OH3 in its current state!

Thanks @Marcusfacius for the feedback.

As an FYI, I found that if you have camera devices, the credentials (.json) file needs to include parameters for a service account if you want to reliably retrieve the camera info. I was having hit or miss luck on this till I made this change. I have 5 nest cameras (Dropcam, Nestcam, Outdoor cam), while all showed on-line, only one or two of these would actually be updated when an event occurred. After this change, all 5 cameras are updating as expected.

I have an open issue on my doc to update it, so will get to that soon - you can find more info about that by reading the issue Update instructions for Credentials file to include service type.

Hi @Marcusfacius, how did you get the binding working in OH3? My building just installed Nests, and I’d like to give it a try!

Hi @dschoepel,

Thank you for the detailed step-by-step guide. I am running into trouble getting my access token. In short, I cannot seem to get beyond Step 3, I click all buttons, then I am re-directed to http://nestservices.google.com. I am not getting a screen to “choose an account”. So, I am not getting an access token. My nestservices.google.com screen just shows a box to change the amazon alexa settings. Any help would be appreciated.

~John